ia64/xen-unstable

changeset 12592:aaaa249e6f3b

[LINUX] Update to Linux 2.6.16.32

Updated patches/linux-2.6.16.32/net-gso-0-base.patch due to changes in
net/core/dev.c and net/core/skbuff.c and update the following in the sparse
tree:
include/linux/skbuff.h
mm/memory.c
mm/mmap.c

Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author Ian Campbell <ian.campbell@xensource.com>
date Mon Nov 27 13:50:02 2006 +0000 (2006-11-27)
parents 447ac06f74d3
children c242b6d6a64a
files buildconfigs/mk.linux-2.6-xen linux-2.6-xen-sparse/include/linux/skbuff.h linux-2.6-xen-sparse/mm/memory.c linux-2.6-xen-sparse/mm/mmap.c linux-2.6-xen-sparse/net/core/skbuff.c patches/linux-2.6.16.31/blktap-aio-16_03_06.patch patches/linux-2.6.16.31/device_bind.patch patches/linux-2.6.16.31/fix-hz-suspend.patch patches/linux-2.6.16.31/fix-ide-cd-pio-mode.patch patches/linux-2.6.16.31/i386-mach-io-check-nmi.patch patches/linux-2.6.16.31/ipv6-no-autoconf.patch patches/linux-2.6.16.31/net-csum.patch patches/linux-2.6.16.31/net-gso-0-base.patch patches/linux-2.6.16.31/net-gso-1-check-dodgy.patch patches/linux-2.6.16.31/net-gso-2-checksum-fix.patch patches/linux-2.6.16.31/net-gso-3-fix-errorcheck.patch patches/linux-2.6.16.31/net-gso-4-kill-warnon.patch patches/linux-2.6.16.31/net-gso-5-rcv-mss.patch patches/linux-2.6.16.31/pci-mmconfig-fix-from-2.6.17.patch patches/linux-2.6.16.31/pmd-shared.patch patches/linux-2.6.16.31/rcu_needs_cpu.patch patches/linux-2.6.16.31/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch patches/linux-2.6.16.31/series patches/linux-2.6.16.31/smp-alts.patch patches/linux-2.6.16.31/tpm_plugin_2.6.17.patch patches/linux-2.6.16.31/x86-elfnote-as-preprocessor-macro.patch patches/linux-2.6.16.31/x86-increase-interrupt-vector-range.patch patches/linux-2.6.16.31/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch patches/linux-2.6.16.31/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch patches/linux-2.6.16.31/xen-hotplug.patch patches/linux-2.6.16.31/xenoprof-generic.patch patches/linux-2.6.16.32/blktap-aio-16_03_06.patch patches/linux-2.6.16.32/device_bind.patch patches/linux-2.6.16.32/fix-hz-suspend.patch patches/linux-2.6.16.32/fix-ide-cd-pio-mode.patch patches/linux-2.6.16.32/i386-mach-io-check-nmi.patch patches/linux-2.6.16.32/ipv6-no-autoconf.patch patches/linux-2.6.16.32/net-csum.patch patches/linux-2.6.16.32/net-gso-0-base.patch patches/linux-2.6.16.32/net-gso-1-check-dodgy.patch patches/linux-2.6.16.32/net-gso-2-checksum-fix.patch patches/linux-2.6.16.32/net-gso-3-fix-errorcheck.patch patches/linux-2.6.16.32/net-gso-4-kill-warnon.patch patches/linux-2.6.16.32/net-gso-5-rcv-mss.patch patches/linux-2.6.16.32/pci-mmconfig-fix-from-2.6.17.patch patches/linux-2.6.16.32/pmd-shared.patch patches/linux-2.6.16.32/rcu_needs_cpu.patch patches/linux-2.6.16.32/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch patches/linux-2.6.16.32/series patches/linux-2.6.16.32/smp-alts.patch patches/linux-2.6.16.32/tpm_plugin_2.6.17.patch patches/linux-2.6.16.32/x86-elfnote-as-preprocessor-macro.patch patches/linux-2.6.16.32/x86-increase-interrupt-vector-range.patch patches/linux-2.6.16.32/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch patches/linux-2.6.16.32/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch patches/linux-2.6.16.32/xen-hotplug.patch patches/linux-2.6.16.32/xenoprof-generic.patch
line diff
     1.1 --- a/buildconfigs/mk.linux-2.6-xen	Mon Nov 27 13:50:02 2006 +0000
     1.2 +++ b/buildconfigs/mk.linux-2.6-xen	Mon Nov 27 13:50:02 2006 +0000
     1.3 @@ -1,5 +1,5 @@
     1.4  LINUX_SERIES = 2.6
     1.5 -LINUX_VER    = 2.6.16.31
     1.6 +LINUX_VER    = 2.6.16.32
     1.7  
     1.8  EXTRAVERSION ?= xen
     1.9  
     2.1 --- a/linux-2.6-xen-sparse/include/linux/skbuff.h	Mon Nov 27 13:50:02 2006 +0000
     2.2 +++ b/linux-2.6-xen-sparse/include/linux/skbuff.h	Mon Nov 27 13:50:02 2006 +0000
     2.3 @@ -974,15 +974,16 @@ static inline void skb_reserve(struct sk
     2.4  #define NET_IP_ALIGN	2
     2.5  #endif
     2.6  
     2.7 -extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc);
     2.8 +extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
     2.9  
    2.10  static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
    2.11  {
    2.12 -	if (!skb->data_len) {
    2.13 -		skb->len  = len;
    2.14 -		skb->tail = skb->data + len;
    2.15 -	} else
    2.16 -		___pskb_trim(skb, len, 0);
    2.17 +	if (unlikely(skb->data_len)) {
    2.18 +		WARN_ON(1);
    2.19 +		return;
    2.20 +	}
    2.21 +	skb->len  = len;
    2.22 +	skb->tail = skb->data + len;
    2.23  }
    2.24  
    2.25  /**
    2.26 @@ -992,6 +993,7 @@ static inline void __skb_trim(struct sk_
    2.27   *
    2.28   *	Cut the length of a buffer down by removing data from the tail. If
    2.29   *	the buffer is already under the length specified it is not modified.
    2.30 + *	The skb must be linear.
    2.31   */
    2.32  static inline void skb_trim(struct sk_buff *skb, unsigned int len)
    2.33  {
    2.34 @@ -1002,12 +1004,10 @@ static inline void skb_trim(struct sk_bu
    2.35  
    2.36  static inline int __pskb_trim(struct sk_buff *skb, unsigned int len)
    2.37  {
    2.38 -	if (!skb->data_len) {
    2.39 -		skb->len  = len;
    2.40 -		skb->tail = skb->data+len;
    2.41 -		return 0;
    2.42 -	}
    2.43 -	return ___pskb_trim(skb, len, 1);
    2.44 +	if (skb->data_len)
    2.45 +		return ___pskb_trim(skb, len);
    2.46 +	__skb_trim(skb, len);
    2.47 +	return 0;
    2.48  }
    2.49  
    2.50  static inline int pskb_trim(struct sk_buff *skb, unsigned int len)
     3.1 --- a/linux-2.6-xen-sparse/mm/memory.c	Mon Nov 27 13:50:02 2006 +0000
     3.2 +++ b/linux-2.6-xen-sparse/mm/memory.c	Mon Nov 27 13:50:02 2006 +0000
     3.3 @@ -1535,6 +1535,7 @@ static inline void cow_user_page(struct 
     3.4  		if (__copy_from_user_inatomic(kaddr, uaddr, PAGE_SIZE))
     3.5  			memset(kaddr, 0, PAGE_SIZE);
     3.6  		kunmap_atomic(kaddr, KM_USER0);
     3.7 +		flush_dcache_page(dst);
     3.8  		return;
     3.9  		
    3.10  	}
     4.1 --- a/linux-2.6-xen-sparse/mm/mmap.c	Mon Nov 27 13:50:02 2006 +0000
     4.2 +++ b/linux-2.6-xen-sparse/mm/mmap.c	Mon Nov 27 13:50:02 2006 +0000
     4.3 @@ -30,6 +30,10 @@
     4.4  #include <asm/cacheflush.h>
     4.5  #include <asm/tlb.h>
     4.6  
     4.7 +#ifndef arch_mmap_check
     4.8 +#define arch_mmap_check(addr, len, flags)	(0)
     4.9 +#endif
    4.10 +
    4.11  static void unmap_region(struct mm_struct *mm,
    4.12  		struct vm_area_struct *vma, struct vm_area_struct *prev,
    4.13  		unsigned long start, unsigned long end);
    4.14 @@ -906,6 +910,10 @@ unsigned long do_mmap_pgoff(struct file 
    4.15  	if (!len)
    4.16  		return -EINVAL;
    4.17  
    4.18 +	error = arch_mmap_check(addr, len, flags);
    4.19 +	if (error)
    4.20 +		return error;
    4.21 +
    4.22  	/* Careful about overflows.. */
    4.23  	len = PAGE_ALIGN(len);
    4.24  	if (!len || len > TASK_SIZE)
    4.25 @@ -1846,6 +1854,7 @@ unsigned long do_brk(unsigned long addr,
    4.26  	unsigned long flags;
    4.27  	struct rb_node ** rb_link, * rb_parent;
    4.28  	pgoff_t pgoff = addr >> PAGE_SHIFT;
    4.29 +	int error;
    4.30  
    4.31  	len = PAGE_ALIGN(len);
    4.32  	if (!len)
    4.33 @@ -1854,6 +1863,12 @@ unsigned long do_brk(unsigned long addr,
    4.34  	if ((addr + len) > TASK_SIZE || (addr + len) < addr)
    4.35  		return -EINVAL;
    4.36  
    4.37 +	flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
    4.38 +
    4.39 +	error = arch_mmap_check(addr, len, flags);
    4.40 +	if (error)
    4.41 +		return error;
    4.42 +
    4.43  	/*
    4.44  	 * mlock MCL_FUTURE?
    4.45  	 */
    4.46 @@ -1894,8 +1909,6 @@ unsigned long do_brk(unsigned long addr,
    4.47  	if (security_vm_enough_memory(len >> PAGE_SHIFT))
    4.48  		return -ENOMEM;
    4.49  
    4.50 -	flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
    4.51 -
    4.52  	/* Can we just expand an old private anonymous mapping? */
    4.53  	if (vma_merge(mm, prev, addr, addr + len, flags,
    4.54  					NULL, NULL, pgoff, NULL))
     5.1 --- a/linux-2.6-xen-sparse/net/core/skbuff.c	Mon Nov 27 13:50:02 2006 +0000
     5.2 +++ b/linux-2.6-xen-sparse/net/core/skbuff.c	Mon Nov 27 13:50:02 2006 +0000
     5.3 @@ -261,11 +261,11 @@ nodata:
     5.4  }
     5.5  
     5.6  
     5.7 -static void skb_drop_fraglist(struct sk_buff *skb)
     5.8 +static void skb_drop_list(struct sk_buff **listp)
     5.9  {
    5.10 -	struct sk_buff *list = skb_shinfo(skb)->frag_list;
    5.11 +	struct sk_buff *list = *listp;
    5.12  
    5.13 -	skb_shinfo(skb)->frag_list = NULL;
    5.14 +	*listp = NULL;
    5.15  
    5.16  	do {
    5.17  		struct sk_buff *this = list;
    5.18 @@ -274,6 +274,11 @@ static void skb_drop_fraglist(struct sk_
    5.19  	} while (list);
    5.20  }
    5.21  
    5.22 +static inline void skb_drop_fraglist(struct sk_buff *skb)
    5.23 +{
    5.24 +	skb_drop_list(&skb_shinfo(skb)->frag_list);
    5.25 +}
    5.26 +
    5.27  static void skb_clone_fraglist(struct sk_buff *skb)
    5.28  {
    5.29  	struct sk_buff *list;
    5.30 @@ -604,6 +609,7 @@ struct sk_buff *pskb_copy(struct sk_buff
    5.31  	n->csum	     = skb->csum;
    5.32  	n->ip_summed = skb->ip_summed;
    5.33  
    5.34 +	n->truesize += skb->data_len;
    5.35  	n->data_len  = skb->data_len;
    5.36  	n->len	     = skb->len;
    5.37  
    5.38 @@ -798,49 +804,86 @@ struct sk_buff *skb_pad(struct sk_buff *
    5.39  	return nskb;
    5.40  }	
    5.41   
    5.42 -/* Trims skb to length len. It can change skb pointers, if "realloc" is 1.
    5.43 - * If realloc==0 and trimming is impossible without change of data,
    5.44 - * it is BUG().
    5.45 +/* Trims skb to length len. It can change skb pointers.
    5.46   */
    5.47  
    5.48 -int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc)
    5.49 +int ___pskb_trim(struct sk_buff *skb, unsigned int len)
    5.50  {
    5.51 +	struct sk_buff **fragp;
    5.52 +	struct sk_buff *frag;
    5.53  	int offset = skb_headlen(skb);
    5.54  	int nfrags = skb_shinfo(skb)->nr_frags;
    5.55  	int i;
    5.56 +	int err;
    5.57  
    5.58 -	for (i = 0; i < nfrags; i++) {
    5.59 +	if (skb_cloned(skb) &&
    5.60 +	    unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))))
    5.61 +		return err;
    5.62 +
    5.63 +	i = 0;
    5.64 +	if (offset >= len)
    5.65 +		goto drop_pages;
    5.66 +
    5.67 +	for (; i < nfrags; i++) {
    5.68  		int end = offset + skb_shinfo(skb)->frags[i].size;
    5.69 -		if (end > len) {
    5.70 -			if (skb_cloned(skb)) {
    5.71 -				BUG_ON(!realloc);
    5.72 -				if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
    5.73 -					return -ENOMEM;
    5.74 -			}
    5.75 -			if (len <= offset) {
    5.76 -				put_page(skb_shinfo(skb)->frags[i].page);
    5.77 -				skb_shinfo(skb)->nr_frags--;
    5.78 -			} else {
    5.79 -				skb_shinfo(skb)->frags[i].size = len - offset;
    5.80 -			}
    5.81 +
    5.82 +		if (end < len) {
    5.83 +			offset = end;
    5.84 +			continue;
    5.85  		}
    5.86 -		offset = end;
    5.87 +
    5.88 +		skb_shinfo(skb)->frags[i++].size = len - offset;
    5.89 +
    5.90 +drop_pages:
    5.91 +		skb_shinfo(skb)->nr_frags = i;
    5.92 +
    5.93 +		for (; i < nfrags; i++)
    5.94 +			put_page(skb_shinfo(skb)->frags[i].page);
    5.95 +
    5.96 +		if (skb_shinfo(skb)->frag_list)
    5.97 +			skb_drop_fraglist(skb);
    5.98 +		goto done;
    5.99  	}
   5.100  
   5.101 -	if (offset < len) {
   5.102 +	for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp);
   5.103 +	     fragp = &frag->next) {
   5.104 +		int end = offset + frag->len;
   5.105 +
   5.106 +		if (skb_shared(frag)) {
   5.107 +			struct sk_buff *nfrag;
   5.108 +
   5.109 +			nfrag = skb_clone(frag, GFP_ATOMIC);
   5.110 +			if (unlikely(!nfrag))
   5.111 +				return -ENOMEM;
   5.112 +
   5.113 +			nfrag->next = frag->next;
   5.114 +			kfree_skb(frag);
   5.115 +			frag = nfrag;
   5.116 +			*fragp = frag;
   5.117 +		}
   5.118 +
   5.119 +		if (end < len) {
   5.120 +			offset = end;
   5.121 +			continue;
   5.122 +		}
   5.123 +
   5.124 +		if (end > len &&
   5.125 +		    unlikely((err = pskb_trim(frag, len - offset))))
   5.126 +			return err;
   5.127 +
   5.128 +		if (frag->next)
   5.129 +			skb_drop_list(&frag->next);
   5.130 +		break;
   5.131 +	}
   5.132 +
   5.133 +done:
   5.134 +	if (len > skb_headlen(skb)) {
   5.135  		skb->data_len -= skb->len - len;
   5.136  		skb->len       = len;
   5.137  	} else {
   5.138 -		if (len <= skb_headlen(skb)) {
   5.139 -			skb->len      = len;
   5.140 -			skb->data_len = 0;
   5.141 -			skb->tail     = skb->data + len;
   5.142 -			if (skb_shinfo(skb)->frag_list && !skb_cloned(skb))
   5.143 -				skb_drop_fraglist(skb);
   5.144 -		} else {
   5.145 -			skb->data_len -= skb->len - len;
   5.146 -			skb->len       = len;
   5.147 -		}
   5.148 +		skb->len       = len;
   5.149 +		skb->data_len  = 0;
   5.150 +		skb->tail      = skb->data + len;
   5.151  	}
   5.152  
   5.153  	return 0;
     6.1 --- a/patches/linux-2.6.16.31/blktap-aio-16_03_06.patch	Mon Nov 27 13:50:02 2006 +0000
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,294 +0,0 @@
     6.4 -diff -pruN ../orig-linux-2.6.16.29/fs/aio.c ./fs/aio.c
     6.5 ---- ../orig-linux-2.6.16.29/fs/aio.c	2006-09-12 19:02:10.000000000 +0100
     6.6 -+++ ./fs/aio.c	2006-09-19 13:58:49.000000000 +0100
     6.7 -@@ -34,6 +34,11 @@
     6.8 - #include <asm/uaccess.h>
     6.9 - #include <asm/mmu_context.h>
    6.10 - 
    6.11 -+#ifdef CONFIG_EPOLL
    6.12 -+#include <linux/poll.h>
    6.13 -+#include <linux/eventpoll.h>
    6.14 -+#endif
    6.15 -+
    6.16 - #if DEBUG > 1
    6.17 - #define dprintk		printk
    6.18 - #else
    6.19 -@@ -1016,6 +1021,10 @@ put_rq:
    6.20 - 	if (waitqueue_active(&ctx->wait))
    6.21 - 		wake_up(&ctx->wait);
    6.22 - 
    6.23 -+#ifdef CONFIG_EPOLL
    6.24 -+	if (ctx->file && waitqueue_active(&ctx->poll_wait))
    6.25 -+		wake_up(&ctx->poll_wait);
    6.26 -+#endif
    6.27 - 	if (ret)
    6.28 - 		put_ioctx(ctx);
    6.29 - 
    6.30 -@@ -1025,6 +1034,8 @@ put_rq:
    6.31 - /* aio_read_evt
    6.32 -  *	Pull an event off of the ioctx's event ring.  Returns the number of 
    6.33 -  *	events fetched (0 or 1 ;-)
    6.34 -+ *	If ent parameter is 0, just returns the number of events that would
    6.35 -+ *	be fetched.
    6.36 -  *	FIXME: make this use cmpxchg.
    6.37 -  *	TODO: make the ringbuffer user mmap()able (requires FIXME).
    6.38 -  */
    6.39 -@@ -1047,13 +1058,18 @@ static int aio_read_evt(struct kioctx *i
    6.40 - 
    6.41 - 	head = ring->head % info->nr;
    6.42 - 	if (head != ring->tail) {
    6.43 --		struct io_event *evp = aio_ring_event(info, head, KM_USER1);
    6.44 --		*ent = *evp;
    6.45 --		head = (head + 1) % info->nr;
    6.46 --		smp_mb(); /* finish reading the event before updatng the head */
    6.47 --		ring->head = head;
    6.48 --		ret = 1;
    6.49 --		put_aio_ring_event(evp, KM_USER1);
    6.50 -+		if (ent) { /* event requested */
    6.51 -+			struct io_event *evp =
    6.52 -+				aio_ring_event(info, head, KM_USER1);
    6.53 -+			*ent = *evp;
    6.54 -+			head = (head + 1) % info->nr;
    6.55 -+			/* finish reading the event before updatng the head */
    6.56 -+			smp_mb();
    6.57 -+			ring->head = head;
    6.58 -+			ret = 1;
    6.59 -+			put_aio_ring_event(evp, KM_USER1);
    6.60 -+		} else /* only need to know availability */
    6.61 -+			ret = 1;
    6.62 - 	}
    6.63 - 	spin_unlock(&info->ring_lock);
    6.64 - 
    6.65 -@@ -1236,9 +1252,78 @@ static void io_destroy(struct kioctx *io
    6.66 - 
    6.67 - 	aio_cancel_all(ioctx);
    6.68 - 	wait_for_all_aios(ioctx);
    6.69 -+#ifdef CONFIG_EPOLL
    6.70 -+	/* forget the poll file, but it's up to the user to close it */
    6.71 -+	if (ioctx->file) {
    6.72 -+		ioctx->file->private_data = 0;
    6.73 -+		ioctx->file = 0;
    6.74 -+	}
    6.75 -+#endif
    6.76 - 	put_ioctx(ioctx);	/* once for the lookup */
    6.77 - }
    6.78 - 
    6.79 -+#ifdef CONFIG_EPOLL
    6.80 -+
    6.81 -+static int aio_queue_fd_close(struct inode *inode, struct file *file)
    6.82 -+{
    6.83 -+	struct kioctx *ioctx = file->private_data;
    6.84 -+	if (ioctx) {
    6.85 -+		file->private_data = 0;
    6.86 -+		spin_lock_irq(&ioctx->ctx_lock);
    6.87 -+		ioctx->file = 0;
    6.88 -+		spin_unlock_irq(&ioctx->ctx_lock);
    6.89 -+	}
    6.90 -+	return 0;
    6.91 -+}
    6.92 -+
    6.93 -+static unsigned int aio_queue_fd_poll(struct file *file, poll_table *wait)
    6.94 -+{	unsigned int pollflags = 0;
    6.95 -+	struct kioctx *ioctx = file->private_data;
    6.96 -+
    6.97 -+	if (ioctx) {
    6.98 -+
    6.99 -+		spin_lock_irq(&ioctx->ctx_lock);
   6.100 -+		/* Insert inside our poll wait queue */
   6.101 -+		poll_wait(file, &ioctx->poll_wait, wait);
   6.102 -+
   6.103 -+		/* Check our condition */
   6.104 -+		if (aio_read_evt(ioctx, 0))
   6.105 -+			pollflags = POLLIN | POLLRDNORM;
   6.106 -+		spin_unlock_irq(&ioctx->ctx_lock);
   6.107 -+	}
   6.108 -+
   6.109 -+	return pollflags;
   6.110 -+}
   6.111 -+
   6.112 -+static struct file_operations aioq_fops = {
   6.113 -+	.release	= aio_queue_fd_close,
   6.114 -+	.poll		= aio_queue_fd_poll
   6.115 -+};
   6.116 -+
   6.117 -+/* make_aio_fd:
   6.118 -+ *  Create a file descriptor that can be used to poll the event queue.
   6.119 -+ *  Based and piggybacked on the excellent epoll code.
   6.120 -+ */
   6.121 -+
   6.122 -+static int make_aio_fd(struct kioctx *ioctx)
   6.123 -+{
   6.124 -+	int error, fd;
   6.125 -+	struct inode *inode;
   6.126 -+	struct file *file;
   6.127 -+
   6.128 -+	error = ep_getfd(&fd, &inode, &file, NULL, &aioq_fops);
   6.129 -+	if (error)
   6.130 -+		return error;
   6.131 -+
   6.132 -+	/* associate the file with the IO context */
   6.133 -+	file->private_data = ioctx;
   6.134 -+	ioctx->file = file;
   6.135 -+	init_waitqueue_head(&ioctx->poll_wait);
   6.136 -+	return fd;
   6.137 -+}
   6.138 -+#endif
   6.139 -+
   6.140 -+
   6.141 - /* sys_io_setup:
   6.142 -  *	Create an aio_context capable of receiving at least nr_events.
   6.143 -  *	ctxp must not point to an aio_context that already exists, and
   6.144 -@@ -1251,18 +1336,30 @@ static void io_destroy(struct kioctx *io
   6.145 -  *	resources are available.  May fail with -EFAULT if an invalid
   6.146 -  *	pointer is passed for ctxp.  Will fail with -ENOSYS if not
   6.147 -  *	implemented.
   6.148 -+ *
   6.149 -+ *	To request a selectable fd, the user context has to be initialized
   6.150 -+ *	to 1, instead of 0, and the return value is the fd.
   6.151 -+ *	This keeps the system call compatible, since a non-zero value
   6.152 -+ *	was not allowed so far.
   6.153 -  */
   6.154 - asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp)
   6.155 - {
   6.156 - 	struct kioctx *ioctx = NULL;
   6.157 - 	unsigned long ctx;
   6.158 - 	long ret;
   6.159 -+	int make_fd = 0;
   6.160 - 
   6.161 - 	ret = get_user(ctx, ctxp);
   6.162 - 	if (unlikely(ret))
   6.163 - 		goto out;
   6.164 - 
   6.165 - 	ret = -EINVAL;
   6.166 -+#ifdef CONFIG_EPOLL
   6.167 -+	if (ctx == 1) {
   6.168 -+		make_fd = 1;
   6.169 -+		ctx = 0;
   6.170 -+	}
   6.171 -+#endif
   6.172 - 	if (unlikely(ctx || nr_events == 0)) {
   6.173 - 		pr_debug("EINVAL: io_setup: ctx %lu nr_events %u\n",
   6.174 - 		         ctx, nr_events);
   6.175 -@@ -1273,8 +1370,12 @@ asmlinkage long sys_io_setup(unsigned nr
   6.176 - 	ret = PTR_ERR(ioctx);
   6.177 - 	if (!IS_ERR(ioctx)) {
   6.178 - 		ret = put_user(ioctx->user_id, ctxp);
   6.179 --		if (!ret)
   6.180 --			return 0;
   6.181 -+#ifdef CONFIG_EPOLL
   6.182 -+		if (make_fd && ret >= 0)
   6.183 -+			ret = make_aio_fd(ioctx);
   6.184 -+#endif
   6.185 -+		if (ret >= 0)
   6.186 -+			return ret;
   6.187 - 
   6.188 - 		get_ioctx(ioctx); /* io_destroy() expects us to hold a ref */
   6.189 - 		io_destroy(ioctx);
   6.190 -diff -pruN ../orig-linux-2.6.16.29/fs/eventpoll.c ./fs/eventpoll.c
   6.191 ---- ../orig-linux-2.6.16.29/fs/eventpoll.c	2006-09-12 19:02:10.000000000 +0100
   6.192 -+++ ./fs/eventpoll.c	2006-09-19 13:58:49.000000000 +0100
   6.193 -@@ -235,8 +235,6 @@ struct ep_pqueue {
   6.194 - 
   6.195 - static void ep_poll_safewake_init(struct poll_safewake *psw);
   6.196 - static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
   6.197 --static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
   6.198 --		    struct eventpoll *ep);
   6.199 - static int ep_alloc(struct eventpoll **pep);
   6.200 - static void ep_free(struct eventpoll *ep);
   6.201 - static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
   6.202 -@@ -266,7 +264,7 @@ static int ep_events_transfer(struct eve
   6.203 - static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
   6.204 - 		   int maxevents, long timeout);
   6.205 - static int eventpollfs_delete_dentry(struct dentry *dentry);
   6.206 --static struct inode *ep_eventpoll_inode(void);
   6.207 -+static struct inode *ep_eventpoll_inode(struct file_operations *fops);
   6.208 - static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
   6.209 - 					      int flags, const char *dev_name,
   6.210 - 					      void *data);
   6.211 -@@ -525,7 +523,7 @@ asmlinkage long sys_epoll_create(int siz
   6.212 - 	 * Creates all the items needed to setup an eventpoll file. That is,
   6.213 - 	 * a file structure, and inode and a free file descriptor.
   6.214 - 	 */
   6.215 --	error = ep_getfd(&fd, &inode, &file, ep);
   6.216 -+	error = ep_getfd(&fd, &inode, &file, ep, &eventpoll_fops);
   6.217 - 	if (error)
   6.218 - 		goto eexit_2;
   6.219 - 
   6.220 -@@ -710,8 +708,8 @@ eexit_1:
   6.221 - /*
   6.222 -  * Creates the file descriptor to be used by the epoll interface.
   6.223 -  */
   6.224 --static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
   6.225 --		    struct eventpoll *ep)
   6.226 -+int ep_getfd(int *efd, struct inode **einode, struct file **efile,
   6.227 -+		    struct eventpoll *ep, struct file_operations *fops)
   6.228 - {
   6.229 - 	struct qstr this;
   6.230 - 	char name[32];
   6.231 -@@ -727,7 +725,7 @@ static int ep_getfd(int *efd, struct ino
   6.232 - 		goto eexit_1;
   6.233 - 
   6.234 - 	/* Allocates an inode from the eventpoll file system */
   6.235 --	inode = ep_eventpoll_inode();
   6.236 -+	inode = ep_eventpoll_inode(fops);
   6.237 - 	error = PTR_ERR(inode);
   6.238 - 	if (IS_ERR(inode))
   6.239 - 		goto eexit_2;
   6.240 -@@ -758,7 +756,7 @@ static int ep_getfd(int *efd, struct ino
   6.241 - 
   6.242 - 	file->f_pos = 0;
   6.243 - 	file->f_flags = O_RDONLY;
   6.244 --	file->f_op = &eventpoll_fops;
   6.245 -+	file->f_op = fops;
   6.246 - 	file->f_mode = FMODE_READ;
   6.247 - 	file->f_version = 0;
   6.248 - 	file->private_data = ep;
   6.249 -@@ -1574,7 +1572,7 @@ static int eventpollfs_delete_dentry(str
   6.250 - }
   6.251 - 
   6.252 - 
   6.253 --static struct inode *ep_eventpoll_inode(void)
   6.254 -+static struct inode *ep_eventpoll_inode(struct file_operations *fops)
   6.255 - {
   6.256 - 	int error = -ENOMEM;
   6.257 - 	struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
   6.258 -@@ -1582,7 +1580,7 @@ static struct inode *ep_eventpoll_inode(
   6.259 - 	if (!inode)
   6.260 - 		goto eexit_1;
   6.261 - 
   6.262 --	inode->i_fop = &eventpoll_fops;
   6.263 -+	inode->i_fop = fops;
   6.264 - 
   6.265 - 	/*
   6.266 - 	 * Mark the inode dirty from the very beginning,
   6.267 -diff -pruN ../orig-linux-2.6.16.29/include/linux/aio.h ./include/linux/aio.h
   6.268 ---- ../orig-linux-2.6.16.29/include/linux/aio.h	2006-09-12 19:02:10.000000000 +0100
   6.269 -+++ ./include/linux/aio.h	2006-09-19 13:58:49.000000000 +0100
   6.270 -@@ -191,6 +191,11 @@ struct kioctx {
   6.271 - 	struct aio_ring_info	ring_info;
   6.272 - 
   6.273 - 	struct work_struct	wq;
   6.274 -+#ifdef CONFIG_EPOLL
   6.275 -+	// poll integration
   6.276 -+	wait_queue_head_t       poll_wait;
   6.277 -+	struct file		*file;
   6.278 -+#endif
   6.279 - };
   6.280 - 
   6.281 - /* prototypes */
   6.282 -diff -pruN ../orig-linux-2.6.16.29/include/linux/eventpoll.h ./include/linux/eventpoll.h
   6.283 ---- ../orig-linux-2.6.16.29/include/linux/eventpoll.h	2006-09-12 19:02:10.000000000 +0100
   6.284 -+++ ./include/linux/eventpoll.h	2006-09-19 13:58:49.000000000 +0100
   6.285 -@@ -86,6 +86,12 @@ static inline void eventpoll_release(str
   6.286 - }
   6.287 - 
   6.288 - 
   6.289 -+/*
   6.290 -+ * called by aio code to create fd that can poll the  aio event queueQ
   6.291 -+ */
   6.292 -+struct eventpoll;
   6.293 -+int ep_getfd(int *efd, struct inode **einode, struct file **efile,
   6.294 -+             struct eventpoll *ep, struct file_operations *fops);
   6.295 - #else
   6.296 - 
   6.297 - static inline void eventpoll_init_file(struct file *file) {}
     7.1 --- a/patches/linux-2.6.16.31/device_bind.patch	Mon Nov 27 13:50:02 2006 +0000
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,15 +0,0 @@
     7.4 -diff -pruN ../orig-linux-2.6.16.29/drivers/base/bus.c ./drivers/base/bus.c
     7.5 ---- ../orig-linux-2.6.16.29/drivers/base/bus.c	2006-09-12 19:02:10.000000000 +0100
     7.6 -+++ ./drivers/base/bus.c	2006-09-19 13:58:54.000000000 +0100
     7.7 -@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device
     7.8 - 		up(&dev->sem);
     7.9 - 		if (dev->parent)
    7.10 - 			up(&dev->parent->sem);
    7.11 -+
    7.12 -+		if (err > 0) 		/* success */
    7.13 -+			err = count;
    7.14 -+		else if (err == 0)	/* driver didn't accept device */
    7.15 -+			err = -ENODEV;
    7.16 - 	}
    7.17 - 	put_device(dev);
    7.18 - 	put_bus(bus);
     8.1 --- a/patches/linux-2.6.16.31/fix-hz-suspend.patch	Mon Nov 27 13:50:02 2006 +0000
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,26 +0,0 @@
     8.4 -diff -pruN ../orig-linux-2.6.16.29/kernel/timer.c ./kernel/timer.c
     8.5 ---- ../orig-linux-2.6.16.29/kernel/timer.c	2006-09-12 19:02:10.000000000 +0100
     8.6 -+++ ./kernel/timer.c	2006-09-19 13:58:58.000000000 +0100
     8.7 -@@ -555,6 +555,22 @@ found:
     8.8 - 	}
     8.9 - 	spin_unlock(&base->t_base.lock);
    8.10 - 
    8.11 -+	/*
    8.12 -+	 * It can happen that other CPUs service timer IRQs and increment
    8.13 -+	 * jiffies, but we have not yet got a local timer tick to process
    8.14 -+	 * the timer wheels.  In that case, the expiry time can be before
    8.15 -+	 * jiffies, but since the high-resolution timer here is relative to
    8.16 -+	 * jiffies, the default expression when high-resolution timers are
    8.17 -+	 * not active,
    8.18 -+	 *
    8.19 -+	 *   time_before(MAX_JIFFY_OFFSET + jiffies, expires)
    8.20 -+	 *
    8.21 -+	 * would falsely evaluate to true.  If that is the case, just
    8.22 -+	 * return jiffies so that we can immediately fire the local timer
    8.23 -+	 */
    8.24 -+	if (time_before(expires, jiffies))
    8.25 -+		return jiffies;
    8.26 -+
    8.27 - 	if (time_before(hr_expires, expires))
    8.28 - 		return hr_expires;
    8.29 - 
     9.1 --- a/patches/linux-2.6.16.31/fix-ide-cd-pio-mode.patch	Mon Nov 27 13:50:02 2006 +0000
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,18 +0,0 @@
     9.4 -diff -pruN ../orig-linux-2.6.16.29/drivers/ide/ide-lib.c ./drivers/ide/ide-lib.c
     9.5 ---- ../orig-linux-2.6.16.29/drivers/ide/ide-lib.c	2006-09-12 19:02:10.000000000 +0100
     9.6 -+++ ./drivers/ide/ide-lib.c	2006-09-19 13:59:03.000000000 +0100
     9.7 -@@ -410,10 +410,10 @@ void ide_toggle_bounce(ide_drive_t *driv
     9.8 - {
     9.9 - 	u64 addr = BLK_BOUNCE_HIGH;	/* dma64_addr_t */
    9.10 - 
    9.11 --	if (!PCI_DMA_BUS_IS_PHYS) {
    9.12 --		addr = BLK_BOUNCE_ANY;
    9.13 --	} else if (on && drive->media == ide_disk) {
    9.14 --		if (HWIF(drive)->pci_dev)
    9.15 -+	if (on && drive->media == ide_disk) {
    9.16 -+		if (!PCI_DMA_BUS_IS_PHYS)
    9.17 -+			addr = BLK_BOUNCE_ANY;
    9.18 -+		else if (HWIF(drive)->pci_dev)
    9.19 - 			addr = HWIF(drive)->pci_dev->dma_mask;
    9.20 - 	}
    9.21 - 
    10.1 --- a/patches/linux-2.6.16.31/i386-mach-io-check-nmi.patch	Mon Nov 27 13:50:02 2006 +0000
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,45 +0,0 @@
    10.4 -diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/traps.c ./arch/i386/kernel/traps.c
    10.5 ---- ../orig-linux-2.6.16.29/arch/i386/kernel/traps.c	2006-09-12 19:02:10.000000000 +0100
    10.6 -+++ ./arch/i386/kernel/traps.c	2006-09-19 13:59:06.000000000 +0100
    10.7 -@@ -567,18 +567,11 @@ static void mem_parity_error(unsigned ch
    10.8 - 
    10.9 - static void io_check_error(unsigned char reason, struct pt_regs * regs)
   10.10 - {
   10.11 --	unsigned long i;
   10.12 --
   10.13 - 	printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
   10.14 - 	show_registers(regs);
   10.15 - 
   10.16 - 	/* Re-enable the IOCK line, wait for a few seconds */
   10.17 --	reason = (reason & 0xf) | 8;
   10.18 --	outb(reason, 0x61);
   10.19 --	i = 2000;
   10.20 --	while (--i) udelay(1000);
   10.21 --	reason &= ~8;
   10.22 --	outb(reason, 0x61);
   10.23 -+	clear_io_check_error(reason);
   10.24 - }
   10.25 - 
   10.26 - static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
   10.27 -diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/mach-default/mach_traps.h ./include/asm-i386/mach-default/mach_traps.h
   10.28 ---- ../orig-linux-2.6.16.29/include/asm-i386/mach-default/mach_traps.h	2006-09-12 19:02:10.000000000 +0100
   10.29 -+++ ./include/asm-i386/mach-default/mach_traps.h	2006-09-19 13:59:06.000000000 +0100
   10.30 -@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsig
   10.31 - 	outb(reason, 0x61);
   10.32 - }
   10.33 - 
   10.34 -+static inline void clear_io_check_error(unsigned char reason)
   10.35 -+{
   10.36 -+	unsigned long i;
   10.37 -+
   10.38 -+	reason = (reason & 0xf) | 8;
   10.39 -+	outb(reason, 0x61);
   10.40 -+	i = 2000;
   10.41 -+	while (--i) udelay(1000);
   10.42 -+	reason &= ~8;
   10.43 -+	outb(reason, 0x61);
   10.44 -+}
   10.45 -+
   10.46 - static inline unsigned char get_nmi_reason(void)
   10.47 - {
   10.48 - 	return inb(0x61);
    11.1 --- a/patches/linux-2.6.16.31/ipv6-no-autoconf.patch	Mon Nov 27 13:50:02 2006 +0000
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,19 +0,0 @@
    11.4 -diff -pruN ../orig-linux-2.6.16.29/net/ipv6/addrconf.c ./net/ipv6/addrconf.c
    11.5 ---- ../orig-linux-2.6.16.29/net/ipv6/addrconf.c	2006-09-12 19:02:10.000000000 +0100
    11.6 -+++ ./net/ipv6/addrconf.c	2006-09-19 13:59:11.000000000 +0100
    11.7 -@@ -2471,6 +2471,7 @@ static void addrconf_dad_start(struct in
    11.8 - 	spin_lock_bh(&ifp->lock);
    11.9 - 
   11.10 - 	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
   11.11 -+	    !(dev->flags&IFF_MULTICAST) ||
   11.12 - 	    !(ifp->flags&IFA_F_TENTATIVE)) {
   11.13 - 		ifp->flags &= ~IFA_F_TENTATIVE;
   11.14 - 		spin_unlock_bh(&ifp->lock);
   11.15 -@@ -2555,6 +2556,7 @@ static void addrconf_dad_completed(struc
   11.16 - 	if (ifp->idev->cnf.forwarding == 0 &&
   11.17 - 	    ifp->idev->cnf.rtr_solicits > 0 &&
   11.18 - 	    (dev->flags&IFF_LOOPBACK) == 0 &&
   11.19 -+	    (dev->flags & IFF_MULTICAST) &&
   11.20 - 	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
   11.21 - 		struct in6_addr all_routers;
   11.22 - 
    12.1 --- a/patches/linux-2.6.16.31/net-csum.patch	Mon Nov 27 13:50:02 2006 +0000
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,63 +0,0 @@
    12.4 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c
    12.5 ---- ../orig-linux-2.6.16.29/net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-09-12 19:02:10.000000000 +0100
    12.6 -+++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-09-19 13:59:15.000000000 +0100
    12.7 -@@ -129,7 +129,12 @@ tcp_manip_pkt(struct sk_buff **pskb,
    12.8 - 	if (hdrsize < sizeof(*hdr))
    12.9 - 		return 1;
   12.10 - 
   12.11 --	hdr->check = ip_nat_cheat_check(~oldip, newip,
   12.12 -+#ifdef CONFIG_XEN
   12.13 -+	if ((*pskb)->proto_csum_blank)
   12.14 -+		hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
   12.15 -+	else
   12.16 -+#endif
   12.17 -+		hdr->check = ip_nat_cheat_check(~oldip, newip,
   12.18 - 					ip_nat_cheat_check(oldport ^ 0xFFFF,
   12.19 - 							   newport,
   12.20 - 							   hdr->check));
   12.21 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c
   12.22 ---- ../orig-linux-2.6.16.29/net/ipv4/netfilter/ip_nat_proto_udp.c	2006-09-12 19:02:10.000000000 +0100
   12.23 -+++ ./net/ipv4/netfilter/ip_nat_proto_udp.c	2006-09-19 13:59:15.000000000 +0100
   12.24 -@@ -113,11 +113,17 @@ udp_manip_pkt(struct sk_buff **pskb,
   12.25 - 		newport = tuple->dst.u.udp.port;
   12.26 - 		portptr = &hdr->dest;
   12.27 - 	}
   12.28 --	if (hdr->check) /* 0 is a special case meaning no checksum */
   12.29 --		hdr->check = ip_nat_cheat_check(~oldip, newip,
   12.30 -+	if (hdr->check) { /* 0 is a special case meaning no checksum */
   12.31 -+#ifdef CONFIG_XEN
   12.32 -+		if ((*pskb)->proto_csum_blank)
   12.33 -+			hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
   12.34 -+		else
   12.35 -+#endif
   12.36 -+			hdr->check = ip_nat_cheat_check(~oldip, newip,
   12.37 - 					ip_nat_cheat_check(*portptr ^ 0xFFFF,
   12.38 - 							   newport,
   12.39 - 							   hdr->check));
   12.40 -+	}
   12.41 - 	*portptr = newport;
   12.42 - 	return 1;
   12.43 - }
   12.44 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/xfrm4_output.c ./net/ipv4/xfrm4_output.c
   12.45 ---- ../orig-linux-2.6.16.29/net/ipv4/xfrm4_output.c	2006-09-12 19:02:10.000000000 +0100
   12.46 -+++ ./net/ipv4/xfrm4_output.c	2006-09-19 13:59:15.000000000 +0100
   12.47 -@@ -17,6 +17,8 @@
   12.48 - #include <net/xfrm.h>
   12.49 - #include <net/icmp.h>
   12.50 - 
   12.51 -+extern int skb_checksum_setup(struct sk_buff *skb);
   12.52 -+
   12.53 - /* Add encapsulation header.
   12.54 -  *
   12.55 -  * In transport mode, the IP header will be moved forward to make space
   12.56 -@@ -103,6 +105,10 @@ static int xfrm4_output_one(struct sk_bu
   12.57 - 	struct xfrm_state *x = dst->xfrm;
   12.58 - 	int err;
   12.59 - 	
   12.60 -+	err = skb_checksum_setup(skb);
   12.61 -+	if (err)
   12.62 -+		goto error_nolock;
   12.63 -+
   12.64 - 	if (skb->ip_summed == CHECKSUM_HW) {
   12.65 - 		err = skb_checksum_help(skb, 0);
   12.66 - 		if (err)
    13.1 --- a/patches/linux-2.6.16.31/net-gso-0-base.patch	Mon Nov 27 13:50:02 2006 +0000
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,2835 +0,0 @@
    13.4 -diff -pruN ../orig-linux-2.6.16.29/Documentation/networking/netdevices.txt ./Documentation/networking/netdevices.txt
    13.5 ---- ../orig-linux-2.6.16.29/Documentation/networking/netdevices.txt	2006-09-12 19:02:10.000000000 +0100
    13.6 -+++ ./Documentation/networking/netdevices.txt	2006-09-19 13:59:20.000000000 +0100
    13.7 -@@ -42,9 +42,9 @@ dev->get_stats:
    13.8 - 	Context: nominally process, but don't sleep inside an rwlock
    13.9 - 
   13.10 - dev->hard_start_xmit:
   13.11 --	Synchronization: dev->xmit_lock spinlock.
   13.12 -+	Synchronization: netif_tx_lock spinlock.
   13.13 - 	When the driver sets NETIF_F_LLTX in dev->features this will be
   13.14 --	called without holding xmit_lock. In this case the driver 
   13.15 -+	called without holding netif_tx_lock. In this case the driver
   13.16 - 	has to lock by itself when needed. It is recommended to use a try lock
   13.17 - 	for this and return -1 when the spin lock fails. 
   13.18 - 	The locking there should also properly protect against 
   13.19 -@@ -62,12 +62,12 @@ dev->hard_start_xmit:
   13.20 - 	  Only valid when NETIF_F_LLTX is set.
   13.21 - 
   13.22 - dev->tx_timeout:
   13.23 --	Synchronization: dev->xmit_lock spinlock.
   13.24 -+	Synchronization: netif_tx_lock spinlock.
   13.25 - 	Context: BHs disabled
   13.26 - 	Notes: netif_queue_stopped() is guaranteed true
   13.27 - 
   13.28 - dev->set_multicast_list:
   13.29 --	Synchronization: dev->xmit_lock spinlock.
   13.30 -+	Synchronization: netif_tx_lock spinlock.
   13.31 - 	Context: BHs disabled
   13.32 - 
   13.33 - dev->poll:
   13.34 -diff -pruN ../orig-linux-2.6.16.29/drivers/block/aoe/aoenet.c ./drivers/block/aoe/aoenet.c
   13.35 ---- ../orig-linux-2.6.16.29/drivers/block/aoe/aoenet.c	2006-09-12 19:02:10.000000000 +0100
   13.36 -+++ ./drivers/block/aoe/aoenet.c	2006-09-19 13:59:20.000000000 +0100
   13.37 -@@ -95,9 +95,8 @@ mac_addr(char addr[6])
   13.38 - static struct sk_buff *
   13.39 - skb_check(struct sk_buff *skb)
   13.40 - {
   13.41 --	if (skb_is_nonlinear(skb))
   13.42 - 	if ((skb = skb_share_check(skb, GFP_ATOMIC)))
   13.43 --	if (skb_linearize(skb, GFP_ATOMIC) < 0) {
   13.44 -+	if (skb_linearize(skb)) {
   13.45 - 		dev_kfree_skb(skb);
   13.46 - 		return NULL;
   13.47 - 	}
   13.48 -diff -pruN ../orig-linux-2.6.16.29/drivers/infiniband/ulp/ipoib/ipoib_multicast.c ./drivers/infiniband/ulp/ipoib/ipoib_multicast.c
   13.49 ---- ../orig-linux-2.6.16.29/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2006-09-12 19:02:10.000000000 +0100
   13.50 -+++ ./drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2006-09-19 13:59:20.000000000 +0100
   13.51 -@@ -821,7 +821,8 @@ void ipoib_mcast_restart_task(void *dev_
   13.52 - 
   13.53 - 	ipoib_mcast_stop_thread(dev, 0);
   13.54 - 
   13.55 --	spin_lock_irqsave(&dev->xmit_lock, flags);
   13.56 -+	local_irq_save(flags);
   13.57 -+	netif_tx_lock(dev);
   13.58 - 	spin_lock(&priv->lock);
   13.59 - 
   13.60 - 	/*
   13.61 -@@ -896,7 +897,8 @@ void ipoib_mcast_restart_task(void *dev_
   13.62 - 	}
   13.63 - 
   13.64 - 	spin_unlock(&priv->lock);
   13.65 --	spin_unlock_irqrestore(&dev->xmit_lock, flags);
   13.66 -+	netif_tx_unlock(dev);
   13.67 -+	local_irq_restore(flags);
   13.68 - 
   13.69 - 	/* We have to cancel outside of the spinlock */
   13.70 - 	list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
   13.71 -diff -pruN ../orig-linux-2.6.16.29/drivers/media/dvb/dvb-core/dvb_net.c ./drivers/media/dvb/dvb-core/dvb_net.c
   13.72 ---- ../orig-linux-2.6.16.29/drivers/media/dvb/dvb-core/dvb_net.c	2006-09-12 19:02:10.000000000 +0100
   13.73 -+++ ./drivers/media/dvb/dvb-core/dvb_net.c	2006-09-19 13:59:20.000000000 +0100
   13.74 -@@ -1052,7 +1052,7 @@ static void wq_set_multicast_list (void 
   13.75 - 
   13.76 - 	dvb_net_feed_stop(dev);
   13.77 - 	priv->rx_mode = RX_MODE_UNI;
   13.78 --	spin_lock_bh(&dev->xmit_lock);
   13.79 -+	netif_tx_lock_bh(dev);
   13.80 - 
   13.81 - 	if (dev->flags & IFF_PROMISC) {
   13.82 - 		dprintk("%s: promiscuous mode\n", dev->name);
   13.83 -@@ -1077,7 +1077,7 @@ static void wq_set_multicast_list (void 
   13.84 - 		}
   13.85 - 	}
   13.86 - 
   13.87 --	spin_unlock_bh(&dev->xmit_lock);
   13.88 -+	netif_tx_unlock_bh(dev);
   13.89 - 	dvb_net_feed_start(dev);
   13.90 - }
   13.91 - 
   13.92 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/8139cp.c ./drivers/net/8139cp.c
   13.93 ---- ../orig-linux-2.6.16.29/drivers/net/8139cp.c	2006-09-12 19:02:10.000000000 +0100
   13.94 -+++ ./drivers/net/8139cp.c	2006-09-19 13:59:20.000000000 +0100
   13.95 -@@ -794,7 +794,7 @@ static int cp_start_xmit (struct sk_buff
   13.96 - 	entry = cp->tx_head;
   13.97 - 	eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
   13.98 - 	if (dev->features & NETIF_F_TSO)
   13.99 --		mss = skb_shinfo(skb)->tso_size;
  13.100 -+		mss = skb_shinfo(skb)->gso_size;
  13.101 - 
  13.102 - 	if (skb_shinfo(skb)->nr_frags == 0) {
  13.103 - 		struct cp_desc *txd = &cp->tx_ring[entry];
  13.104 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/bnx2.c ./drivers/net/bnx2.c
  13.105 ---- ../orig-linux-2.6.16.29/drivers/net/bnx2.c	2006-09-12 19:02:10.000000000 +0100
  13.106 -+++ ./drivers/net/bnx2.c	2006-09-19 13:59:20.000000000 +0100
  13.107 -@@ -1593,7 +1593,7 @@ bnx2_tx_int(struct bnx2 *bp)
  13.108 - 		skb = tx_buf->skb;
  13.109 - #ifdef BCM_TSO 
  13.110 - 		/* partial BD completions possible with TSO packets */
  13.111 --		if (skb_shinfo(skb)->tso_size) {
  13.112 -+		if (skb_shinfo(skb)->gso_size) {
  13.113 - 			u16 last_idx, last_ring_idx;
  13.114 - 
  13.115 - 			last_idx = sw_cons +
  13.116 -@@ -1948,7 +1948,7 @@ bnx2_poll(struct net_device *dev, int *b
  13.117 - 	return 1;
  13.118 - }
  13.119 - 
  13.120 --/* Called with rtnl_lock from vlan functions and also dev->xmit_lock
  13.121 -+/* Called with rtnl_lock from vlan functions and also netif_tx_lock
  13.122 -  * from set_multicast.
  13.123 -  */
  13.124 - static void
  13.125 -@@ -4403,7 +4403,7 @@ bnx2_vlan_rx_kill_vid(struct net_device 
  13.126 - }
  13.127 - #endif
  13.128 - 
  13.129 --/* Called with dev->xmit_lock.
  13.130 -+/* Called with netif_tx_lock.
  13.131 -  * hard_start_xmit is pseudo-lockless - a lock is only required when
  13.132 -  * the tx queue is full. This way, we get the benefit of lockless
  13.133 -  * operations most of the time without the complexities to handle
  13.134 -@@ -4441,7 +4441,7 @@ bnx2_start_xmit(struct sk_buff *skb, str
  13.135 - 			(TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
  13.136 - 	}
  13.137 - #ifdef BCM_TSO 
  13.138 --	if ((mss = skb_shinfo(skb)->tso_size) &&
  13.139 -+	if ((mss = skb_shinfo(skb)->gso_size) &&
  13.140 - 		(skb->len > (bp->dev->mtu + ETH_HLEN))) {
  13.141 - 		u32 tcp_opt_len, ip_tcp_len;
  13.142 - 
  13.143 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/bonding/bond_main.c ./drivers/net/bonding/bond_main.c
  13.144 ---- ../orig-linux-2.6.16.29/drivers/net/bonding/bond_main.c	2006-09-12 19:02:10.000000000 +0100
  13.145 -+++ ./drivers/net/bonding/bond_main.c	2006-09-19 13:59:20.000000000 +0100
  13.146 -@@ -1145,8 +1145,7 @@ int bond_sethwaddr(struct net_device *bo
  13.147 - }
  13.148 - 
  13.149 - #define BOND_INTERSECT_FEATURES \
  13.150 --	(NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\
  13.151 --	NETIF_F_TSO|NETIF_F_UFO)
  13.152 -+	(NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO)
  13.153 - 
  13.154 - /* 
  13.155 -  * Compute the common dev->feature set available to all slaves.  Some
  13.156 -@@ -1164,9 +1163,7 @@ static int bond_compute_features(struct 
  13.157 - 		features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
  13.158 - 
  13.159 - 	if ((features & NETIF_F_SG) && 
  13.160 --	    !(features & (NETIF_F_IP_CSUM |
  13.161 --			  NETIF_F_NO_CSUM |
  13.162 --			  NETIF_F_HW_CSUM)))
  13.163 -+	    !(features & NETIF_F_ALL_CSUM))
  13.164 - 		features &= ~NETIF_F_SG;
  13.165 - 
  13.166 - 	/* 
  13.167 -@@ -4147,7 +4144,7 @@ static int bond_init(struct net_device *
  13.168 - 	 */
  13.169 - 	bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
  13.170 - 
  13.171 --	/* don't acquire bond device's xmit_lock when 
  13.172 -+	/* don't acquire bond device's netif_tx_lock when
  13.173 - 	 * transmitting */
  13.174 - 	bond_dev->features |= NETIF_F_LLTX;
  13.175 - 
  13.176 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/chelsio/sge.c ./drivers/net/chelsio/sge.c
  13.177 ---- ../orig-linux-2.6.16.29/drivers/net/chelsio/sge.c	2006-09-12 19:02:10.000000000 +0100
  13.178 -+++ ./drivers/net/chelsio/sge.c	2006-09-19 13:59:20.000000000 +0100
  13.179 -@@ -1419,7 +1419,7 @@ int t1_start_xmit(struct sk_buff *skb, s
  13.180 - 	struct cpl_tx_pkt *cpl;
  13.181 - 
  13.182 - #ifdef NETIF_F_TSO
  13.183 --	if (skb_shinfo(skb)->tso_size) {
  13.184 -+	if (skb_shinfo(skb)->gso_size) {
  13.185 - 		int eth_type;
  13.186 - 		struct cpl_tx_pkt_lso *hdr;
  13.187 - 
  13.188 -@@ -1434,7 +1434,7 @@ int t1_start_xmit(struct sk_buff *skb, s
  13.189 - 		hdr->ip_hdr_words = skb->nh.iph->ihl;
  13.190 - 		hdr->tcp_hdr_words = skb->h.th->doff;
  13.191 - 		hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type,
  13.192 --						skb_shinfo(skb)->tso_size));
  13.193 -+						skb_shinfo(skb)->gso_size));
  13.194 - 		hdr->len = htonl(skb->len - sizeof(*hdr));
  13.195 - 		cpl = (struct cpl_tx_pkt *)hdr;
  13.196 - 		sge->stats.tx_lso_pkts++;
  13.197 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/e1000/e1000_main.c ./drivers/net/e1000/e1000_main.c
  13.198 ---- ../orig-linux-2.6.16.29/drivers/net/e1000/e1000_main.c	2006-09-12 19:02:10.000000000 +0100
  13.199 -+++ ./drivers/net/e1000/e1000_main.c	2006-09-19 13:59:20.000000000 +0100
  13.200 -@@ -2526,7 +2526,7 @@ e1000_tso(struct e1000_adapter *adapter,
  13.201 - 	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
  13.202 - 	int err;
  13.203 - 
  13.204 --	if (skb_shinfo(skb)->tso_size) {
  13.205 -+	if (skb_shinfo(skb)->gso_size) {
  13.206 - 		if (skb_header_cloned(skb)) {
  13.207 - 			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
  13.208 - 			if (err)
  13.209 -@@ -2534,7 +2534,7 @@ e1000_tso(struct e1000_adapter *adapter,
  13.210 - 		}
  13.211 - 
  13.212 - 		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
  13.213 --		mss = skb_shinfo(skb)->tso_size;
  13.214 -+		mss = skb_shinfo(skb)->gso_size;
  13.215 - 		if (skb->protocol == ntohs(ETH_P_IP)) {
  13.216 - 			skb->nh.iph->tot_len = 0;
  13.217 - 			skb->nh.iph->check = 0;
  13.218 -@@ -2651,7 +2651,7 @@ e1000_tx_map(struct e1000_adapter *adapt
  13.219 - 		 * tso gets written back prematurely before the data is fully
  13.220 - 		 * DMAd to the controller */
  13.221 - 		if (!skb->data_len && tx_ring->last_tx_tso &&
  13.222 --				!skb_shinfo(skb)->tso_size) {
  13.223 -+				!skb_shinfo(skb)->gso_size) {
  13.224 - 			tx_ring->last_tx_tso = 0;
  13.225 - 			size -= 4;
  13.226 - 		}
  13.227 -@@ -2893,7 +2893,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
  13.228 - 	}
  13.229 - 
  13.230 - #ifdef NETIF_F_TSO
  13.231 --	mss = skb_shinfo(skb)->tso_size;
  13.232 -+	mss = skb_shinfo(skb)->gso_size;
  13.233 - 	/* The controller does a simple calculation to 
  13.234 - 	 * make sure there is enough room in the FIFO before
  13.235 - 	 * initiating the DMA for each buffer.  The calc is:
  13.236 -@@ -2935,7 +2935,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
  13.237 - #ifdef NETIF_F_TSO
  13.238 - 	/* Controller Erratum workaround */
  13.239 - 	if (!skb->data_len && tx_ring->last_tx_tso &&
  13.240 --		!skb_shinfo(skb)->tso_size)
  13.241 -+		!skb_shinfo(skb)->gso_size)
  13.242 - 		count++;
  13.243 - #endif
  13.244 - 
  13.245 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/forcedeth.c ./drivers/net/forcedeth.c
  13.246 ---- ../orig-linux-2.6.16.29/drivers/net/forcedeth.c	2006-09-12 19:02:10.000000000 +0100
  13.247 -+++ ./drivers/net/forcedeth.c	2006-09-19 13:59:20.000000000 +0100
  13.248 -@@ -482,9 +482,9 @@ typedef union _ring_type {
  13.249 -  * critical parts:
  13.250 -  * - rx is (pseudo-) lockless: it relies on the single-threading provided
  13.251 -  *	by the arch code for interrupts.
  13.252 -- * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission
  13.253 -+ * - tx setup is lockless: it relies on netif_tx_lock. Actual submission
  13.254 -  *	needs dev->priv->lock :-(
  13.255 -- * - set_multicast_list: preparation lockless, relies on dev->xmit_lock.
  13.256 -+ * - set_multicast_list: preparation lockless, relies on netif_tx_lock.
  13.257 -  */
  13.258 - 
  13.259 - /* in dev: base, irq */
  13.260 -@@ -1016,7 +1016,7 @@ static void drain_ring(struct net_device
  13.261 - 
  13.262 - /*
  13.263 -  * nv_start_xmit: dev->hard_start_xmit function
  13.264 -- * Called with dev->xmit_lock held.
  13.265 -+ * Called with netif_tx_lock held.
  13.266 -  */
  13.267 - static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
  13.268 - {
  13.269 -@@ -1105,8 +1105,8 @@ static int nv_start_xmit(struct sk_buff 
  13.270 - 	np->tx_skbuff[nr] = skb;
  13.271 - 
  13.272 - #ifdef NETIF_F_TSO
  13.273 --	if (skb_shinfo(skb)->tso_size)
  13.274 --		tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT);
  13.275 -+	if (skb_shinfo(skb)->gso_size)
  13.276 -+		tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT);
  13.277 - 	else
  13.278 - #endif
  13.279 - 	tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
  13.280 -@@ -1203,7 +1203,7 @@ static void nv_tx_done(struct net_device
  13.281 - 
  13.282 - /*
  13.283 -  * nv_tx_timeout: dev->tx_timeout function
  13.284 -- * Called with dev->xmit_lock held.
  13.285 -+ * Called with netif_tx_lock held.
  13.286 -  */
  13.287 - static void nv_tx_timeout(struct net_device *dev)
  13.288 - {
  13.289 -@@ -1524,7 +1524,7 @@ static int nv_change_mtu(struct net_devi
  13.290 - 		 * Changing the MTU is a rare event, it shouldn't matter.
  13.291 - 		 */
  13.292 - 		disable_irq(dev->irq);
  13.293 --		spin_lock_bh(&dev->xmit_lock);
  13.294 -+		netif_tx_lock_bh(dev);
  13.295 - 		spin_lock(&np->lock);
  13.296 - 		/* stop engines */
  13.297 - 		nv_stop_rx(dev);
  13.298 -@@ -1559,7 +1559,7 @@ static int nv_change_mtu(struct net_devi
  13.299 - 		nv_start_rx(dev);
  13.300 - 		nv_start_tx(dev);
  13.301 - 		spin_unlock(&np->lock);
  13.302 --		spin_unlock_bh(&dev->xmit_lock);
  13.303 -+		netif_tx_unlock_bh(dev);
  13.304 - 		enable_irq(dev->irq);
  13.305 - 	}
  13.306 - 	return 0;
  13.307 -@@ -1594,7 +1594,7 @@ static int nv_set_mac_address(struct net
  13.308 - 	memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN);
  13.309 - 
  13.310 - 	if (netif_running(dev)) {
  13.311 --		spin_lock_bh(&dev->xmit_lock);
  13.312 -+		netif_tx_lock_bh(dev);
  13.313 - 		spin_lock_irq(&np->lock);
  13.314 - 
  13.315 - 		/* stop rx engine */
  13.316 -@@ -1606,7 +1606,7 @@ static int nv_set_mac_address(struct net
  13.317 - 		/* restart rx engine */
  13.318 - 		nv_start_rx(dev);
  13.319 - 		spin_unlock_irq(&np->lock);
  13.320 --		spin_unlock_bh(&dev->xmit_lock);
  13.321 -+		netif_tx_unlock_bh(dev);
  13.322 - 	} else {
  13.323 - 		nv_copy_mac_to_hw(dev);
  13.324 - 	}
  13.325 -@@ -1615,7 +1615,7 @@ static int nv_set_mac_address(struct net
  13.326 - 
  13.327 - /*
  13.328 -  * nv_set_multicast: dev->set_multicast function
  13.329 -- * Called with dev->xmit_lock held.
  13.330 -+ * Called with netif_tx_lock held.
  13.331 -  */
  13.332 - static void nv_set_multicast(struct net_device *dev)
  13.333 - {
  13.334 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/hamradio/6pack.c ./drivers/net/hamradio/6pack.c
  13.335 ---- ../orig-linux-2.6.16.29/drivers/net/hamradio/6pack.c	2006-09-12 19:02:10.000000000 +0100
  13.336 -+++ ./drivers/net/hamradio/6pack.c	2006-09-19 13:59:20.000000000 +0100
  13.337 -@@ -308,9 +308,9 @@ static int sp_set_mac_address(struct net
  13.338 - {
  13.339 - 	struct sockaddr_ax25 *sa = addr;
  13.340 - 
  13.341 --	spin_lock_irq(&dev->xmit_lock);
  13.342 -+	netif_tx_lock_bh(dev);
  13.343 - 	memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
  13.344 --	spin_unlock_irq(&dev->xmit_lock);
  13.345 -+	netif_tx_unlock_bh(dev);
  13.346 - 
  13.347 - 	return 0;
  13.348 - }
  13.349 -@@ -767,9 +767,9 @@ static int sixpack_ioctl(struct tty_stru
  13.350 - 			break;
  13.351 - 		}
  13.352 - 
  13.353 --		spin_lock_irq(&dev->xmit_lock);
  13.354 -+		netif_tx_lock_bh(dev);
  13.355 - 		memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
  13.356 --		spin_unlock_irq(&dev->xmit_lock);
  13.357 -+		netif_tx_unlock_bh(dev);
  13.358 - 
  13.359 - 		err = 0;
  13.360 - 		break;
  13.361 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/hamradio/mkiss.c ./drivers/net/hamradio/mkiss.c
  13.362 ---- ../orig-linux-2.6.16.29/drivers/net/hamradio/mkiss.c	2006-09-12 19:02:10.000000000 +0100
  13.363 -+++ ./drivers/net/hamradio/mkiss.c	2006-09-19 13:59:20.000000000 +0100
  13.364 -@@ -357,9 +357,9 @@ static int ax_set_mac_address(struct net
  13.365 - {
  13.366 - 	struct sockaddr_ax25 *sa = addr;
  13.367 - 
  13.368 --	spin_lock_irq(&dev->xmit_lock);
  13.369 -+	netif_tx_lock_bh(dev);
  13.370 - 	memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
  13.371 --	spin_unlock_irq(&dev->xmit_lock);
  13.372 -+	netif_tx_unlock_bh(dev);
  13.373 - 
  13.374 - 	return 0;
  13.375 - }
  13.376 -@@ -886,9 +886,9 @@ static int mkiss_ioctl(struct tty_struct
  13.377 - 			break;
  13.378 - 		}
  13.379 - 
  13.380 --		spin_lock_irq(&dev->xmit_lock);
  13.381 -+		netif_tx_lock_bh(dev);
  13.382 - 		memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
  13.383 --		spin_unlock_irq(&dev->xmit_lock);
  13.384 -+		netif_tx_unlock_bh(dev);
  13.385 - 
  13.386 - 		err = 0;
  13.387 - 		break;
  13.388 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/ifb.c ./drivers/net/ifb.c
  13.389 ---- ../orig-linux-2.6.16.29/drivers/net/ifb.c	2006-09-12 19:02:10.000000000 +0100
  13.390 -+++ ./drivers/net/ifb.c	2006-09-19 13:59:20.000000000 +0100
  13.391 -@@ -76,13 +76,13 @@ static void ri_tasklet(unsigned long dev
  13.392 - 	dp->st_task_enter++;
  13.393 - 	if ((skb = skb_peek(&dp->tq)) == NULL) {
  13.394 - 		dp->st_txq_refl_try++;
  13.395 --		if (spin_trylock(&_dev->xmit_lock)) {
  13.396 -+		if (netif_tx_trylock(_dev)) {
  13.397 - 			dp->st_rxq_enter++;
  13.398 - 			while ((skb = skb_dequeue(&dp->rq)) != NULL) {
  13.399 - 				skb_queue_tail(&dp->tq, skb);
  13.400 - 				dp->st_rx2tx_tran++;
  13.401 - 			}
  13.402 --			spin_unlock(&_dev->xmit_lock);
  13.403 -+			netif_tx_unlock(_dev);
  13.404 - 		} else {
  13.405 - 			/* reschedule */
  13.406 - 			dp->st_rxq_notenter++;
  13.407 -@@ -110,7 +110,7 @@ static void ri_tasklet(unsigned long dev
  13.408 - 		}
  13.409 - 	}
  13.410 - 
  13.411 --	if (spin_trylock(&_dev->xmit_lock)) {
  13.412 -+	if (netif_tx_trylock(_dev)) {
  13.413 - 		dp->st_rxq_check++;
  13.414 - 		if ((skb = skb_peek(&dp->rq)) == NULL) {
  13.415 - 			dp->tasklet_pending = 0;
  13.416 -@@ -118,10 +118,10 @@ static void ri_tasklet(unsigned long dev
  13.417 - 				netif_wake_queue(_dev);
  13.418 - 		} else {
  13.419 - 			dp->st_rxq_rsch++;
  13.420 --			spin_unlock(&_dev->xmit_lock);
  13.421 -+			netif_tx_unlock(_dev);
  13.422 - 			goto resched;
  13.423 - 		}
  13.424 --		spin_unlock(&_dev->xmit_lock);
  13.425 -+		netif_tx_unlock(_dev);
  13.426 - 	} else {
  13.427 - resched:
  13.428 - 		dp->tasklet_pending = 1;
  13.429 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/irda/vlsi_ir.c ./drivers/net/irda/vlsi_ir.c
  13.430 ---- ../orig-linux-2.6.16.29/drivers/net/irda/vlsi_ir.c	2006-09-12 19:02:10.000000000 +0100
  13.431 -+++ ./drivers/net/irda/vlsi_ir.c	2006-09-19 13:59:20.000000000 +0100
  13.432 -@@ -959,7 +959,7 @@ static int vlsi_hard_start_xmit(struct s
  13.433 - 			    ||  (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec))
  13.434 - 			    	break;
  13.435 - 			udelay(100);
  13.436 --			/* must not sleep here - we are called under xmit_lock! */
  13.437 -+			/* must not sleep here - called under netif_tx_lock! */
  13.438 - 		}
  13.439 - 	}
  13.440 - 
  13.441 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/ixgb/ixgb_main.c ./drivers/net/ixgb/ixgb_main.c
  13.442 ---- ../orig-linux-2.6.16.29/drivers/net/ixgb/ixgb_main.c	2006-09-12 19:02:10.000000000 +0100
  13.443 -+++ ./drivers/net/ixgb/ixgb_main.c	2006-09-19 13:59:20.000000000 +0100
  13.444 -@@ -1163,7 +1163,7 @@ ixgb_tso(struct ixgb_adapter *adapter, s
  13.445 - 	uint16_t ipcse, tucse, mss;
  13.446 - 	int err;
  13.447 - 
  13.448 --	if(likely(skb_shinfo(skb)->tso_size)) {
  13.449 -+	if(likely(skb_shinfo(skb)->gso_size)) {
  13.450 - 		if (skb_header_cloned(skb)) {
  13.451 - 			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
  13.452 - 			if (err)
  13.453 -@@ -1171,7 +1171,7 @@ ixgb_tso(struct ixgb_adapter *adapter, s
  13.454 - 		}
  13.455 - 
  13.456 - 		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
  13.457 --		mss = skb_shinfo(skb)->tso_size;
  13.458 -+		mss = skb_shinfo(skb)->gso_size;
  13.459 - 		skb->nh.iph->tot_len = 0;
  13.460 - 		skb->nh.iph->check = 0;
  13.461 - 		skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr,
  13.462 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/loopback.c ./drivers/net/loopback.c
  13.463 ---- ../orig-linux-2.6.16.29/drivers/net/loopback.c	2006-09-12 19:02:10.000000000 +0100
  13.464 -+++ ./drivers/net/loopback.c	2006-09-19 13:59:20.000000000 +0100
  13.465 -@@ -74,7 +74,7 @@ static void emulate_large_send_offload(s
  13.466 - 	struct iphdr *iph = skb->nh.iph;
  13.467 - 	struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4));
  13.468 - 	unsigned int doffset = (iph->ihl + th->doff) * 4;
  13.469 --	unsigned int mtu = skb_shinfo(skb)->tso_size + doffset;
  13.470 -+	unsigned int mtu = skb_shinfo(skb)->gso_size + doffset;
  13.471 - 	unsigned int offset = 0;
  13.472 - 	u32 seq = ntohl(th->seq);
  13.473 - 	u16 id  = ntohs(iph->id);
  13.474 -@@ -139,7 +139,7 @@ static int loopback_xmit(struct sk_buff 
  13.475 - #endif
  13.476 - 
  13.477 - #ifdef LOOPBACK_TSO
  13.478 --	if (skb_shinfo(skb)->tso_size) {
  13.479 -+	if (skb_shinfo(skb)->gso_size) {
  13.480 - 		BUG_ON(skb->protocol != htons(ETH_P_IP));
  13.481 - 		BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP);
  13.482 - 
  13.483 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/mv643xx_eth.c ./drivers/net/mv643xx_eth.c
  13.484 ---- ../orig-linux-2.6.16.29/drivers/net/mv643xx_eth.c	2006-09-12 19:02:10.000000000 +0100
  13.485 -+++ ./drivers/net/mv643xx_eth.c	2006-09-19 13:59:20.000000000 +0100
  13.486 -@@ -1107,7 +1107,7 @@ static int mv643xx_eth_start_xmit(struct
  13.487 - 
  13.488 - #ifdef MV643XX_CHECKSUM_OFFLOAD_TX
  13.489 - 	if (has_tiny_unaligned_frags(skb)) {
  13.490 --		if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {
  13.491 -+		if (__skb_linearize(skb)) {
  13.492 - 			stats->tx_dropped++;
  13.493 - 			printk(KERN_DEBUG "%s: failed to linearize tiny "
  13.494 - 					"unaligned fragment\n", dev->name);
  13.495 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/natsemi.c ./drivers/net/natsemi.c
  13.496 ---- ../orig-linux-2.6.16.29/drivers/net/natsemi.c	2006-09-12 19:02:10.000000000 +0100
  13.497 -+++ ./drivers/net/natsemi.c	2006-09-19 13:59:20.000000000 +0100
  13.498 -@@ -323,12 +323,12 @@ performance critical codepaths:
  13.499 - The rx process only runs in the interrupt handler. Access from outside
  13.500 - the interrupt handler is only permitted after disable_irq().
  13.501 - 
  13.502 --The rx process usually runs under the dev->xmit_lock. If np->intr_tx_reap
  13.503 -+The rx process usually runs under the netif_tx_lock. If np->intr_tx_reap
  13.504 - is set, then access is permitted under spin_lock_irq(&np->lock).
  13.505 - 
  13.506 - Thus configuration functions that want to access everything must call
  13.507 - 	disable_irq(dev->irq);
  13.508 --	spin_lock_bh(dev->xmit_lock);
  13.509 -+	netif_tx_lock_bh(dev);
  13.510 - 	spin_lock_irq(&np->lock);
  13.511 - 
  13.512 - IV. Notes
  13.513 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/r8169.c ./drivers/net/r8169.c
  13.514 ---- ../orig-linux-2.6.16.29/drivers/net/r8169.c	2006-09-12 19:02:10.000000000 +0100
  13.515 -+++ ./drivers/net/r8169.c	2006-09-19 13:59:20.000000000 +0100
  13.516 -@@ -2171,7 +2171,7 @@ static int rtl8169_xmit_frags(struct rtl
  13.517 - static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev)
  13.518 - {
  13.519 - 	if (dev->features & NETIF_F_TSO) {
  13.520 --		u32 mss = skb_shinfo(skb)->tso_size;
  13.521 -+		u32 mss = skb_shinfo(skb)->gso_size;
  13.522 - 
  13.523 - 		if (mss)
  13.524 - 			return LargeSend | ((mss & MSSMask) << MSSShift);
  13.525 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/s2io.c ./drivers/net/s2io.c
  13.526 ---- ../orig-linux-2.6.16.29/drivers/net/s2io.c	2006-09-12 19:02:10.000000000 +0100
  13.527 -+++ ./drivers/net/s2io.c	2006-09-19 13:59:20.000000000 +0100
  13.528 -@@ -3522,8 +3522,8 @@ static int s2io_xmit(struct sk_buff *skb
  13.529 - 	txdp->Control_1 = 0;
  13.530 - 	txdp->Control_2 = 0;
  13.531 - #ifdef NETIF_F_TSO
  13.532 --	mss = skb_shinfo(skb)->tso_size;
  13.533 --	if (mss) {
  13.534 -+	mss = skb_shinfo(skb)->gso_size;
  13.535 -+	if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4) {
  13.536 - 		txdp->Control_1 |= TXD_TCP_LSO_EN;
  13.537 - 		txdp->Control_1 |= TXD_TCP_LSO_MSS(mss);
  13.538 - 	}
  13.539 -@@ -3543,10 +3543,10 @@ static int s2io_xmit(struct sk_buff *skb
  13.540 - 	}
  13.541 - 
  13.542 - 	frg_len = skb->len - skb->data_len;
  13.543 --	if (skb_shinfo(skb)->ufo_size) {
  13.544 -+	if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) {
  13.545 - 		int ufo_size;
  13.546 - 
  13.547 --		ufo_size = skb_shinfo(skb)->ufo_size;
  13.548 -+		ufo_size = skb_shinfo(skb)->gso_size;
  13.549 - 		ufo_size &= ~7;
  13.550 - 		txdp->Control_1 |= TXD_UFO_EN;
  13.551 - 		txdp->Control_1 |= TXD_UFO_MSS(ufo_size);
  13.552 -@@ -3572,7 +3572,7 @@ static int s2io_xmit(struct sk_buff *skb
  13.553 - 	txdp->Host_Control = (unsigned long) skb;
  13.554 - 	txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
  13.555 - 
  13.556 --	if (skb_shinfo(skb)->ufo_size)
  13.557 -+	if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
  13.558 - 		txdp->Control_1 |= TXD_UFO_EN;
  13.559 - 
  13.560 - 	frg_cnt = skb_shinfo(skb)->nr_frags;
  13.561 -@@ -3587,12 +3587,12 @@ static int s2io_xmit(struct sk_buff *skb
  13.562 - 		    (sp->pdev, frag->page, frag->page_offset,
  13.563 - 		     frag->size, PCI_DMA_TODEVICE);
  13.564 - 		txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size);
  13.565 --		if (skb_shinfo(skb)->ufo_size)
  13.566 -+		if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
  13.567 - 			txdp->Control_1 |= TXD_UFO_EN;
  13.568 - 	}
  13.569 - 	txdp->Control_1 |= TXD_GATHER_CODE_LAST;
  13.570 - 
  13.571 --	if (skb_shinfo(skb)->ufo_size)
  13.572 -+	if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
  13.573 - 		frg_cnt++; /* as Txd0 was used for inband header */
  13.574 - 
  13.575 - 	tx_fifo = mac_control->tx_FIFO_start[queue];
  13.576 -@@ -3606,7 +3606,7 @@ static int s2io_xmit(struct sk_buff *skb
  13.577 - 	if (mss)
  13.578 - 		val64 |= TX_FIFO_SPECIAL_FUNC;
  13.579 - #endif
  13.580 --	if (skb_shinfo(skb)->ufo_size)
  13.581 -+	if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
  13.582 - 		val64 |= TX_FIFO_SPECIAL_FUNC;
  13.583 - 	writeq(val64, &tx_fifo->List_Control);
  13.584 - 
  13.585 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/sky2.c ./drivers/net/sky2.c
  13.586 ---- ../orig-linux-2.6.16.29/drivers/net/sky2.c	2006-09-12 19:02:10.000000000 +0100
  13.587 -+++ ./drivers/net/sky2.c	2006-09-19 13:59:20.000000000 +0100
  13.588 -@@ -1125,7 +1125,7 @@ static unsigned tx_le_req(const struct s
  13.589 - 	count = sizeof(dma_addr_t) / sizeof(u32);
  13.590 - 	count += skb_shinfo(skb)->nr_frags * count;
  13.591 - 
  13.592 --	if (skb_shinfo(skb)->tso_size)
  13.593 -+	if (skb_shinfo(skb)->gso_size)
  13.594 - 		++count;
  13.595 - 
  13.596 - 	if (skb->ip_summed == CHECKSUM_HW)
  13.597 -@@ -1197,7 +1197,7 @@ static int sky2_xmit_frame(struct sk_buf
  13.598 - 	}
  13.599 - 
  13.600 - 	/* Check for TCP Segmentation Offload */
  13.601 --	mss = skb_shinfo(skb)->tso_size;
  13.602 -+	mss = skb_shinfo(skb)->gso_size;
  13.603 - 	if (mss != 0) {
  13.604 - 		/* just drop the packet if non-linear expansion fails */
  13.605 - 		if (skb_header_cloned(skb) &&
  13.606 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/tg3.c ./drivers/net/tg3.c
  13.607 ---- ../orig-linux-2.6.16.29/drivers/net/tg3.c	2006-09-12 19:02:10.000000000 +0100
  13.608 -+++ ./drivers/net/tg3.c	2006-09-19 13:59:20.000000000 +0100
  13.609 -@@ -3664,7 +3664,7 @@ static int tg3_start_xmit(struct sk_buff
  13.610 - #if TG3_TSO_SUPPORT != 0
  13.611 - 	mss = 0;
  13.612 - 	if (skb->len > (tp->dev->mtu + ETH_HLEN) &&
  13.613 --	    (mss = skb_shinfo(skb)->tso_size) != 0) {
  13.614 -+	    (mss = skb_shinfo(skb)->gso_size) != 0) {
  13.615 - 		int tcp_opt_len, ip_tcp_len;
  13.616 - 
  13.617 - 		if (skb_header_cloned(skb) &&
  13.618 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/tulip/winbond-840.c ./drivers/net/tulip/winbond-840.c
  13.619 ---- ../orig-linux-2.6.16.29/drivers/net/tulip/winbond-840.c	2006-09-12 19:02:10.000000000 +0100
  13.620 -+++ ./drivers/net/tulip/winbond-840.c	2006-09-19 13:59:20.000000000 +0100
  13.621 -@@ -1605,11 +1605,11 @@ static void __devexit w840_remove1 (stru
  13.622 -  * - get_stats:
  13.623 -  * 	spin_lock_irq(np->lock), doesn't touch hw if not present
  13.624 -  * - hard_start_xmit:
  13.625 -- * 	netif_stop_queue + spin_unlock_wait(&dev->xmit_lock);
  13.626 -+ * 	synchronize_irq + netif_tx_disable;
  13.627 -  * - tx_timeout:
  13.628 -- * 	netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
  13.629 -+ * 	netif_device_detach + netif_tx_disable;
  13.630 -  * - set_multicast_list
  13.631 -- * 	netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
  13.632 -+ * 	netif_device_detach + netif_tx_disable;
  13.633 -  * - interrupt handler
  13.634 -  * 	doesn't touch hw if not present, synchronize_irq waits for
  13.635 -  * 	running instances of the interrupt handler.
  13.636 -@@ -1635,11 +1635,10 @@ static int w840_suspend (struct pci_dev 
  13.637 - 		netif_device_detach(dev);
  13.638 - 		update_csr6(dev, 0);
  13.639 - 		iowrite32(0, ioaddr + IntrEnable);
  13.640 --		netif_stop_queue(dev);
  13.641 - 		spin_unlock_irq(&np->lock);
  13.642 - 
  13.643 --		spin_unlock_wait(&dev->xmit_lock);
  13.644 - 		synchronize_irq(dev->irq);
  13.645 -+		netif_tx_disable(dev);
  13.646 - 	
  13.647 - 		np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff;
  13.648 - 
  13.649 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/typhoon.c ./drivers/net/typhoon.c
  13.650 ---- ../orig-linux-2.6.16.29/drivers/net/typhoon.c	2006-09-12 19:02:10.000000000 +0100
  13.651 -+++ ./drivers/net/typhoon.c	2006-09-19 13:59:20.000000000 +0100
  13.652 -@@ -340,7 +340,7 @@ enum state_values {
  13.653 - #endif
  13.654 - 
  13.655 - #if defined(NETIF_F_TSO)
  13.656 --#define skb_tso_size(x)		(skb_shinfo(x)->tso_size)
  13.657 -+#define skb_tso_size(x)		(skb_shinfo(x)->gso_size)
  13.658 - #define TSO_NUM_DESCRIPTORS	2
  13.659 - #define TSO_OFFLOAD_ON		TYPHOON_OFFLOAD_TCP_SEGMENT
  13.660 - #else
  13.661 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/via-velocity.c ./drivers/net/via-velocity.c
  13.662 ---- ../orig-linux-2.6.16.29/drivers/net/via-velocity.c	2006-09-12 19:02:10.000000000 +0100
  13.663 -+++ ./drivers/net/via-velocity.c	2006-09-19 13:59:20.000000000 +0100
  13.664 -@@ -1899,6 +1899,13 @@ static int velocity_xmit(struct sk_buff 
  13.665 - 
  13.666 - 	int pktlen = skb->len;
  13.667 - 
  13.668 -+#ifdef VELOCITY_ZERO_COPY_SUPPORT
  13.669 -+	if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
  13.670 -+		kfree_skb(skb);
  13.671 -+		return 0;
  13.672 -+	}
  13.673 -+#endif
  13.674 -+
  13.675 - 	spin_lock_irqsave(&vptr->lock, flags);
  13.676 - 
  13.677 - 	index = vptr->td_curr[qnum];
  13.678 -@@ -1914,8 +1921,6 @@ static int velocity_xmit(struct sk_buff 
  13.679 - 	 */
  13.680 - 	if (pktlen < ETH_ZLEN) {
  13.681 - 		/* Cannot occur until ZC support */
  13.682 --		if(skb_linearize(skb, GFP_ATOMIC))
  13.683 --			return 0; 
  13.684 - 		pktlen = ETH_ZLEN;
  13.685 - 		memcpy(tdinfo->buf, skb->data, skb->len);
  13.686 - 		memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
  13.687 -@@ -1933,7 +1938,6 @@ static int velocity_xmit(struct sk_buff 
  13.688 - 		int nfrags = skb_shinfo(skb)->nr_frags;
  13.689 - 		tdinfo->skb = skb;
  13.690 - 		if (nfrags > 6) {
  13.691 --			skb_linearize(skb, GFP_ATOMIC);
  13.692 - 			memcpy(tdinfo->buf, skb->data, skb->len);
  13.693 - 			tdinfo->skb_dma[0] = tdinfo->buf_dma;
  13.694 - 			td_ptr->tdesc0.pktsize = 
  13.695 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/wireless/orinoco.c ./drivers/net/wireless/orinoco.c
  13.696 ---- ../orig-linux-2.6.16.29/drivers/net/wireless/orinoco.c	2006-09-12 19:02:10.000000000 +0100
  13.697 -+++ ./drivers/net/wireless/orinoco.c	2006-09-19 13:59:20.000000000 +0100
  13.698 -@@ -1835,7 +1835,9 @@ static int __orinoco_program_rids(struct
  13.699 - 	/* Set promiscuity / multicast*/
  13.700 - 	priv->promiscuous = 0;
  13.701 - 	priv->mc_count = 0;
  13.702 --	__orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */
  13.703 -+
  13.704 -+	/* FIXME: what about netif_tx_lock */
  13.705 -+	__orinoco_set_multicast_list(dev);
  13.706 - 
  13.707 - 	return 0;
  13.708 - }
  13.709 -diff -pruN ../orig-linux-2.6.16.29/drivers/s390/net/qeth_eddp.c ./drivers/s390/net/qeth_eddp.c
  13.710 ---- ../orig-linux-2.6.16.29/drivers/s390/net/qeth_eddp.c	2006-09-12 19:02:10.000000000 +0100
  13.711 -+++ ./drivers/s390/net/qeth_eddp.c	2006-09-19 13:59:20.000000000 +0100
  13.712 -@@ -421,7 +421,7 @@ __qeth_eddp_fill_context_tcp(struct qeth
  13.713 -        }
  13.714 - 	tcph = eddp->skb->h.th;
  13.715 - 	while (eddp->skb_offset < eddp->skb->len) {
  13.716 --		data_len = min((int)skb_shinfo(eddp->skb)->tso_size,
  13.717 -+		data_len = min((int)skb_shinfo(eddp->skb)->gso_size,
  13.718 - 			       (int)(eddp->skb->len - eddp->skb_offset));
  13.719 - 		/* prepare qdio hdr */
  13.720 - 		if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){
  13.721 -@@ -516,20 +516,20 @@ qeth_eddp_calc_num_pages(struct qeth_edd
  13.722 - 	
  13.723 - 	QETH_DBF_TEXT(trace, 5, "eddpcanp");
  13.724 - 	/* can we put multiple skbs in one page? */
  13.725 --	skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len);
  13.726 -+	skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len);
  13.727 - 	if (skbs_per_page > 1){
  13.728 --		ctx->num_pages = (skb_shinfo(skb)->tso_segs + 1) /
  13.729 -+		ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) /
  13.730 - 				 skbs_per_page + 1;
  13.731 - 		ctx->elements_per_skb = 1;
  13.732 - 	} else {
  13.733 - 		/* no -> how many elements per skb? */
  13.734 --		ctx->elements_per_skb = (skb_shinfo(skb)->tso_size + hdr_len +
  13.735 -+		ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len +
  13.736 - 				     PAGE_SIZE) >> PAGE_SHIFT;
  13.737 - 		ctx->num_pages = ctx->elements_per_skb *
  13.738 --				 (skb_shinfo(skb)->tso_segs + 1);
  13.739 -+				 (skb_shinfo(skb)->gso_segs + 1);
  13.740 - 	}
  13.741 - 	ctx->num_elements = ctx->elements_per_skb *
  13.742 --			    (skb_shinfo(skb)->tso_segs + 1);
  13.743 -+			    (skb_shinfo(skb)->gso_segs + 1);
  13.744 - }
  13.745 - 
  13.746 - static inline struct qeth_eddp_context *
  13.747 -diff -pruN ../orig-linux-2.6.16.29/drivers/s390/net/qeth_main.c ./drivers/s390/net/qeth_main.c
  13.748 ---- ../orig-linux-2.6.16.29/drivers/s390/net/qeth_main.c	2006-09-12 19:02:10.000000000 +0100
  13.749 -+++ ./drivers/s390/net/qeth_main.c	2006-09-19 13:59:20.000000000 +0100
  13.750 -@@ -4454,7 +4454,7 @@ qeth_send_packet(struct qeth_card *card,
  13.751 - 	queue = card->qdio.out_qs
  13.752 - 		[qeth_get_priority_queue(card, skb, ipv, cast_type)];
  13.753 - 
  13.754 --	if (skb_shinfo(skb)->tso_size)
  13.755 -+	if (skb_shinfo(skb)->gso_size)
  13.756 - 		large_send = card->options.large_send;
  13.757 - 
  13.758 - 	/*are we able to do TSO ? If so ,prepare and send it from here */
  13.759 -@@ -4501,7 +4501,7 @@ qeth_send_packet(struct qeth_card *card,
  13.760 - 		card->stats.tx_packets++;
  13.761 - 		card->stats.tx_bytes += skb->len;
  13.762 - #ifdef CONFIG_QETH_PERF_STATS
  13.763 --		if (skb_shinfo(skb)->tso_size &&
  13.764 -+		if (skb_shinfo(skb)->gso_size &&
  13.765 - 		   !(large_send == QETH_LARGE_SEND_NO)) {
  13.766 - 			card->perf_stats.large_send_bytes += skb->len;
  13.767 - 			card->perf_stats.large_send_cnt++;
  13.768 -diff -pruN ../orig-linux-2.6.16.29/drivers/s390/net/qeth_tso.h ./drivers/s390/net/qeth_tso.h
  13.769 ---- ../orig-linux-2.6.16.29/drivers/s390/net/qeth_tso.h	2006-09-12 19:02:10.000000000 +0100
  13.770 -+++ ./drivers/s390/net/qeth_tso.h	2006-09-19 13:59:20.000000000 +0100
  13.771 -@@ -51,7 +51,7 @@ qeth_tso_fill_header(struct qeth_card *c
  13.772 - 	hdr->ext.hdr_version = 1;
  13.773 - 	hdr->ext.hdr_len     = 28;
  13.774 - 	/*insert non-fix values */
  13.775 --	hdr->ext.mss = skb_shinfo(skb)->tso_size;
  13.776 -+	hdr->ext.mss = skb_shinfo(skb)->gso_size;
  13.777 - 	hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
  13.778 - 	hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
  13.779 - 				       sizeof(struct qeth_hdr_tso));
  13.780 -diff -pruN ../orig-linux-2.6.16.29/include/linux/ethtool.h ./include/linux/ethtool.h
  13.781 ---- ../orig-linux-2.6.16.29/include/linux/ethtool.h	2006-09-12 19:02:10.000000000 +0100
  13.782 -+++ ./include/linux/ethtool.h	2006-09-19 13:59:20.000000000 +0100
  13.783 -@@ -408,6 +408,8 @@ struct ethtool_ops {
  13.784 - #define ETHTOOL_GPERMADDR	0x00000020 /* Get permanent hardware address */
  13.785 - #define ETHTOOL_GUFO		0x00000021 /* Get UFO enable (ethtool_value) */
  13.786 - #define ETHTOOL_SUFO		0x00000022 /* Set UFO enable (ethtool_value) */
  13.787 -+#define ETHTOOL_GGSO		0x00000023 /* Get GSO enable (ethtool_value) */
  13.788 -+#define ETHTOOL_SGSO		0x00000024 /* Set GSO enable (ethtool_value) */
  13.789 - 
  13.790 - /* compatibility with older code */
  13.791 - #define SPARC_ETH_GSET		ETHTOOL_GSET
  13.792 -diff -pruN ../orig-linux-2.6.16.29/include/linux/netdevice.h ./include/linux/netdevice.h
  13.793 ---- ../orig-linux-2.6.16.29/include/linux/netdevice.h	2006-09-12 19:02:10.000000000 +0100
  13.794 -+++ ./include/linux/netdevice.h	2006-09-19 13:59:20.000000000 +0100
  13.795 -@@ -230,7 +230,8 @@ enum netdev_state_t
  13.796 - 	__LINK_STATE_SCHED,
  13.797 - 	__LINK_STATE_NOCARRIER,
  13.798 - 	__LINK_STATE_RX_SCHED,
  13.799 --	__LINK_STATE_LINKWATCH_PENDING
  13.800 -+	__LINK_STATE_LINKWATCH_PENDING,
  13.801 -+	__LINK_STATE_QDISC_RUNNING,
  13.802 - };
  13.803 - 
  13.804 - 
  13.805 -@@ -306,9 +307,17 @@ struct net_device
  13.806 - #define NETIF_F_HW_VLAN_RX	256	/* Receive VLAN hw acceleration */
  13.807 - #define NETIF_F_HW_VLAN_FILTER	512	/* Receive filtering on VLAN */
  13.808 - #define NETIF_F_VLAN_CHALLENGED	1024	/* Device cannot handle VLAN packets */
  13.809 --#define NETIF_F_TSO		2048	/* Can offload TCP/IP segmentation */
  13.810 -+#define NETIF_F_GSO		2048	/* Enable software GSO. */
  13.811 - #define NETIF_F_LLTX		4096	/* LockLess TX */
  13.812 --#define NETIF_F_UFO             8192    /* Can offload UDP Large Send*/
  13.813 -+
  13.814 -+	/* Segmentation offload features */
  13.815 -+#define NETIF_F_GSO_SHIFT	16
  13.816 -+#define NETIF_F_TSO		(SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
  13.817 -+#define NETIF_F_UFO		(SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT)
  13.818 -+#define NETIF_F_GSO_ROBUST	(SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
  13.819 -+
  13.820 -+#define NETIF_F_GEN_CSUM	(NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
  13.821 -+#define NETIF_F_ALL_CSUM	(NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM)
  13.822 - 
  13.823 - 	struct net_device	*next_sched;
  13.824 - 
  13.825 -@@ -394,6 +403,9 @@ struct net_device
  13.826 - 	struct list_head	qdisc_list;
  13.827 - 	unsigned long		tx_queue_len;	/* Max frames per queue allowed */
  13.828 - 
  13.829 -+	/* Partially transmitted GSO packet. */
  13.830 -+	struct sk_buff		*gso_skb;
  13.831 -+
  13.832 - 	/* ingress path synchronizer */
  13.833 - 	spinlock_t		ingress_lock;
  13.834 - 	struct Qdisc		*qdisc_ingress;
  13.835 -@@ -402,7 +414,7 @@ struct net_device
  13.836 -  * One part is mostly used on xmit path (device)
  13.837 -  */
  13.838 - 	/* hard_start_xmit synchronizer */
  13.839 --	spinlock_t		xmit_lock ____cacheline_aligned_in_smp;
  13.840 -+	spinlock_t		_xmit_lock ____cacheline_aligned_in_smp;
  13.841 - 	/* cpu id of processor entered to hard_start_xmit or -1,
  13.842 - 	   if nobody entered there.
  13.843 - 	 */
  13.844 -@@ -527,6 +539,8 @@ struct packet_type {
  13.845 - 					 struct net_device *,
  13.846 - 					 struct packet_type *,
  13.847 - 					 struct net_device *);
  13.848 -+	struct sk_buff		*(*gso_segment)(struct sk_buff *skb,
  13.849 -+						int features);
  13.850 - 	void			*af_packet_priv;
  13.851 - 	struct list_head	list;
  13.852 - };
  13.853 -@@ -693,7 +707,8 @@ extern int		dev_change_name(struct net_d
  13.854 - extern int		dev_set_mtu(struct net_device *, int);
  13.855 - extern int		dev_set_mac_address(struct net_device *,
  13.856 - 					    struct sockaddr *);
  13.857 --extern void		dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev);
  13.858 -+extern int		dev_hard_start_xmit(struct sk_buff *skb,
  13.859 -+					    struct net_device *dev);
  13.860 - 
  13.861 - extern void		dev_init(void);
  13.862 - 
  13.863 -@@ -900,11 +915,43 @@ static inline void __netif_rx_complete(s
  13.864 - 	clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
  13.865 - }
  13.866 - 
  13.867 -+static inline void netif_tx_lock(struct net_device *dev)
  13.868 -+{
  13.869 -+	spin_lock(&dev->_xmit_lock);
  13.870 -+	dev->xmit_lock_owner = smp_processor_id();
  13.871 -+}
  13.872 -+
  13.873 -+static inline void netif_tx_lock_bh(struct net_device *dev)
  13.874 -+{
  13.875 -+	spin_lock_bh(&dev->_xmit_lock);
  13.876 -+	dev->xmit_lock_owner = smp_processor_id();
  13.877 -+}
  13.878 -+
  13.879 -+static inline int netif_tx_trylock(struct net_device *dev)
  13.880 -+{
  13.881 -+	int err = spin_trylock(&dev->_xmit_lock);
  13.882 -+	if (!err)
  13.883 -+		dev->xmit_lock_owner = smp_processor_id();
  13.884 -+	return err;
  13.885 -+}
  13.886 -+
  13.887 -+static inline void netif_tx_unlock(struct net_device *dev)
  13.888 -+{
  13.889 -+	dev->xmit_lock_owner = -1;
  13.890 -+	spin_unlock(&dev->_xmit_lock);
  13.891 -+}
  13.892 -+
  13.893 -+static inline void netif_tx_unlock_bh(struct net_device *dev)
  13.894 -+{
  13.895 -+	dev->xmit_lock_owner = -1;
  13.896 -+	spin_unlock_bh(&dev->_xmit_lock);
  13.897 -+}
  13.898 -+
  13.899 - static inline void netif_tx_disable(struct net_device *dev)
  13.900 - {
  13.901 --	spin_lock_bh(&dev->xmit_lock);
  13.902 -+	netif_tx_lock_bh(dev);
  13.903 - 	netif_stop_queue(dev);
  13.904 --	spin_unlock_bh(&dev->xmit_lock);
  13.905 -+	netif_tx_unlock_bh(dev);
  13.906 - }
  13.907 - 
  13.908 - /* These functions live elsewhere (drivers/net/net_init.c, but related) */
  13.909 -@@ -932,6 +979,7 @@ extern int		netdev_max_backlog;
  13.910 - extern int		weight_p;
  13.911 - extern int		netdev_set_master(struct net_device *dev, struct net_device *master);
  13.912 - extern int skb_checksum_help(struct sk_buff *skb, int inward);
  13.913 -+extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features);
  13.914 - #ifdef CONFIG_BUG
  13.915 - extern void netdev_rx_csum_fault(struct net_device *dev);
  13.916 - #else
  13.917 -@@ -951,6 +999,18 @@ extern void dev_seq_stop(struct seq_file
  13.918 - 
  13.919 - extern void linkwatch_run_queue(void);
  13.920 - 
  13.921 -+static inline int skb_gso_ok(struct sk_buff *skb, int features)
  13.922 -+{
  13.923 -+	int feature = skb_shinfo(skb)->gso_size ?
  13.924 -+		      skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0;
  13.925 -+	return (features & feature) == feature;
  13.926 -+}
  13.927 -+
  13.928 -+static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
  13.929 -+{
  13.930 -+	return !skb_gso_ok(skb, dev->features);
  13.931 -+}
  13.932 -+
  13.933 - #endif /* __KERNEL__ */
  13.934 - 
  13.935 - #endif	/* _LINUX_DEV_H */
  13.936 -diff -pruN ../orig-linux-2.6.16.29/include/linux/skbuff.h ./include/linux/skbuff.h
  13.937 ---- ../orig-linux-2.6.16.29/include/linux/skbuff.h	2006-09-12 19:02:10.000000000 +0100
  13.938 -+++ ./include/linux/skbuff.h	2006-09-19 13:59:20.000000000 +0100
  13.939 -@@ -134,9 +134,10 @@ struct skb_frag_struct {
  13.940 - struct skb_shared_info {
  13.941 - 	atomic_t	dataref;
  13.942 - 	unsigned short	nr_frags;
  13.943 --	unsigned short	tso_size;
  13.944 --	unsigned short	tso_segs;
  13.945 --	unsigned short  ufo_size;
  13.946 -+	unsigned short	gso_size;
  13.947 -+	/* Warning: this field is not always filled in (UFO)! */
  13.948 -+	unsigned short	gso_segs;
  13.949 -+	unsigned short  gso_type;
  13.950 - 	unsigned int    ip6_frag_id;
  13.951 - 	struct sk_buff	*frag_list;
  13.952 - 	skb_frag_t	frags[MAX_SKB_FRAGS];
  13.953 -@@ -168,6 +169,14 @@ enum {
  13.954 - 	SKB_FCLONE_CLONE,
  13.955 - };
  13.956 - 
  13.957 -+enum {
  13.958 -+	SKB_GSO_TCPV4 = 1 << 0,
  13.959 -+	SKB_GSO_UDPV4 = 1 << 1,
  13.960 -+
  13.961 -+	/* This indicates the skb is from an untrusted source. */
  13.962 -+	SKB_GSO_DODGY = 1 << 2,
  13.963 -+};
  13.964 -+
  13.965 - /** 
  13.966 -  *	struct sk_buff - socket buffer
  13.967 -  *	@next: Next buffer in list
  13.968 -@@ -1148,18 +1157,34 @@ static inline int skb_can_coalesce(struc
  13.969 - 	return 0;
  13.970 - }
  13.971 - 
  13.972 -+static inline int __skb_linearize(struct sk_buff *skb)
  13.973 -+{
  13.974 -+	return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
  13.975 -+}
  13.976 -+
  13.977 - /**
  13.978 -  *	skb_linearize - convert paged skb to linear one
  13.979 -  *	@skb: buffer to linarize
  13.980 -- *	@gfp: allocation mode
  13.981 -  *
  13.982 -  *	If there is no free memory -ENOMEM is returned, otherwise zero
  13.983 -  *	is returned and the old skb data released.
  13.984 -  */
  13.985 --extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
  13.986 --static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
  13.987 -+static inline int skb_linearize(struct sk_buff *skb)
  13.988 -+{
  13.989 -+	return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;
  13.990 -+}
  13.991 -+
  13.992 -+/**
  13.993 -+ *	skb_linearize_cow - make sure skb is linear and writable
  13.994 -+ *	@skb: buffer to process
  13.995 -+ *
  13.996 -+ *	If there is no free memory -ENOMEM is returned, otherwise zero
  13.997 -+ *	is returned and the old skb data released.
  13.998 -+ */
  13.999 -+static inline int skb_linearize_cow(struct sk_buff *skb)
 13.1000 - {
 13.1001 --	return __skb_linearize(skb, gfp);
 13.1002 -+	return skb_is_nonlinear(skb) || skb_cloned(skb) ?
 13.1003 -+	       __skb_linearize(skb) : 0;
 13.1004 - }
 13.1005 - 
 13.1006 - /**
 13.1007 -@@ -1254,6 +1279,7 @@ extern void	       skb_split(struct sk_b
 13.1008 - 				 struct sk_buff *skb1, const u32 len);
 13.1009 - 
 13.1010 - extern void	       skb_release_data(struct sk_buff *skb);
 13.1011 -+extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
 13.1012 - 
 13.1013 - static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
 13.1014 - 				       int len, void *buffer)
 13.1015 -diff -pruN ../orig-linux-2.6.16.29/include/net/pkt_sched.h ./include/net/pkt_sched.h
 13.1016 ---- ../orig-linux-2.6.16.29/include/net/pkt_sched.h	2006-09-12 19:02:10.000000000 +0100
 13.1017 -+++ ./include/net/pkt_sched.h	2006-09-19 13:59:20.000000000 +0100
 13.1018 -@@ -218,12 +218,13 @@ extern struct qdisc_rate_table *qdisc_ge
 13.1019 - 		struct rtattr *tab);
 13.1020 - extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
 13.1021 - 
 13.1022 --extern int qdisc_restart(struct net_device *dev);
 13.1023 -+extern void __qdisc_run(struct net_device *dev);
 13.1024 - 
 13.1025 - static inline void qdisc_run(struct net_device *dev)
 13.1026 - {
 13.1027 --	while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0)
 13.1028 --		/* NOTHING */;
 13.1029 -+	if (!netif_queue_stopped(dev) &&
 13.1030 -+	    !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
 13.1031 -+		__qdisc_run(dev);
 13.1032 - }
 13.1033 - 
 13.1034 - extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
 13.1035 -diff -pruN ../orig-linux-2.6.16.29/include/net/protocol.h ./include/net/protocol.h
 13.1036 ---- ../orig-linux-2.6.16.29/include/net/protocol.h	2006-09-12 19:02:10.000000000 +0100
 13.1037 -+++ ./include/net/protocol.h	2006-09-19 13:59:20.000000000 +0100
 13.1038 -@@ -37,6 +37,8 @@
 13.1039 - struct net_protocol {
 13.1040 - 	int			(*handler)(struct sk_buff *skb);
 13.1041 - 	void			(*err_handler)(struct sk_buff *skb, u32 info);
 13.1042 -+	struct sk_buff	       *(*gso_segment)(struct sk_buff *skb,
 13.1043 -+					       int features);
 13.1044 - 	int			no_policy;
 13.1045 - };
 13.1046 - 
 13.1047 -diff -pruN ../orig-linux-2.6.16.29/include/net/sock.h ./include/net/sock.h
 13.1048 ---- ../orig-linux-2.6.16.29/include/net/sock.h	2006-09-12 19:02:10.000000000 +0100
 13.1049 -+++ ./include/net/sock.h	2006-09-19 13:59:20.000000000 +0100
 13.1050 -@@ -1064,9 +1064,13 @@ static inline void sk_setup_caps(struct 
 13.1051 - {
 13.1052 - 	__sk_dst_set(sk, dst);
 13.1053 - 	sk->sk_route_caps = dst->dev->features;
 13.1054 -+	if (sk->sk_route_caps & NETIF_F_GSO)
 13.1055 -+		sk->sk_route_caps |= NETIF_F_TSO;
 13.1056 - 	if (sk->sk_route_caps & NETIF_F_TSO) {
 13.1057 - 		if (sock_flag(sk, SOCK_NO_LARGESEND) || dst->header_len)
 13.1058 - 			sk->sk_route_caps &= ~NETIF_F_TSO;
 13.1059 -+		else 
 13.1060 -+			sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
 13.1061 - 	}
 13.1062 - }
 13.1063 - 
 13.1064 -diff -pruN ../orig-linux-2.6.16.29/include/net/tcp.h ./include/net/tcp.h
 13.1065 ---- ../orig-linux-2.6.16.29/include/net/tcp.h	2006-09-12 19:02:10.000000000 +0100
 13.1066 -+++ ./include/net/tcp.h	2006-09-19 13:59:20.000000000 +0100
 13.1067 -@@ -552,13 +552,13 @@ struct tcp_skb_cb {
 13.1068 -  */
 13.1069 - static inline int tcp_skb_pcount(const struct sk_buff *skb)
 13.1070 - {
 13.1071 --	return skb_shinfo(skb)->tso_segs;
 13.1072 -+	return skb_shinfo(skb)->gso_segs;
 13.1073 - }
 13.1074 - 
 13.1075 - /* This is valid iff tcp_skb_pcount() > 1. */
 13.1076 - static inline int tcp_skb_mss(const struct sk_buff *skb)
 13.1077 - {
 13.1078 --	return skb_shinfo(skb)->tso_size;
 13.1079 -+	return skb_shinfo(skb)->gso_size;
 13.1080 - }
 13.1081 - 
 13.1082 - static inline void tcp_dec_pcount_approx(__u32 *count,
 13.1083 -@@ -1063,6 +1063,8 @@ extern struct request_sock_ops tcp_reque
 13.1084 - 
 13.1085 - extern int tcp_v4_destroy_sock(struct sock *sk);
 13.1086 - 
 13.1087 -+extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features);
 13.1088 -+
 13.1089 - #ifdef CONFIG_PROC_FS
 13.1090 - extern int  tcp4_proc_init(void);
 13.1091 - extern void tcp4_proc_exit(void);
 13.1092 -diff -pruN ../orig-linux-2.6.16.29/net/atm/clip.c ./net/atm/clip.c
 13.1093 ---- ../orig-linux-2.6.16.29/net/atm/clip.c	2006-09-12 19:02:10.000000000 +0100
 13.1094 -+++ ./net/atm/clip.c	2006-09-19 13:59:20.000000000 +0100
 13.1095 -@@ -101,7 +101,7 @@ static void unlink_clip_vcc(struct clip_
 13.1096 - 		printk(KERN_CRIT "!clip_vcc->entry (clip_vcc %p)\n",clip_vcc);
 13.1097 - 		return;
 13.1098 - 	}
 13.1099 --	spin_lock_bh(&entry->neigh->dev->xmit_lock);	/* block clip_start_xmit() */
 13.1100 -+	netif_tx_lock_bh(entry->neigh->dev);	/* block clip_start_xmit() */
 13.1101 - 	entry->neigh->used = jiffies;
 13.1102 - 	for (walk = &entry->vccs; *walk; walk = &(*walk)->next)
 13.1103 - 		if (*walk == clip_vcc) {
 13.1104 -@@ -125,7 +125,7 @@ static void unlink_clip_vcc(struct clip_
 13.1105 - 	printk(KERN_CRIT "ATMARP: unlink_clip_vcc failed (entry %p, vcc "
 13.1106 - 	  "0x%p)\n",entry,clip_vcc);
 13.1107 - out:
 13.1108 --	spin_unlock_bh(&entry->neigh->dev->xmit_lock);
 13.1109 -+	netif_tx_unlock_bh(entry->neigh->dev);
 13.1110 - }
 13.1111 - 
 13.1112 - /* The neighbour entry n->lock is held. */
 13.1113 -diff -pruN ../orig-linux-2.6.16.29/net/bridge/br_device.c ./net/bridge/br_device.c
 13.1114 ---- ../orig-linux-2.6.16.29/net/bridge/br_device.c	2006-09-12 19:02:10.000000000 +0100
 13.1115 -+++ ./net/bridge/br_device.c	2006-09-19 13:59:20.000000000 +0100
 13.1116 -@@ -146,9 +146,9 @@ static int br_set_tx_csum(struct net_dev
 13.1117 - 	struct net_bridge *br = netdev_priv(dev);
 13.1118 - 
 13.1119 - 	if (data)
 13.1120 --		br->feature_mask |= NETIF_F_IP_CSUM;
 13.1121 -+		br->feature_mask |= NETIF_F_NO_CSUM;
 13.1122 - 	else
 13.1123 --		br->feature_mask &= ~NETIF_F_IP_CSUM;
 13.1124 -+		br->feature_mask &= ~NETIF_F_ALL_CSUM;
 13.1125 - 
 13.1126 - 	br_features_recompute(br);
 13.1127 - 	return 0;
 13.1128 -@@ -185,6 +185,6 @@ void br_dev_setup(struct net_device *dev
 13.1129 - 	dev->set_mac_address = br_set_mac_address;
 13.1130 - 	dev->priv_flags = IFF_EBRIDGE;
 13.1131 - 
 13.1132 -- 	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
 13.1133 -- 		| NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM;
 13.1134 -+ 	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
 13.1135 -+ 			NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST;
 13.1136 - }
 13.1137 -diff -pruN ../orig-linux-2.6.16.29/net/bridge/br_forward.c ./net/bridge/br_forward.c
 13.1138 ---- ../orig-linux-2.6.16.29/net/bridge/br_forward.c	2006-09-12 19:02:10.000000000 +0100
 13.1139 -+++ ./net/bridge/br_forward.c	2006-09-19 13:59:20.000000000 +0100
 13.1140 -@@ -32,7 +32,7 @@ static inline int should_deliver(const s
 13.1141 - int br_dev_queue_push_xmit(struct sk_buff *skb)
 13.1142 - {
 13.1143 - 	/* drop mtu oversized packets except tso */
 13.1144 --	if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->tso_size)
 13.1145 -+	if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->gso_size)
 13.1146 - 		kfree_skb(skb);
 13.1147 - 	else {
 13.1148 - #ifdef CONFIG_BRIDGE_NETFILTER
 13.1149 -diff -pruN ../orig-linux-2.6.16.29/net/bridge/br_if.c ./net/bridge/br_if.c
 13.1150 ---- ../orig-linux-2.6.16.29/net/bridge/br_if.c	2006-09-12 19:02:10.000000000 +0100
 13.1151 -+++ ./net/bridge/br_if.c	2006-09-19 13:59:20.000000000 +0100
 13.1152 -@@ -385,17 +385,28 @@ void br_features_recompute(struct net_br
 13.1153 - 	struct net_bridge_port *p;
 13.1154 - 	unsigned long features, checksum;
 13.1155 - 
 13.1156 --	features = br->feature_mask &~ NETIF_F_IP_CSUM;
 13.1157 --	checksum = br->feature_mask & NETIF_F_IP_CSUM;
 13.1158 -+	checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0;
 13.1159 -+	features = br->feature_mask & ~NETIF_F_ALL_CSUM;
 13.1160 - 
 13.1161 - 	list_for_each_entry(p, &br->port_list, list) {
 13.1162 --		if (!(p->dev->features 
 13.1163 --		      & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)))
 13.1164 -+		unsigned long feature = p->dev->features;
 13.1165 -+
 13.1166 -+		if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
 13.1167 -+			checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
 13.1168 -+		if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
 13.1169 -+			checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM;
 13.1170 -+		if (!(feature & NETIF_F_IP_CSUM))
 13.1171 - 			checksum = 0;
 13.1172 --		features &= p->dev->features;
 13.1173 -+
 13.1174 -+		if (feature & NETIF_F_GSO)
 13.1175 -+			feature |= NETIF_F_TSO;
 13.1176 -+		feature |= NETIF_F_GSO;
 13.1177 -+
 13.1178 -+		features &= feature;
 13.1179 - 	}
 13.1180 - 
 13.1181 --	br->dev->features = features | checksum | NETIF_F_LLTX;
 13.1182 -+	br->dev->features = features | checksum | NETIF_F_LLTX |
 13.1183 -+			    NETIF_F_GSO_ROBUST;
 13.1184 - }
 13.1185 - 
 13.1186 - /* called with RTNL */
 13.1187 -diff -pruN ../orig-linux-2.6.16.29/net/bridge/br_netfilter.c ./net/bridge/br_netfilter.c
 13.1188 ---- ../orig-linux-2.6.16.29/net/bridge/br_netfilter.c	2006-09-12 19:02:10.000000000 +0100
 13.1189 -+++ ./net/bridge/br_netfilter.c	2006-09-19 13:59:20.000000000 +0100
 13.1190 -@@ -743,7 +743,7 @@ static int br_nf_dev_queue_xmit(struct s
 13.1191 - {
 13.1192 - 	if (skb->protocol == htons(ETH_P_IP) &&
 13.1193 - 	    skb->len > skb->dev->mtu &&
 13.1194 --	    !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
 13.1195 -+	    !skb_shinfo(skb)->gso_size)
 13.1196 - 		return ip_fragment(skb, br_dev_queue_push_xmit);
 13.1197 - 	else
 13.1198 - 		return br_dev_queue_push_xmit(skb);
 13.1199 -diff -pruN ../orig-linux-2.6.16.29/net/core/dev.c ./net/core/dev.c
 13.1200 ---- ../orig-linux-2.6.16.29/net/core/dev.c	2006-09-12 19:02:10.000000000 +0100
 13.1201 -+++ ./net/core/dev.c	2006-09-19 13:59:20.000000000 +0100
 13.1202 -@@ -115,6 +115,7 @@
 13.1203 - #include <net/iw_handler.h>
 13.1204 - #endif	/* CONFIG_NET_RADIO */
 13.1205 - #include <asm/current.h>
 13.1206 -+#include <linux/err.h>
 13.1207 - 
 13.1208 - /*
 13.1209 -  *	The list of packet types we will receive (as opposed to discard)
 13.1210 -@@ -1032,7 +1033,7 @@ static inline void net_timestamp(struct 
 13.1211 -  *	taps currently in use.
 13.1212 -  */
 13.1213 - 
 13.1214 --void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 13.1215 -+static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 13.1216 - {
 13.1217 - 	struct packet_type *ptype;
 13.1218 - 
 13.1219 -@@ -1106,6 +1107,45 @@ out:	
 13.1220 - 	return ret;
 13.1221 - }
 13.1222 - 
 13.1223 -+/**
 13.1224 -+ *	skb_gso_segment - Perform segmentation on skb.
 13.1225 -+ *	@skb: buffer to segment
 13.1226 -+ *	@features: features for the output path (see dev->features)
 13.1227 -+ *
 13.1228 -+ *	This function segments the given skb and returns a list of segments.
 13.1229 -+ *
 13.1230 -+ *	It may return NULL if the skb requires no segmentation.  This is
 13.1231 -+ *	only possible when GSO is used for verifying header integrity.
 13.1232 -+ */
 13.1233 -+struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
 13.1234 -+{
 13.1235 -+	struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
 13.1236 -+	struct packet_type *ptype;
 13.1237 -+	int type = skb->protocol;
 13.1238 -+
 13.1239 -+	BUG_ON(skb_shinfo(skb)->frag_list);
 13.1240 -+	BUG_ON(skb->ip_summed != CHECKSUM_HW);
 13.1241 -+
 13.1242 -+	skb->mac.raw = skb->data;
 13.1243 -+	skb->mac_len = skb->nh.raw - skb->data;
 13.1244 -+	__skb_pull(skb, skb->mac_len);
 13.1245 -+
 13.1246 -+	rcu_read_lock();
 13.1247 -+	list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
 13.1248 -+		if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
 13.1249 -+			segs = ptype->gso_segment(skb, features);
 13.1250 -+			break;
 13.1251 -+		}
 13.1252 -+	}
 13.1253 -+	rcu_read_unlock();
 13.1254 -+
 13.1255 -+	__skb_push(skb, skb->data - skb->mac.raw);
 13.1256 -+
 13.1257 -+	return segs;
 13.1258 -+}
 13.1259 -+
 13.1260 -+EXPORT_SYMBOL(skb_gso_segment);
 13.1261 -+
 13.1262 - /* Take action when hardware reception checksum errors are detected. */
 13.1263 - #ifdef CONFIG_BUG
 13.1264 - void netdev_rx_csum_fault(struct net_device *dev)
 13.1265 -@@ -1142,75 +1182,108 @@ static inline int illegal_highdma(struct
 13.1266 - #define illegal_highdma(dev, skb)	(0)
 13.1267 - #endif
 13.1268 - 
 13.1269 --/* Keep head the same: replace data */
 13.1270 --int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
 13.1271 -+struct dev_gso_cb {
 13.1272 -+	void (*destructor)(struct sk_buff *skb);
 13.1273 -+};
 13.1274 -+
 13.1275 -+#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
 13.1276 -+
 13.1277 -+static void dev_gso_skb_destructor(struct sk_buff *skb)
 13.1278 -+{
 13.1279 -+	struct dev_gso_cb *cb;
 13.1280 -+
 13.1281 -+	do {
 13.1282 -+		struct sk_buff *nskb = skb->next;
 13.1283 -+
 13.1284 -+		skb->next = nskb->next;
 13.1285 -+		nskb->next = NULL;
 13.1286 -+		kfree_skb(nskb);
 13.1287 -+	} while (skb->next);
 13.1288 -+
 13.1289 -+	cb = DEV_GSO_CB(skb);
 13.1290 -+	if (cb->destructor)
 13.1291 -+		cb->destructor(skb);
 13.1292 -+}
 13.1293 -+
 13.1294 -+/**
 13.1295 -+ *	dev_gso_segment - Perform emulated hardware segmentation on skb.
 13.1296 -+ *	@skb: buffer to segment
 13.1297 -+ *
 13.1298 -+ *	This function segments the given skb and stores the list of segments
 13.1299 -+ *	in skb->next.
 13.1300 -+ */
 13.1301 -+static int dev_gso_segment(struct sk_buff *skb)
 13.1302 - {
 13.1303 --	unsigned int size;
 13.1304 --	u8 *data;
 13.1305 --	long offset;
 13.1306 --	struct skb_shared_info *ninfo;
 13.1307 --	int headerlen = skb->data - skb->head;
 13.1308 --	int expand = (skb->tail + skb->data_len) - skb->end;
 13.1309 --
 13.1310 --	if (skb_shared(skb))
 13.1311 --		BUG();
 13.1312 --
 13.1313 --	if (expand <= 0)
 13.1314 --		expand = 0;
 13.1315 --
 13.1316 --	size = skb->end - skb->head + expand;
 13.1317 --	size = SKB_DATA_ALIGN(size);
 13.1318 --	data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
 13.1319 --	if (!data)
 13.1320 --		return -ENOMEM;
 13.1321 --
 13.1322 --	/* Copy entire thing */
 13.1323 --	if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
 13.1324 --		BUG();
 13.1325 --
 13.1326 --	/* Set up shinfo */
 13.1327 --	ninfo = (struct skb_shared_info*)(data + size);
 13.1328 --	atomic_set(&ninfo->dataref, 1);
 13.1329 --	ninfo->tso_size = skb_shinfo(skb)->tso_size;
 13.1330 --	ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
 13.1331 --	ninfo->nr_frags = 0;
 13.1332 --	ninfo->frag_list = NULL;
 13.1333 --
 13.1334 --	/* Offset between the two in bytes */
 13.1335 --	offset = data - skb->head;
 13.1336 --
 13.1337 --	/* Free old data. */
 13.1338 --	skb_release_data(skb);
 13.1339 --
 13.1340 --	skb->head = data;
 13.1341 --	skb->end  = data + size;
 13.1342 --
 13.1343 --	/* Set up new pointers */
 13.1344 --	skb->h.raw   += offset;
 13.1345 --	skb->nh.raw  += offset;
 13.1346 --	skb->mac.raw += offset;
 13.1347 --	skb->tail    += offset;
 13.1348 --	skb->data    += offset;
 13.1349 -+	struct net_device *dev = skb->dev;
 13.1350 -+	struct sk_buff *segs;
 13.1351 -+	int features = dev->features & ~(illegal_highdma(dev, skb) ?
 13.1352 -+					 NETIF_F_SG : 0);
 13.1353 -+
 13.1354 -+	segs = skb_gso_segment(skb, features);
 13.1355 -+
 13.1356 -+	/* Verifying header integrity only. */
 13.1357 -+	if (!segs)
 13.1358 -+		return 0;
 13.1359 - 
 13.1360 --	/* We are no longer a clone, even if we were. */
 13.1361 --	skb->cloned    = 0;
 13.1362 -+	if (unlikely(IS_ERR(segs)))
 13.1363 -+		return PTR_ERR(segs);
 13.1364 -+
 13.1365 -+	skb->next = segs;
 13.1366 -+	DEV_GSO_CB(skb)->destructor = skb->destructor;
 13.1367 -+	skb->destructor = dev_gso_skb_destructor;
 13.1368 - 
 13.1369 --	skb->tail     += skb->data_len;
 13.1370 --	skb->data_len  = 0;
 13.1371 -+	return 0;
 13.1372 -+}
 13.1373 -+
 13.1374 -+int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 13.1375 -+{
 13.1376 -+	if (likely(!skb->next)) {
 13.1377 -+		if (netdev_nit)
 13.1378 -+			dev_queue_xmit_nit(skb, dev);
 13.1379 -+
 13.1380 -+		if (netif_needs_gso(dev, skb)) {
 13.1381 -+			if (unlikely(dev_gso_segment(skb)))
 13.1382 -+				goto out_kfree_skb;
 13.1383 -+			if (skb->next)
 13.1384 -+				goto gso;
 13.1385 -+		}
 13.1386 -+
 13.1387 -+		return dev->hard_start_xmit(skb, dev);
 13.1388 -+	}
 13.1389 -+
 13.1390 -+gso:
 13.1391 -+	do {
 13.1392 -+		struct sk_buff *nskb = skb->next;
 13.1393 -+		int rc;
 13.1394 -+
 13.1395 -+		skb->next = nskb->next;
 13.1396 -+		nskb->next = NULL;
 13.1397 -+		rc = dev->hard_start_xmit(nskb, dev);
 13.1398 -+		if (unlikely(rc)) {
 13.1399 -+			nskb->next = skb->next;
 13.1400 -+			skb->next = nskb;
 13.1401 -+			return rc;
 13.1402 -+		}
 13.1403 -+		if (unlikely(netif_queue_stopped(dev) && skb->next))
 13.1404 -+			return NETDEV_TX_BUSY;
 13.1405 -+	} while (skb->next);
 13.1406 -+	
 13.1407 -+	skb->destructor = DEV_GSO_CB(skb)->destructor;
 13.1408 -+
 13.1409 -+out_kfree_skb:
 13.1410 -+	kfree_skb(skb);
 13.1411 - 	return 0;
 13.1412 - }
 13.1413 - 
 13.1414 - #define HARD_TX_LOCK(dev, cpu) {			\
 13.1415 - 	if ((dev->features & NETIF_F_LLTX) == 0) {	\
 13.1416 --		spin_lock(&dev->xmit_lock);		\
 13.1417 --		dev->xmit_lock_owner = cpu;		\
 13.1418 -+		netif_tx_lock(dev);			\
 13.1419 - 	}						\
 13.1420 - }
 13.1421 - 
 13.1422 - #define HARD_TX_UNLOCK(dev) {				\
 13.1423 - 	if ((dev->features & NETIF_F_LLTX) == 0) {	\
 13.1424 --		dev->xmit_lock_owner = -1;		\
 13.1425 --		spin_unlock(&dev->xmit_lock);		\
 13.1426 -+		netif_tx_unlock(dev);			\
 13.1427 - 	}						\
 13.1428 - }
 13.1429 - 
 13.1430 -@@ -1246,9 +1319,13 @@ int dev_queue_xmit(struct sk_buff *skb)
 13.1431 - 	struct Qdisc *q;
 13.1432 - 	int rc = -ENOMEM;
 13.1433 - 
 13.1434 -+	/* GSO will handle the following emulations directly. */
 13.1435 -+	if (netif_needs_gso(dev, skb))
 13.1436 -+		goto gso;
 13.1437 -+
 13.1438 - 	if (skb_shinfo(skb)->frag_list &&
 13.1439 - 	    !(dev->features & NETIF_F_FRAGLIST) &&
 13.1440 --	    __skb_linearize(skb, GFP_ATOMIC))
 13.1441 -+	    __skb_linearize(skb))
 13.1442 - 		goto out_kfree_skb;
 13.1443 - 
 13.1444 - 	/* Fragmented skb is linearized if device does not support SG,
 13.1445 -@@ -1257,25 +1334,26 @@ int dev_queue_xmit(struct sk_buff *skb)
 13.1446 - 	 */
 13.1447 - 	if (skb_shinfo(skb)->nr_frags &&
 13.1448 - 	    (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
 13.1449 --	    __skb_linearize(skb, GFP_ATOMIC))
 13.1450 -+	    __skb_linearize(skb))
 13.1451 - 		goto out_kfree_skb;
 13.1452 - 
 13.1453 - 	/* If packet is not checksummed and device does not support
 13.1454 - 	 * checksumming for this protocol, complete checksumming here.
 13.1455 - 	 */
 13.1456 - 	if (skb->ip_summed == CHECKSUM_HW &&
 13.1457 --	    (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
 13.1458 -+	    (!(dev->features & NETIF_F_GEN_CSUM) &&
 13.1459 - 	     (!(dev->features & NETIF_F_IP_CSUM) ||
 13.1460 - 	      skb->protocol != htons(ETH_P_IP))))
 13.1461 - 	      	if (skb_checksum_help(skb, 0))
 13.1462 - 	      		goto out_kfree_skb;
 13.1463 - 
 13.1464 -+gso:
 13.1465 - 	spin_lock_prefetch(&dev->queue_lock);
 13.1466 - 
 13.1467 - 	/* Disable soft irqs for various locks below. Also 
 13.1468 - 	 * stops preemption for RCU. 
 13.1469 - 	 */
 13.1470 --	local_bh_disable(); 
 13.1471 -+	rcu_read_lock_bh(); 
 13.1472 - 
 13.1473 - 	/* Updates of qdisc are serialized by queue_lock. 
 13.1474 - 	 * The struct Qdisc which is pointed to by qdisc is now a 
 13.1475 -@@ -1309,8 +1387,8 @@ int dev_queue_xmit(struct sk_buff *skb)
 13.1476 - 	/* The device has no queue. Common case for software devices:
 13.1477 - 	   loopback, all the sorts of tunnels...
 13.1478 - 
 13.1479 --	   Really, it is unlikely that xmit_lock protection is necessary here.
 13.1480 --	   (f.e. loopback and IP tunnels are clean ignoring statistics
 13.1481 -+	   Really, it is unlikely that netif_tx_lock protection is necessary
 13.1482 -+	   here.  (f.e. loopback and IP tunnels are clean ignoring statistics
 13.1483 - 	   counters.)
 13.1484 - 	   However, it is possible, that they rely on protection
 13.1485 - 	   made by us here.
 13.1486 -@@ -1326,11 +1404,8 @@ int dev_queue_xmit(struct sk_buff *skb)
 13.1487 - 			HARD_TX_LOCK(dev, cpu);
 13.1488 - 
 13.1489 - 			if (!netif_queue_stopped(dev)) {
 13.1490 --				if (netdev_nit)
 13.1491 --					dev_queue_xmit_nit(skb, dev);
 13.1492 --
 13.1493 - 				rc = 0;
 13.1494 --				if (!dev->hard_start_xmit(skb, dev)) {
 13.1495 -+				if (!dev_hard_start_xmit(skb, dev)) {
 13.1496 - 					HARD_TX_UNLOCK(dev);
 13.1497 - 					goto out;
 13.1498 - 				}
 13.1499 -@@ -1349,13 +1424,13 @@ int dev_queue_xmit(struct sk_buff *skb)
 13.1500 - 	}
 13.1501 - 
 13.1502 - 	rc = -ENETDOWN;
 13.1503 --	local_bh_enable();
 13.1504 -+	rcu_read_unlock_bh();
 13.1505 - 
 13.1506 - out_kfree_skb:
 13.1507 - 	kfree_skb(skb);
 13.1508 - 	return rc;
 13.1509 - out:
 13.1510 --	local_bh_enable();
 13.1511 -+	rcu_read_unlock_bh();
 13.1512 - 	return rc;
 13.1513 - }
 13.1514 - 
 13.1515 -@@ -2670,7 +2745,7 @@ int register_netdevice(struct net_device
 13.1516 - 	BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
 13.1517 - 
 13.1518 - 	spin_lock_init(&dev->queue_lock);
 13.1519 --	spin_lock_init(&dev->xmit_lock);
 13.1520 -+	spin_lock_init(&dev->_xmit_lock);
 13.1521 - 	dev->xmit_lock_owner = -1;
 13.1522 - #ifdef CONFIG_NET_CLS_ACT
 13.1523 - 	spin_lock_init(&dev->ingress_lock);
 13.1524 -@@ -2714,9 +2789,7 @@ int register_netdevice(struct net_device
 13.1525 - 
 13.1526 - 	/* Fix illegal SG+CSUM combinations. */
 13.1527 - 	if ((dev->features & NETIF_F_SG) &&
 13.1528 --	    !(dev->features & (NETIF_F_IP_CSUM |
 13.1529 --			       NETIF_F_NO_CSUM |
 13.1530 --			       NETIF_F_HW_CSUM))) {
 13.1531 -+	    !(dev->features & NETIF_F_ALL_CSUM)) {
 13.1532 - 		printk("%s: Dropping NETIF_F_SG since no checksum feature.\n",
 13.1533 - 		       dev->name);
 13.1534 - 		dev->features &= ~NETIF_F_SG;
 13.1535 -@@ -3268,7 +3341,6 @@ subsys_initcall(net_dev_init);
 13.1536 - EXPORT_SYMBOL(__dev_get_by_index);
 13.1537 - EXPORT_SYMBOL(__dev_get_by_name);
 13.1538 - EXPORT_SYMBOL(__dev_remove_pack);
 13.1539 --EXPORT_SYMBOL(__skb_linearize);
 13.1540 - EXPORT_SYMBOL(dev_valid_name);
 13.1541 - EXPORT_SYMBOL(dev_add_pack);
 13.1542 - EXPORT_SYMBOL(dev_alloc_name);
 13.1543 -diff -pruN ../orig-linux-2.6.16.29/net/core/dev_mcast.c ./net/core/dev_mcast.c
 13.1544 ---- ../orig-linux-2.6.16.29/net/core/dev_mcast.c	2006-09-12 19:02:10.000000000 +0100
 13.1545 -+++ ./net/core/dev_mcast.c	2006-09-19 13:59:20.000000000 +0100
 13.1546 -@@ -62,7 +62,7 @@
 13.1547 -  *	Device mc lists are changed by bh at least if IPv6 is enabled,
 13.1548 -  *	so that it must be bh protected.
 13.1549 -  *
 13.1550 -- *	We block accesses to device mc filters with dev->xmit_lock.
 13.1551 -+ *	We block accesses to device mc filters with netif_tx_lock.
 13.1552 -  */
 13.1553 - 
 13.1554 - /*
 13.1555 -@@ -93,9 +93,9 @@ static void __dev_mc_upload(struct net_d
 13.1556 - 
 13.1557 - void dev_mc_upload(struct net_device *dev)
 13.1558 - {
 13.1559 --	spin_lock_bh(&dev->xmit_lock);
 13.1560 -+	netif_tx_lock_bh(dev);
 13.1561 - 	__dev_mc_upload(dev);
 13.1562 --	spin_unlock_bh(&dev->xmit_lock);
 13.1563 -+	netif_tx_unlock_bh(dev);
 13.1564 - }
 13.1565 - 
 13.1566 - /*
 13.1567 -@@ -107,7 +107,7 @@ int dev_mc_delete(struct net_device *dev
 13.1568 - 	int err = 0;
 13.1569 - 	struct dev_mc_list *dmi, **dmip;
 13.1570 - 
 13.1571 --	spin_lock_bh(&dev->xmit_lock);
 13.1572 -+	netif_tx_lock_bh(dev);
 13.1573 - 
 13.1574 - 	for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) {
 13.1575 - 		/*
 13.1576 -@@ -139,13 +139,13 @@ int dev_mc_delete(struct net_device *dev
 13.1577 - 			 */
 13.1578 - 			__dev_mc_upload(dev);
 13.1579 - 			
 13.1580 --			spin_unlock_bh(&dev->xmit_lock);
 13.1581 -+			netif_tx_unlock_bh(dev);
 13.1582 - 			return 0;
 13.1583 - 		}
 13.1584 - 	}
 13.1585 - 	err = -ENOENT;
 13.1586 - done:
 13.1587 --	spin_unlock_bh(&dev->xmit_lock);
 13.1588 -+	netif_tx_unlock_bh(dev);
 13.1589 - 	return err;
 13.1590 - }
 13.1591 - 
 13.1592 -@@ -160,7 +160,7 @@ int dev_mc_add(struct net_device *dev, v
 13.1593 - 
 13.1594 - 	dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC);
 13.1595 - 
 13.1596 --	spin_lock_bh(&dev->xmit_lock);
 13.1597 -+	netif_tx_lock_bh(dev);
 13.1598 - 	for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) {
 13.1599 - 		if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
 13.1600 - 		    dmi->dmi_addrlen == alen) {
 13.1601 -@@ -176,7 +176,7 @@ int dev_mc_add(struct net_device *dev, v
 13.1602 - 	}
 13.1603 - 
 13.1604 - 	if ((dmi = dmi1) == NULL) {
 13.1605 --		spin_unlock_bh(&dev->xmit_lock);
 13.1606 -+		netif_tx_unlock_bh(dev);
 13.1607 - 		return -ENOMEM;
 13.1608 - 	}
 13.1609 - 	memcpy(dmi->dmi_addr, addr, alen);
 13.1610 -@@ -189,11 +189,11 @@ int dev_mc_add(struct net_device *dev, v
 13.1611 - 
 13.1612 - 	__dev_mc_upload(dev);
 13.1613 - 	
 13.1614 --	spin_unlock_bh(&dev->xmit_lock);
 13.1615 -+	netif_tx_unlock_bh(dev);
 13.1616 - 	return 0;
 13.1617 - 
 13.1618 - done:
 13.1619 --	spin_unlock_bh(&dev->xmit_lock);
 13.1620 -+	netif_tx_unlock_bh(dev);
 13.1621 - 	kfree(dmi1);
 13.1622 - 	return err;
 13.1623 - }
 13.1624 -@@ -204,7 +204,7 @@ done:
 13.1625 - 
 13.1626 - void dev_mc_discard(struct net_device *dev)
 13.1627 - {
 13.1628 --	spin_lock_bh(&dev->xmit_lock);
 13.1629 -+	netif_tx_lock_bh(dev);
 13.1630 - 	
 13.1631 - 	while (dev->mc_list != NULL) {
 13.1632 - 		struct dev_mc_list *tmp = dev->mc_list;
 13.1633 -@@ -215,7 +215,7 @@ void dev_mc_discard(struct net_device *d
 13.1634 - 	}
 13.1635 - 	dev->mc_count = 0;
 13.1636 - 
 13.1637 --	spin_unlock_bh(&dev->xmit_lock);
 13.1638 -+	netif_tx_unlock_bh(dev);
 13.1639 - }
 13.1640 - 
 13.1641 - #ifdef CONFIG_PROC_FS
 13.1642 -@@ -250,7 +250,7 @@ static int dev_mc_seq_show(struct seq_fi
 13.1643 - 	struct dev_mc_list *m;
 13.1644 - 	struct net_device *dev = v;
 13.1645 - 
 13.1646 --	spin_lock_bh(&dev->xmit_lock);
 13.1647 -+	netif_tx_lock_bh(dev);
 13.1648 - 	for (m = dev->mc_list; m; m = m->next) {
 13.1649 - 		int i;
 13.1650 - 
 13.1651 -@@ -262,7 +262,7 @@ static int dev_mc_seq_show(struct seq_fi
 13.1652 - 
 13.1653 - 		seq_putc(seq, '\n');
 13.1654 - 	}
 13.1655 --	spin_unlock_bh(&dev->xmit_lock);
 13.1656 -+	netif_tx_unlock_bh(dev);
 13.1657 - 	return 0;
 13.1658 - }
 13.1659 - 
 13.1660 -diff -pruN ../orig-linux-2.6.16.29/net/core/ethtool.c ./net/core/ethtool.c
 13.1661 ---- ../orig-linux-2.6.16.29/net/core/ethtool.c	2006-09-12 19:02:10.000000000 +0100
 13.1662 -+++ ./net/core/ethtool.c	2006-09-19 13:59:20.000000000 +0100
 13.1663 -@@ -30,7 +30,7 @@ u32 ethtool_op_get_link(struct net_devic
 13.1664 - 
 13.1665 - u32 ethtool_op_get_tx_csum(struct net_device *dev)
 13.1666 - {
 13.1667 --	return (dev->features & (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM)) != 0;
 13.1668 -+	return (dev->features & NETIF_F_ALL_CSUM) != 0;
 13.1669 - }
 13.1670 - 
 13.1671 - int ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
 13.1672 -@@ -551,9 +551,7 @@ static int ethtool_set_sg(struct net_dev
 13.1673 - 		return -EFAULT;
 13.1674 - 
 13.1675 - 	if (edata.data && 
 13.1676 --	    !(dev->features & (NETIF_F_IP_CSUM |
 13.1677 --			       NETIF_F_NO_CSUM |
 13.1678 --			       NETIF_F_HW_CSUM)))
 13.1679 -+	    !(dev->features & NETIF_F_ALL_CSUM))
 13.1680 - 		return -EINVAL;
 13.1681 - 
 13.1682 - 	return __ethtool_set_sg(dev, edata.data);
 13.1683 -@@ -561,7 +559,7 @@ static int ethtool_set_sg(struct net_dev
 13.1684 - 
 13.1685 - static int ethtool_get_tso(struct net_device *dev, char __user *useraddr)
 13.1686 - {
 13.1687 --	struct ethtool_value edata = { ETHTOOL_GTSO };
 13.1688 -+	struct ethtool_value edata = { ETHTOOL_GUFO };
 13.1689 - 
 13.1690 - 	if (!dev->ethtool_ops->get_tso)
 13.1691 - 		return -EOPNOTSUPP;
 13.1692 -@@ -616,6 +614,29 @@ static int ethtool_set_ufo(struct net_de
 13.1693 - 	return dev->ethtool_ops->set_ufo(dev, edata.data);
 13.1694 - }
 13.1695 - 
 13.1696 -+static int ethtool_get_gso(struct net_device *dev, char __user *useraddr)
 13.1697 -+{
 13.1698 -+	struct ethtool_value edata = { ETHTOOL_GGSO };
 13.1699 -+
 13.1700 -+	edata.data = dev->features & NETIF_F_GSO;
 13.1701 -+	if (copy_to_user(useraddr, &edata, sizeof(edata)))
 13.1702 -+		 return -EFAULT;
 13.1703 -+	return 0;
 13.1704 -+}
 13.1705 -+
 13.1706 -+static int ethtool_set_gso(struct net_device *dev, char __user *useraddr)
 13.1707 -+{
 13.1708 -+	struct ethtool_value edata;
 13.1709 -+
 13.1710 -+	if (copy_from_user(&edata, useraddr, sizeof(edata)))
 13.1711 -+		return -EFAULT;
 13.1712 -+	if (edata.data)
 13.1713 -+		dev->features |= NETIF_F_GSO;
 13.1714 -+	else
 13.1715 -+		dev->features &= ~NETIF_F_GSO;
 13.1716 -+	return 0;
 13.1717 -+}
 13.1718 -+
 13.1719 - static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
 13.1720 - {
 13.1721 - 	struct ethtool_test test;
 13.1722 -@@ -907,6 +928,12 @@ int dev_ethtool(struct ifreq *ifr)
 13.1723 - 	case ETHTOOL_SUFO:
 13.1724 - 		rc = ethtool_set_ufo(dev, useraddr);
 13.1725 - 		break;
 13.1726 -+	case ETHTOOL_GGSO:
 13.1727 -+		rc = ethtool_get_gso(dev, useraddr);
 13.1728 -+		break;
 13.1729 -+	case ETHTOOL_SGSO:
 13.1730 -+		rc = ethtool_set_gso(dev, useraddr);
 13.1731 -+		break;
 13.1732 - 	default:
 13.1733 - 		rc =  -EOPNOTSUPP;
 13.1734 - 	}
 13.1735 -diff -pruN ../orig-linux-2.6.16.29/net/core/netpoll.c ./net/core/netpoll.c
 13.1736 ---- ../orig-linux-2.6.16.29/net/core/netpoll.c	2006-09-12 19:02:10.000000000 +0100
 13.1737 -+++ ./net/core/netpoll.c	2006-09-19 13:59:20.000000000 +0100
 13.1738 -@@ -273,24 +273,21 @@ static void netpoll_send_skb(struct netp
 13.1739 - 
 13.1740 - 	do {
 13.1741 - 		npinfo->tries--;
 13.1742 --		spin_lock(&np->dev->xmit_lock);
 13.1743 --		np->dev->xmit_lock_owner = smp_processor_id();
 13.1744 -+		netif_tx_lock(np->dev);
 13.1745 - 
 13.1746 - 		/*
 13.1747 - 		 * network drivers do not expect to be called if the queue is
 13.1748 - 		 * stopped.
 13.1749 - 		 */
 13.1750 - 		if (netif_queue_stopped(np->dev)) {
 13.1751 --			np->dev->xmit_lock_owner = -1;
 13.1752 --			spin_unlock(&np->dev->xmit_lock);
 13.1753 -+			netif_tx_unlock(np->dev);
 13.1754 - 			netpoll_poll(np);
 13.1755 - 			udelay(50);
 13.1756 - 			continue;
 13.1757 - 		}
 13.1758 - 
 13.1759 - 		status = np->dev->hard_start_xmit(skb, np->dev);
 13.1760 --		np->dev->xmit_lock_owner = -1;
 13.1761 --		spin_unlock(&np->dev->xmit_lock);
 13.1762 -+		netif_tx_unlock(np->dev);
 13.1763 - 
 13.1764 - 		/* success */
 13.1765 - 		if(!status) {
 13.1766 -diff -pruN ../orig-linux-2.6.16.29/net/core/pktgen.c ./net/core/pktgen.c
 13.1767 ---- ../orig-linux-2.6.16.29/net/core/pktgen.c	2006-09-12 19:02:10.000000000 +0100
 13.1768 -+++ ./net/core/pktgen.c	2006-09-19 13:59:20.000000000 +0100
 13.1769 -@@ -2586,7 +2586,7 @@ static __inline__ void pktgen_xmit(struc
 13.1770 - 		}
 13.1771 - 	}
 13.1772 - 	
 13.1773 --	spin_lock_bh(&odev->xmit_lock);
 13.1774 -+	netif_tx_lock_bh(odev);
 13.1775 - 	if (!netif_queue_stopped(odev)) {
 13.1776 - 
 13.1777 - 		atomic_inc(&(pkt_dev->skb->users));
 13.1778 -@@ -2631,7 +2631,7 @@ retry_now:
 13.1779 - 		pkt_dev->next_tx_ns = 0;
 13.1780 -         }
 13.1781 - 
 13.1782 --	spin_unlock_bh(&odev->xmit_lock);
 13.1783 -+	netif_tx_unlock_bh(odev);
 13.1784 - 	
 13.1785 - 	/* If pkt_dev->count is zero, then run forever */
 13.1786 - 	if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
 13.1787 -diff -pruN ../orig-linux-2.6.16.29/net/core/skbuff.c ./net/core/skbuff.c
 13.1788 ---- ../orig-linux-2.6.16.29/net/core/skbuff.c	2006-09-12 19:02:10.000000000 +0100
 13.1789 -+++ ./net/core/skbuff.c	2006-09-19 13:59:20.000000000 +0100
 13.1790 -@@ -164,9 +164,9 @@ struct sk_buff *__alloc_skb(unsigned int
 13.1791 - 	shinfo = skb_shinfo(skb);
 13.1792 - 	atomic_set(&shinfo->dataref, 1);
 13.1793 - 	shinfo->nr_frags  = 0;
 13.1794 --	shinfo->tso_size = 0;
 13.1795 --	shinfo->tso_segs = 0;
 13.1796 --	shinfo->ufo_size = 0;
 13.1797 -+	shinfo->gso_size = 0;
 13.1798 -+	shinfo->gso_segs = 0;
 13.1799 -+	shinfo->gso_type = 0;
 13.1800 - 	shinfo->ip6_frag_id = 0;
 13.1801 - 	shinfo->frag_list = NULL;
 13.1802 - 
 13.1803 -@@ -230,8 +230,9 @@ struct sk_buff *alloc_skb_from_cache(kme
 13.1804 - 
 13.1805 - 	atomic_set(&(skb_shinfo(skb)->dataref), 1);
 13.1806 - 	skb_shinfo(skb)->nr_frags  = 0;
 13.1807 --	skb_shinfo(skb)->tso_size = 0;
 13.1808 --	skb_shinfo(skb)->tso_segs = 0;
 13.1809 -+	skb_shinfo(skb)->gso_size = 0;
 13.1810 -+	skb_shinfo(skb)->gso_segs = 0;
 13.1811 -+	skb_shinfo(skb)->gso_type = 0;
 13.1812 - 	skb_shinfo(skb)->frag_list = NULL;
 13.1813 - out:
 13.1814 - 	return skb;
 13.1815 -@@ -501,8 +502,9 @@ static void copy_skb_header(struct sk_bu
 13.1816 - 	new->tc_index	= old->tc_index;
 13.1817 - #endif
 13.1818 - 	atomic_set(&new->users, 1);
 13.1819 --	skb_shinfo(new)->tso_size = skb_shinfo(old)->tso_size;
 13.1820 --	skb_shinfo(new)->tso_segs = skb_shinfo(old)->tso_segs;
 13.1821 -+	skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
 13.1822 -+	skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
 13.1823 -+	skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
 13.1824 - }
 13.1825 - 
 13.1826 - /**
 13.1827 -@@ -1777,6 +1779,133 @@ int skb_append_datato_frags(struct sock 
 13.1828 - 	return 0;
 13.1829 - }
 13.1830 - 
 13.1831 -+/**
 13.1832 -+ *	skb_segment - Perform protocol segmentation on skb.
 13.1833 -+ *	@skb: buffer to segment
 13.1834 -+ *	@features: features for the output path (see dev->features)
 13.1835 -+ *
 13.1836 -+ *	This function performs segmentation on the given skb.  It returns
 13.1837 -+ *	the segment at the given position.  It returns NULL if there are
 13.1838 -+ *	no more segments to generate, or when an error is encountered.
 13.1839 -+ */
 13.1840 -+struct sk_buff *skb_segment(struct sk_buff *skb, int features)
 13.1841 -+{
 13.1842 -+	struct sk_buff *segs = NULL;
 13.1843 -+	struct sk_buff *tail = NULL;
 13.1844 -+	unsigned int mss = skb_shinfo(skb)->gso_size;
 13.1845 -+	unsigned int doffset = skb->data - skb->mac.raw;
 13.1846 -+	unsigned int offset = doffset;
 13.1847 -+	unsigned int headroom;
 13.1848 -+	unsigned int len;
 13.1849 -+	int sg = features & NETIF_F_SG;
 13.1850 -+	int nfrags = skb_shinfo(skb)->nr_frags;
 13.1851 -+	int err = -ENOMEM;
 13.1852 -+	int i = 0;
 13.1853 -+	int pos;
 13.1854 -+
 13.1855 -+	__skb_push(skb, doffset);
 13.1856 -+	headroom = skb_headroom(skb);
 13.1857 -+	pos = skb_headlen(skb);
 13.1858 -+
 13.1859 -+	do {
 13.1860 -+		struct sk_buff *nskb;
 13.1861 -+		skb_frag_t *frag;
 13.1862 -+		int hsize, nsize;
 13.1863 -+		int k;
 13.1864 -+		int size;
 13.1865 -+
 13.1866 -+		len = skb->len - offset;
 13.1867 -+		if (len > mss)
 13.1868 -+			len = mss;
 13.1869 -+
 13.1870 -+		hsize = skb_headlen(skb) - offset;
 13.1871 -+		if (hsize < 0)
 13.1872 -+			hsize = 0;
 13.1873 -+		nsize = hsize + doffset;
 13.1874 -+		if (nsize > len + doffset || !sg)
 13.1875 -+			nsize = len + doffset;
 13.1876 -+
 13.1877 -+		nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
 13.1878 -+		if (unlikely(!nskb))
 13.1879 -+			goto err;
 13.1880 -+
 13.1881 -+		if (segs)
 13.1882 -+			tail->next = nskb;
 13.1883 -+		else
 13.1884 -+			segs = nskb;
 13.1885 -+		tail = nskb;
 13.1886 -+
 13.1887 -+		nskb->dev = skb->dev;
 13.1888 -+		nskb->priority = skb->priority;
 13.1889 -+		nskb->protocol = skb->protocol;
 13.1890 -+		nskb->dst = dst_clone(skb->dst);
 13.1891 -+		memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
 13.1892 -+		nskb->pkt_type = skb->pkt_type;
 13.1893 -+		nskb->mac_len = skb->mac_len;
 13.1894 -+
 13.1895 -+		skb_reserve(nskb, headroom);
 13.1896 -+		nskb->mac.raw = nskb->data;
 13.1897 -+		nskb->nh.raw = nskb->data + skb->mac_len;
 13.1898 -+		nskb->h.raw = nskb->nh.raw + (skb->h.raw - skb->nh.raw);
 13.1899 -+		memcpy(skb_put(nskb, doffset), skb->data, doffset);
 13.1900 -+
 13.1901 -+		if (!sg) {
 13.1902 -+			nskb->csum = skb_copy_and_csum_bits(skb, offset,
 13.1903 -+							    skb_put(nskb, len),
 13.1904 -+							    len, 0);
 13.1905 -+			continue;
 13.1906 -+		}
 13.1907 -+
 13.1908 -+		frag = skb_shinfo(nskb)->frags;
 13.1909 -+		k = 0;
 13.1910 -+
 13.1911 -+		nskb->ip_summed = CHECKSUM_HW;
 13.1912 -+		nskb->csum = skb->csum;
 13.1913 -+		memcpy(skb_put(nskb, hsize), skb->data + offset, hsize);
 13.1914 -+
 13.1915 -+		while (pos < offset + len) {
 13.1916 -+			BUG_ON(i >= nfrags);
 13.1917 -+
 13.1918 -+			*frag = skb_shinfo(skb)->frags[i];
 13.1919 -+			get_page(frag->page);
 13.1920 -+			size = frag->size;
 13.1921 -+
 13.1922 -+			if (pos < offset) {
 13.1923 -+				frag->page_offset += offset - pos;
 13.1924 -+				frag->size -= offset - pos;
 13.1925 -+			}
 13.1926 -+
 13.1927 -+			k++;
 13.1928 -+
 13.1929 -+			if (pos + size <= offset + len) {
 13.1930 -+				i++;
 13.1931 -+				pos += size;
 13.1932 -+			} else {
 13.1933 -+				frag->size -= pos + size - (offset + len);
 13.1934 -+				break;
 13.1935 -+			}
 13.1936 -+
 13.1937 -+			frag++;
 13.1938 -+		}
 13.1939 -+
 13.1940 -+		skb_shinfo(nskb)->nr_frags = k;
 13.1941 -+		nskb->data_len = len - hsize;
 13.1942 -+		nskb->len += nskb->data_len;
 13.1943 -+		nskb->truesize += nskb->data_len;
 13.1944 -+	} while ((offset += len) < skb->len);
 13.1945 -+
 13.1946 -+	return segs;
 13.1947 -+
 13.1948 -+err:
 13.1949 -+	while ((skb = segs)) {
 13.1950 -+		segs = skb->next;
 13.1951 -+		kfree(skb);
 13.1952 -+	}
 13.1953 -+	return ERR_PTR(err);
 13.1954 -+}
 13.1955 -+
 13.1956 -+EXPORT_SYMBOL_GPL(skb_segment);
 13.1957 -+
 13.1958 - void __init skb_init(void)
 13.1959 - {
 13.1960 - 	skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
 13.1961 -diff -pruN ../orig-linux-2.6.16.29/net/decnet/dn_nsp_in.c ./net/decnet/dn_nsp_in.c
 13.1962 ---- ../orig-linux-2.6.16.29/net/decnet/dn_nsp_in.c	2006-09-12 19:02:10.000000000 +0100
 13.1963 -+++ ./net/decnet/dn_nsp_in.c	2006-09-19 13:59:20.000000000 +0100
 13.1964 -@@ -801,8 +801,7 @@ got_it:
 13.1965 - 		 * We linearize everything except data segments here.
 13.1966 - 		 */
 13.1967 - 		if (cb->nsp_flags & ~0x60) {
 13.1968 --			if (unlikely(skb_is_nonlinear(skb)) &&
 13.1969 --			    skb_linearize(skb, GFP_ATOMIC) != 0)
 13.1970 -+			if (unlikely(skb_linearize(skb)))
 13.1971 - 				goto free_out;
 13.1972 - 		}
 13.1973 - 
 13.1974 -diff -pruN ../orig-linux-2.6.16.29/net/decnet/dn_route.c ./net/decnet/dn_route.c
 13.1975 ---- ../orig-linux-2.6.16.29/net/decnet/dn_route.c	2006-09-12 19:02:10.000000000 +0100
 13.1976 -+++ ./net/decnet/dn_route.c	2006-09-19 13:59:20.000000000 +0100
 13.1977 -@@ -629,8 +629,7 @@ int dn_route_rcv(struct sk_buff *skb, st
 13.1978 - 			padlen);
 13.1979 - 
 13.1980 -         if (flags & DN_RT_PKT_CNTL) {
 13.1981 --		if (unlikely(skb_is_nonlinear(skb)) &&
 13.1982 --		    skb_linearize(skb, GFP_ATOMIC) != 0)
 13.1983 -+		if (unlikely(skb_linearize(skb)))
 13.1984 - 			goto dump_it;
 13.1985 - 
 13.1986 -                 switch(flags & DN_RT_CNTL_MSK) {
 13.1987 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/af_inet.c ./net/ipv4/af_inet.c
 13.1988 ---- ../orig-linux-2.6.16.29/net/ipv4/af_inet.c	2006-09-12 19:02:10.000000000 +0100
 13.1989 -+++ ./net/ipv4/af_inet.c	2006-09-19 13:59:20.000000000 +0100
 13.1990 -@@ -68,6 +68,7 @@
 13.1991 -  */
 13.1992 - 
 13.1993 - #include <linux/config.h>
 13.1994 -+#include <linux/err.h>
 13.1995 - #include <linux/errno.h>
 13.1996 - #include <linux/types.h>
 13.1997 - #include <linux/socket.h>
 13.1998 -@@ -1084,6 +1085,54 @@ int inet_sk_rebuild_header(struct sock *
 13.1999 - 
 13.2000 - EXPORT_SYMBOL(inet_sk_rebuild_header);
 13.2001 - 
 13.2002 -+static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
 13.2003 -+{
 13.2004 -+	struct sk_buff *segs = ERR_PTR(-EINVAL);
 13.2005 -+	struct iphdr *iph;
 13.2006 -+	struct net_protocol *ops;
 13.2007 -+	int proto;
 13.2008 -+	int ihl;
 13.2009 -+	int id;
 13.2010 -+
 13.2011 -+	if (!pskb_may_pull(skb, sizeof(*iph)))
 13.2012 -+		goto out;
 13.2013 -+
 13.2014 -+	iph = skb->nh.iph;
 13.2015 -+	ihl = iph->ihl * 4;
 13.2016 -+	if (ihl < sizeof(*iph))
 13.2017 -+		goto out;
 13.2018 -+
 13.2019 -+	if (!pskb_may_pull(skb, ihl))
 13.2020 -+		goto out;
 13.2021 -+
 13.2022 -+	skb->h.raw = __skb_pull(skb, ihl);
 13.2023 -+	iph = skb->nh.iph;
 13.2024 -+	id = ntohs(iph->id);
 13.2025 -+	proto = iph->protocol & (MAX_INET_PROTOS - 1);
 13.2026 -+	segs = ERR_PTR(-EPROTONOSUPPORT);
 13.2027 -+
 13.2028 -+	rcu_read_lock();
 13.2029 -+	ops = rcu_dereference(inet_protos[proto]);
 13.2030 -+	if (ops && ops->gso_segment)
 13.2031 -+		segs = ops->gso_segment(skb, features);
 13.2032 -+	rcu_read_unlock();
 13.2033 -+
 13.2034 -+	if (!segs || unlikely(IS_ERR(segs)))
 13.2035 -+		goto out;
 13.2036 -+
 13.2037 -+	skb = segs;
 13.2038 -+	do {
 13.2039 -+		iph = skb->nh.iph;
 13.2040 -+		iph->id = htons(id++);
 13.2041 -+		iph->tot_len = htons(skb->len - skb->mac_len);
 13.2042 -+		iph->check = 0;
 13.2043 -+		iph->check = ip_fast_csum(skb->nh.raw, iph->ihl);
 13.2044 -+	} while ((skb = skb->next));
 13.2045 -+
 13.2046 -+out:
 13.2047 -+	return segs;
 13.2048 -+}
 13.2049 -+
 13.2050 - #ifdef CONFIG_IP_MULTICAST
 13.2051 - static struct net_protocol igmp_protocol = {
 13.2052 - 	.handler =	igmp_rcv,
 13.2053 -@@ -1093,6 +1142,7 @@ static struct net_protocol igmp_protocol
 13.2054 - static struct net_protocol tcp_protocol = {
 13.2055 - 	.handler =	tcp_v4_rcv,
 13.2056 - 	.err_handler =	tcp_v4_err,
 13.2057 -+	.gso_segment =	tcp_tso_segment,
 13.2058 - 	.no_policy =	1,
 13.2059 - };
 13.2060 - 
 13.2061 -@@ -1138,6 +1188,7 @@ static int ipv4_proc_init(void);
 13.2062 - static struct packet_type ip_packet_type = {
 13.2063 - 	.type = __constant_htons(ETH_P_IP),
 13.2064 - 	.func = ip_rcv,
 13.2065 -+	.gso_segment = inet_gso_segment,
 13.2066 - };
 13.2067 - 
 13.2068 - static int __init inet_init(void)
 13.2069 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/ip_output.c ./net/ipv4/ip_output.c
 13.2070 ---- ../orig-linux-2.6.16.29/net/ipv4/ip_output.c	2006-09-12 19:02:10.000000000 +0100
 13.2071 -+++ ./net/ipv4/ip_output.c	2006-09-19 13:59:20.000000000 +0100
 13.2072 -@@ -210,8 +210,7 @@ static inline int ip_finish_output(struc
 13.2073 - 		return dst_output(skb);
 13.2074 - 	}
 13.2075 - #endif
 13.2076 --	if (skb->len > dst_mtu(skb->dst) &&
 13.2077 --	    !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
 13.2078 -+	if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size)
 13.2079 - 		return ip_fragment(skb, ip_finish_output2);
 13.2080 - 	else
 13.2081 - 		return ip_finish_output2(skb);
 13.2082 -@@ -362,7 +361,7 @@ packet_routed:
 13.2083 - 	}
 13.2084 - 
 13.2085 - 	ip_select_ident_more(iph, &rt->u.dst, sk,
 13.2086 --			     (skb_shinfo(skb)->tso_segs ?: 1) - 1);
 13.2087 -+			     (skb_shinfo(skb)->gso_segs ?: 1) - 1);
 13.2088 - 
 13.2089 - 	/* Add an IP checksum. */
 13.2090 - 	ip_send_check(iph);
 13.2091 -@@ -743,7 +742,8 @@ static inline int ip_ufo_append_data(str
 13.2092 - 			       (length - transhdrlen));
 13.2093 - 	if (!err) {
 13.2094 - 		/* specify the length of each IP datagram fragment*/
 13.2095 --		skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
 13.2096 -+		skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
 13.2097 -+		skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
 13.2098 - 		__skb_queue_tail(&sk->sk_write_queue, skb);
 13.2099 - 
 13.2100 - 		return 0;
 13.2101 -@@ -839,7 +839,7 @@ int ip_append_data(struct sock *sk,
 13.2102 - 	 */
 13.2103 - 	if (transhdrlen &&
 13.2104 - 	    length + fragheaderlen <= mtu &&
 13.2105 --	    rt->u.dst.dev->features&(NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) &&
 13.2106 -+	    rt->u.dst.dev->features & NETIF_F_ALL_CSUM &&
 13.2107 - 	    !exthdrlen)
 13.2108 - 		csummode = CHECKSUM_HW;
 13.2109 - 
 13.2110 -@@ -1086,14 +1086,16 @@ ssize_t	ip_append_page(struct sock *sk, 
 13.2111 - 
 13.2112 - 	inet->cork.length += size;
 13.2113 - 	if ((sk->sk_protocol == IPPROTO_UDP) &&
 13.2114 --	    (rt->u.dst.dev->features & NETIF_F_UFO))
 13.2115 --		skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen);
 13.2116 -+	    (rt->u.dst.dev->features & NETIF_F_UFO)) {
 13.2117 -+		skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
 13.2118 -+		skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
 13.2119 -+	}
 13.2120 - 
 13.2121 - 
 13.2122 - 	while (size > 0) {
 13.2123 - 		int i;
 13.2124 - 
 13.2125 --		if (skb_shinfo(skb)->ufo_size)
 13.2126 -+		if (skb_shinfo(skb)->gso_size)
 13.2127 - 			len = size;
 13.2128 - 		else {
 13.2129 - 
 13.2130 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/ipcomp.c ./net/ipv4/ipcomp.c
 13.2131 ---- ../orig-linux-2.6.16.29/net/ipv4/ipcomp.c	2006-09-12 19:02:10.000000000 +0100
 13.2132 -+++ ./net/ipv4/ipcomp.c	2006-09-19 13:59:20.000000000 +0100
 13.2133 -@@ -84,7 +84,7 @@ static int ipcomp_input(struct xfrm_stat
 13.2134 -                         struct xfrm_decap_state *decap, struct sk_buff *skb)
 13.2135 - {
 13.2136 - 	u8 nexthdr;
 13.2137 --	int err = 0;
 13.2138 -+	int err = -ENOMEM;
 13.2139 - 	struct iphdr *iph;
 13.2140 - 	union {
 13.2141 - 		struct iphdr	iph;
 13.2142 -@@ -92,11 +92,8 @@ static int ipcomp_input(struct xfrm_stat
 13.2143 - 	} tmp_iph;
 13.2144 - 
 13.2145 - 
 13.2146 --	if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
 13.2147 --	    skb_linearize(skb, GFP_ATOMIC) != 0) {
 13.2148 --	    	err = -ENOMEM;
 13.2149 -+	if (skb_linearize_cow(skb))
 13.2150 - 	    	goto out;
 13.2151 --	}
 13.2152 - 
 13.2153 - 	skb->ip_summed = CHECKSUM_NONE;
 13.2154 - 
 13.2155 -@@ -171,10 +168,8 @@ static int ipcomp_output(struct xfrm_sta
 13.2156 - 		goto out_ok;
 13.2157 - 	}
 13.2158 - 
 13.2159 --	if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
 13.2160 --	    skb_linearize(skb, GFP_ATOMIC) != 0) {
 13.2161 -+	if (skb_linearize_cow(skb))
 13.2162 - 		goto out_ok;
 13.2163 --	}
 13.2164 - 	
 13.2165 - 	err = ipcomp_compress(x, skb);
 13.2166 - 	iph = skb->nh.iph;
 13.2167 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/tcp.c ./net/ipv4/tcp.c
 13.2168 ---- ../orig-linux-2.6.16.29/net/ipv4/tcp.c	2006-09-12 19:02:10.000000000 +0100
 13.2169 -+++ ./net/ipv4/tcp.c	2006-09-19 13:59:20.000000000 +0100
 13.2170 -@@ -257,6 +257,7 @@
 13.2171 - #include <linux/fs.h>
 13.2172 - #include <linux/random.h>
 13.2173 - #include <linux/bootmem.h>
 13.2174 -+#include <linux/err.h>
 13.2175 - 
 13.2176 - #include <net/icmp.h>
 13.2177 - #include <net/tcp.h>
 13.2178 -@@ -570,7 +571,7 @@ new_segment:
 13.2179 - 		skb->ip_summed = CHECKSUM_HW;
 13.2180 - 		tp->write_seq += copy;
 13.2181 - 		TCP_SKB_CB(skb)->end_seq += copy;
 13.2182 --		skb_shinfo(skb)->tso_segs = 0;
 13.2183 -+		skb_shinfo(skb)->gso_segs = 0;
 13.2184 - 
 13.2185 - 		if (!copied)
 13.2186 - 			TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_PSH;
 13.2187 -@@ -621,14 +622,10 @@ ssize_t tcp_sendpage(struct socket *sock
 13.2188 - 	ssize_t res;
 13.2189 - 	struct sock *sk = sock->sk;
 13.2190 - 
 13.2191 --#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
 13.2192 --
 13.2193 - 	if (!(sk->sk_route_caps & NETIF_F_SG) ||
 13.2194 --	    !(sk->sk_route_caps & TCP_ZC_CSUM_FLAGS))
 13.2195 -+	    !(sk->sk_route_caps & NETIF_F_ALL_CSUM))
 13.2196 - 		return sock_no_sendpage(sock, page, offset, size, flags);
 13.2197 - 
 13.2198 --#undef TCP_ZC_CSUM_FLAGS
 13.2199 --
 13.2200 - 	lock_sock(sk);
 13.2201 - 	TCP_CHECK_TIMER(sk);
 13.2202 - 	res = do_tcp_sendpages(sk, &page, offset, size, flags);
 13.2203 -@@ -725,9 +722,7 @@ new_segment:
 13.2204 - 				/*
 13.2205 - 				 * Check whether we can use HW checksum.
 13.2206 - 				 */
 13.2207 --				if (sk->sk_route_caps &
 13.2208 --				    (NETIF_F_IP_CSUM | NETIF_F_NO_CSUM |
 13.2209 --				     NETIF_F_HW_CSUM))
 13.2210 -+				if (sk->sk_route_caps & NETIF_F_ALL_CSUM)
 13.2211 - 					skb->ip_summed = CHECKSUM_HW;
 13.2212 - 
 13.2213 - 				skb_entail(sk, tp, skb);
 13.2214 -@@ -823,7 +818,7 @@ new_segment:
 13.2215 - 
 13.2216 - 			tp->write_seq += copy;
 13.2217 - 			TCP_SKB_CB(skb)->end_seq += copy;
 13.2218 --			skb_shinfo(skb)->tso_segs = 0;
 13.2219 -+			skb_shinfo(skb)->gso_segs = 0;
 13.2220 - 
 13.2221 - 			from += copy;
 13.2222 - 			copied += copy;
 13.2223 -@@ -2026,6 +2021,71 @@ int tcp_getsockopt(struct sock *sk, int 
 13.2224 - }
 13.2225 - 
 13.2226 - 
 13.2227 -+struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
 13.2228 -+{
 13.2229 -+	struct sk_buff *segs = ERR_PTR(-EINVAL);
 13.2230 -+	struct tcphdr *th;
 13.2231 -+	unsigned thlen;
 13.2232 -+	unsigned int seq;
 13.2233 -+	unsigned int delta;
 13.2234 -+	unsigned int oldlen;
 13.2235 -+	unsigned int len;
 13.2236 -+
 13.2237 -+	if (!pskb_may_pull(skb, sizeof(*th)))
 13.2238 -+		goto out;
 13.2239 -+
 13.2240 -+	th = skb->h.th;
 13.2241 -+	thlen = th->doff * 4;
 13.2242 -+	if (thlen < sizeof(*th))
 13.2243 -+		goto out;
 13.2244 -+
 13.2245 -+	if (!pskb_may_pull(skb, thlen))
 13.2246 -+		goto out;
 13.2247 -+
 13.2248 -+	segs = NULL;
 13.2249 -+	if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
 13.2250 -+		goto out;
 13.2251 -+
 13.2252 -+	oldlen = (u16)~skb->len;
 13.2253 -+	__skb_pull(skb, thlen);
 13.2254 -+
 13.2255 -+	segs = skb_segment(skb, features);
 13.2256 -+	if (IS_ERR(segs))
 13.2257 -+		goto out;
 13.2258 -+
 13.2259 -+	len = skb_shinfo(skb)->gso_size;
 13.2260 -+	delta = htonl(oldlen + (thlen + len));
 13.2261 -+
 13.2262 -+	skb = segs;
 13.2263 -+	th = skb->h.th;
 13.2264 -+	seq = ntohl(th->seq);
 13.2265 -+
 13.2266 -+	do {
 13.2267 -+		th->fin = th->psh = 0;
 13.2268 -+
 13.2269 -+		th->check = ~csum_fold(th->check + delta);
 13.2270 -+		if (skb->ip_summed != CHECKSUM_HW)
 13.2271 -+			th->check = csum_fold(csum_partial(skb->h.raw, thlen,
 13.2272 -+							   skb->csum));
 13.2273 -+
 13.2274 -+		seq += len;
 13.2275 -+		skb = skb->next;
 13.2276 -+		th = skb->h.th;
 13.2277 -+
 13.2278 -+		th->seq = htonl(seq);
 13.2279 -+		th->cwr = 0;
 13.2280 -+	} while (skb->next);
 13.2281 -+
 13.2282 -+	delta = htonl(oldlen + (skb->tail - skb->h.raw) + skb->data_len);
 13.2283 -+	th->check = ~csum_fold(th->check + delta);
 13.2284 -+	if (skb->ip_summed != CHECKSUM_HW)
 13.2285 -+		th->check = csum_fold(csum_partial(skb->h.raw, thlen,
 13.2286 -+						   skb->csum));
 13.2287 -+
 13.2288 -+out:
 13.2289 -+	return segs;
 13.2290 -+}
 13.2291 -+
 13.2292 - extern void __skb_cb_too_small_for_tcp(int, int);
 13.2293 - extern struct tcp_congestion_ops tcp_reno;
 13.2294 - 
 13.2295 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/tcp_input.c ./net/ipv4/tcp_input.c
 13.2296 ---- ../orig-linux-2.6.16.29/net/ipv4/tcp_input.c	2006-09-12 19:02:10.000000000 +0100
 13.2297 -+++ ./net/ipv4/tcp_input.c	2006-09-19 13:59:20.000000000 +0100
 13.2298 -@@ -1072,7 +1072,7 @@ tcp_sacktag_write_queue(struct sock *sk,
 13.2299 - 				else
 13.2300 - 					pkt_len = (end_seq -
 13.2301 - 						   TCP_SKB_CB(skb)->seq);
 13.2302 --				if (tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->tso_size))
 13.2303 -+				if (tcp_fragment(sk, skb, pkt_len, skb_shinfo(skb)->gso_size))
 13.2304 - 					break;
 13.2305 - 				pcount = tcp_skb_pcount(skb);
 13.2306 - 			}
 13.2307 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/tcp_output.c ./net/ipv4/tcp_output.c
 13.2308 ---- ../orig-linux-2.6.16.29/net/ipv4/tcp_output.c	2006-09-12 19:02:10.000000000 +0100
 13.2309 -+++ ./net/ipv4/tcp_output.c	2006-09-19 13:59:20.000000000 +0100
 13.2310 -@@ -497,15 +497,17 @@ static void tcp_set_skb_tso_segs(struct 
 13.2311 - 		/* Avoid the costly divide in the normal
 13.2312 - 		 * non-TSO case.
 13.2313 - 		 */
 13.2314 --		skb_shinfo(skb)->tso_segs = 1;
 13.2315 --		skb_shinfo(skb)->tso_size = 0;
 13.2316 -+		skb_shinfo(skb)->gso_segs = 1;
 13.2317 -+		skb_shinfo(skb)->gso_size = 0;
 13.2318 -+		skb_shinfo(skb)->gso_type = 0;
 13.2319 - 	} else {
 13.2320 - 		unsigned int factor;
 13.2321 - 
 13.2322 - 		factor = skb->len + (mss_now - 1);
 13.2323 - 		factor /= mss_now;
 13.2324 --		skb_shinfo(skb)->tso_segs = factor;
 13.2325 --		skb_shinfo(skb)->tso_size = mss_now;
 13.2326 -+		skb_shinfo(skb)->gso_segs = factor;
 13.2327 -+		skb_shinfo(skb)->gso_size = mss_now;
 13.2328 -+		skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
 13.2329 - 	}
 13.2330 - }
 13.2331 - 
 13.2332 -@@ -850,7 +852,7 @@ static int tcp_init_tso_segs(struct sock
 13.2333 - 
 13.2334 - 	if (!tso_segs ||
 13.2335 - 	    (tso_segs > 1 &&
 13.2336 --	     skb_shinfo(skb)->tso_size != mss_now)) {
 13.2337 -+	     tcp_skb_mss(skb) != mss_now)) {
 13.2338 - 		tcp_set_skb_tso_segs(sk, skb, mss_now);
 13.2339 - 		tso_segs = tcp_skb_pcount(skb);
 13.2340 - 	}
 13.2341 -@@ -1510,8 +1512,9 @@ int tcp_retransmit_skb(struct sock *sk, 
 13.2342 - 	   tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {
 13.2343 - 		if (!pskb_trim(skb, 0)) {
 13.2344 - 			TCP_SKB_CB(skb)->seq = TCP_SKB_CB(skb)->end_seq - 1;
 13.2345 --			skb_shinfo(skb)->tso_segs = 1;
 13.2346 --			skb_shinfo(skb)->tso_size = 0;
 13.2347 -+			skb_shinfo(skb)->gso_segs = 1;
 13.2348 -+			skb_shinfo(skb)->gso_size = 0;
 13.2349 -+			skb_shinfo(skb)->gso_type = 0;
 13.2350 - 			skb->ip_summed = CHECKSUM_NONE;
 13.2351 - 			skb->csum = 0;
 13.2352 - 		}
 13.2353 -@@ -1716,8 +1719,9 @@ void tcp_send_fin(struct sock *sk)
 13.2354 - 		skb->csum = 0;
 13.2355 - 		TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_FIN);
 13.2356 - 		TCP_SKB_CB(skb)->sacked = 0;
 13.2357 --		skb_shinfo(skb)->tso_segs = 1;
 13.2358 --		skb_shinfo(skb)->tso_size = 0;
 13.2359 -+		skb_shinfo(skb)->gso_segs = 1;
 13.2360 -+		skb_shinfo(skb)->gso_size = 0;
 13.2361 -+		skb_shinfo(skb)->gso_type = 0;
 13.2362 - 
 13.2363 - 		/* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */
 13.2364 - 		TCP_SKB_CB(skb)->seq = tp->write_seq;
 13.2365 -@@ -1749,8 +1753,9 @@ void tcp_send_active_reset(struct sock *
 13.2366 - 	skb->csum = 0;
 13.2367 - 	TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_RST);
 13.2368 - 	TCP_SKB_CB(skb)->sacked = 0;
 13.2369 --	skb_shinfo(skb)->tso_segs = 1;
 13.2370 --	skb_shinfo(skb)->tso_size = 0;
 13.2371 -+	skb_shinfo(skb)->gso_segs = 1;
 13.2372 -+	skb_shinfo(skb)->gso_size = 0;
 13.2373 -+	skb_shinfo(skb)->gso_type = 0;
 13.2374 - 
 13.2375 - 	/* Send it off. */
 13.2376 - 	TCP_SKB_CB(skb)->seq = tcp_acceptable_seq(sk, tp);
 13.2377 -@@ -1833,8 +1838,9 @@ struct sk_buff * tcp_make_synack(struct 
 13.2378 - 	TCP_SKB_CB(skb)->seq = tcp_rsk(req)->snt_isn;
 13.2379 - 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
 13.2380 - 	TCP_SKB_CB(skb)->sacked = 0;
 13.2381 --	skb_shinfo(skb)->tso_segs = 1;
 13.2382 --	skb_shinfo(skb)->tso_size = 0;
 13.2383 -+	skb_shinfo(skb)->gso_segs = 1;
 13.2384 -+	skb_shinfo(skb)->gso_size = 0;
 13.2385 -+	skb_shinfo(skb)->gso_type = 0;
 13.2386 - 	th->seq = htonl(TCP_SKB_CB(skb)->seq);
 13.2387 - 	th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1);
 13.2388 - 	if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */
 13.2389 -@@ -1937,8 +1943,9 @@ int tcp_connect(struct sock *sk)
 13.2390 - 	TCP_SKB_CB(buff)->flags = TCPCB_FLAG_SYN;
 13.2391 - 	TCP_ECN_send_syn(sk, tp, buff);
 13.2392 - 	TCP_SKB_CB(buff)->sacked = 0;
 13.2393 --	skb_shinfo(buff)->tso_segs = 1;
 13.2394 --	skb_shinfo(buff)->tso_size = 0;
 13.2395 -+	skb_shinfo(buff)->gso_segs = 1;
 13.2396 -+	skb_shinfo(buff)->gso_size = 0;
 13.2397 -+	skb_shinfo(buff)->gso_type = 0;
 13.2398 - 	buff->csum = 0;
 13.2399 - 	TCP_SKB_CB(buff)->seq = tp->write_seq++;
 13.2400 - 	TCP_SKB_CB(buff)->end_seq = tp->write_seq;
 13.2401 -@@ -2042,8 +2049,9 @@ void tcp_send_ack(struct sock *sk)
 13.2402 - 		buff->csum = 0;
 13.2403 - 		TCP_SKB_CB(buff)->flags = TCPCB_FLAG_ACK;
 13.2404 - 		TCP_SKB_CB(buff)->sacked = 0;
 13.2405 --		skb_shinfo(buff)->tso_segs = 1;
 13.2406 --		skb_shinfo(buff)->tso_size = 0;
 13.2407 -+		skb_shinfo(buff)->gso_segs = 1;
 13.2408 -+		skb_shinfo(buff)->gso_size = 0;
 13.2409 -+		skb_shinfo(buff)->gso_type = 0;
 13.2410 - 
 13.2411 - 		/* Send it off, this clears delayed acks for us. */
 13.2412 - 		TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tcp_acceptable_seq(sk, tp);
 13.2413 -@@ -2078,8 +2086,9 @@ static int tcp_xmit_probe_skb(struct soc
 13.2414 - 	skb->csum = 0;
 13.2415 - 	TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK;
 13.2416 - 	TCP_SKB_CB(skb)->sacked = urgent;
 13.2417 --	skb_shinfo(skb)->tso_segs = 1;
 13.2418 --	skb_shinfo(skb)->tso_size = 0;
 13.2419 -+	skb_shinfo(skb)->gso_segs = 1;
 13.2420 -+	skb_shinfo(skb)->gso_size = 0;
 13.2421 -+	skb_shinfo(skb)->gso_type = 0;
 13.2422 - 
 13.2423 - 	/* Use a previous sequence.  This should cause the other
 13.2424 - 	 * end to send an ack.  Don't queue or clone SKB, just
 13.2425 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/xfrm4_output.c ./net/ipv4/xfrm4_output.c
 13.2426 ---- ../orig-linux-2.6.16.29/net/ipv4/xfrm4_output.c	2006-09-19 13:59:15.000000000 +0100
 13.2427 -+++ ./net/ipv4/xfrm4_output.c	2006-09-19 13:59:20.000000000 +0100
 13.2428 -@@ -9,6 +9,8 @@
 13.2429 -  */
 13.2430 - 
 13.2431 - #include <linux/compiler.h>
 13.2432 -+#include <linux/if_ether.h>
 13.2433 -+#include <linux/kernel.h>
 13.2434 - #include <linux/skbuff.h>
 13.2435 - #include <linux/spinlock.h>
 13.2436 - #include <linux/netfilter_ipv4.h>
 13.2437 -@@ -158,16 +160,10 @@ error_nolock:
 13.2438 - 	goto out_exit;
 13.2439 - }
 13.2440 - 
 13.2441 --static int xfrm4_output_finish(struct sk_buff *skb)
 13.2442 -+static int xfrm4_output_finish2(struct sk_buff *skb)
 13.2443 - {
 13.2444 - 	int err;
 13.2445 - 
 13.2446 --#ifdef CONFIG_NETFILTER
 13.2447 --	if (!skb->dst->xfrm) {
 13.2448 --		IPCB(skb)->flags |= IPSKB_REROUTED;
 13.2449 --		return dst_output(skb);
 13.2450 --	}
 13.2451 --#endif
 13.2452 - 	while (likely((err = xfrm4_output_one(skb)) == 0)) {
 13.2453 - 		nf_reset(skb);
 13.2454 - 
 13.2455 -@@ -180,7 +176,7 @@ static int xfrm4_output_finish(struct sk
 13.2456 - 			return dst_output(skb);
 13.2457 - 
 13.2458 - 		err = nf_hook(PF_INET, NF_IP_POST_ROUTING, &skb, NULL,
 13.2459 --			      skb->dst->dev, xfrm4_output_finish);
 13.2460 -+			      skb->dst->dev, xfrm4_output_finish2);
 13.2461 - 		if (unlikely(err != 1))
 13.2462 - 			break;
 13.2463 - 	}
 13.2464 -@@ -188,6 +184,48 @@ static int xfrm4_output_finish(struct sk
 13.2465 - 	return err;
 13.2466 - }
 13.2467 - 
 13.2468 -+static int xfrm4_output_finish(struct sk_buff *skb)
 13.2469 -+{
 13.2470 -+	struct sk_buff *segs;
 13.2471 -+
 13.2472 -+#ifdef CONFIG_NETFILTER
 13.2473 -+	if (!skb->dst->xfrm) {
 13.2474 -+		IPCB(skb)->flags |= IPSKB_REROUTED;
 13.2475 -+		return dst_output(skb);
 13.2476 -+	}
 13.2477 -+#endif
 13.2478 -+
 13.2479 -+	if (!skb_shinfo(skb)->gso_size)
 13.2480 -+		return xfrm4_output_finish2(skb);
 13.2481 -+
 13.2482 -+	skb->protocol = htons(ETH_P_IP);
 13.2483 -+	segs = skb_gso_segment(skb, 0);
 13.2484 -+	kfree_skb(skb);
 13.2485 -+	if (unlikely(IS_ERR(segs)))
 13.2486 -+		return PTR_ERR(segs);
 13.2487 -+
 13.2488 -+	do {
 13.2489 -+		struct sk_buff *nskb = segs->next;
 13.2490 -+		int err;
 13.2491 -+
 13.2492 -+		segs->next = NULL;
 13.2493 -+		err = xfrm4_output_finish2(segs);
 13.2494 -+
 13.2495 -+		if (unlikely(err)) {
 13.2496 -+			while ((segs = nskb)) {
 13.2497 -+				nskb = segs->next;
 13.2498 -+				segs->next = NULL;
 13.2499 -+				kfree_skb(segs);
 13.2500 -+			}
 13.2501 -+			return err;
 13.2502 -+		}
 13.2503 -+
 13.2504 -+		segs = nskb;
 13.2505 -+	} while (segs);
 13.2506 -+
 13.2507 -+	return 0;
 13.2508 -+}
 13.2509 -+
 13.2510 - int xfrm4_output(struct sk_buff *skb)
 13.2511 - {
 13.2512 - 	return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev,
 13.2513 -diff -pruN ../orig-linux-2.6.16.29/net/ipv6/ip6_output.c ./net/ipv6/ip6_output.c
 13.2514 ---- ../orig-linux-2.6.16.29/net/ipv6/ip6_output.c	2006-09-12 19:02:10.000000000 +0100
 13.2515 -+++ ./net/ipv6/ip6_output.c	2006-09-19 13:59:20.000000000 +0100
 13.2516 -@@ -147,7 +147,7 @@ static int ip6_output2(struct sk_buff *s
 13.2517 - 
 13.2518 - int ip6_output(struct sk_buff *skb)
 13.2519 - {
 13.2520 --	if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->ufo_size) ||
 13.2521 -+	if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size) ||
 13.2522 - 				dst_allfrag(skb->dst))
 13.2523 - 		return ip6_fragment(skb, ip6_output2);
 13.2524 - 	else
 13.2525 -@@ -829,8 +829,9 @@ static inline int ip6_ufo_append_data(st
 13.2526 - 		struct frag_hdr fhdr;
 13.2527 - 
 13.2528 - 		/* specify the length of each IP datagram fragment*/
 13.2529 --		skb_shinfo(skb)->ufo_size = (mtu - fragheaderlen) - 
 13.2530 --						sizeof(struct frag_hdr);
 13.2531 -+		skb_shinfo(skb)->gso_size = mtu - fragheaderlen - 
 13.2532 -+					    sizeof(struct frag_hdr);
 13.2533 -+		skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
 13.2534 - 		ipv6_select_ident(skb, &fhdr);
 13.2535 - 		skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
 13.2536 - 		__skb_queue_tail(&sk->sk_write_queue, skb);
 13.2537 -diff -pruN ../orig-linux-2.6.16.29/net/ipv6/ipcomp6.c ./net/ipv6/ipcomp6.c
 13.2538 ---- ../orig-linux-2.6.16.29/net/ipv6/ipcomp6.c	2006-09-12 19:02:10.000000000 +0100
 13.2539 -+++ ./net/ipv6/ipcomp6.c	2006-09-19 13:59:20.000000000 +0100
 13.2540 -@@ -64,7 +64,7 @@ static LIST_HEAD(ipcomp6_tfms_list);
 13.2541 - 
 13.2542 - static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
 13.2543 - {
 13.2544 --	int err = 0;
 13.2545 -+	int err = -ENOMEM;
 13.2546 - 	u8 nexthdr = 0;
 13.2547 - 	int hdr_len = skb->h.raw - skb->nh.raw;
 13.2548 - 	unsigned char *tmp_hdr = NULL;
 13.2549 -@@ -75,11 +75,8 @@ static int ipcomp6_input(struct xfrm_sta
 13.2550 - 	struct crypto_tfm *tfm;
 13.2551 - 	int cpu;
 13.2552 - 
 13.2553 --	if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
 13.2554 --		skb_linearize(skb, GFP_ATOMIC) != 0) {
 13.2555 --		err = -ENOMEM;
 13.2556 -+	if (skb_linearize_cow(skb))
 13.2557 - 		goto out;
 13.2558 --	}
 13.2559 - 
 13.2560 - 	skb->ip_summed = CHECKSUM_NONE;
 13.2561 - 
 13.2562 -@@ -158,10 +155,8 @@ static int ipcomp6_output(struct xfrm_st
 13.2563 - 		goto out_ok;
 13.2564 - 	}
 13.2565 - 
 13.2566 --	if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
 13.2567 --		skb_linearize(skb, GFP_ATOMIC) != 0) {
 13.2568 -+	if (skb_linearize_cow(skb))
 13.2569 - 		goto out_ok;
 13.2570 --	}
 13.2571 - 
 13.2572 - 	/* compression */
 13.2573 - 	plen = skb->len - hdr_len;
 13.2574 -diff -pruN ../orig-linux-2.6.16.29/net/ipv6/xfrm6_output.c ./net/ipv6/xfrm6_output.c
 13.2575 ---- ../orig-linux-2.6.16.29/net/ipv6/xfrm6_output.c	2006-09-12 19:02:10.000000000 +0100
 13.2576 -+++ ./net/ipv6/xfrm6_output.c	2006-09-19 13:59:20.000000000 +0100
 13.2577 -@@ -151,7 +151,7 @@ error_nolock:
 13.2578 - 	goto out_exit;
 13.2579 - }
 13.2580 - 
 13.2581 --static int xfrm6_output_finish(struct sk_buff *skb)
 13.2582 -+static int xfrm6_output_finish2(struct sk_buff *skb)
 13.2583 - {
 13.2584 - 	int err;
 13.2585 - 
 13.2586 -@@ -167,7 +167,7 @@ static int xfrm6_output_finish(struct sk
 13.2587 - 			return dst_output(skb);
 13.2588 - 
 13.2589 - 		err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, &skb, NULL,
 13.2590 --			      skb->dst->dev, xfrm6_output_finish);
 13.2591 -+			      skb->dst->dev, xfrm6_output_finish2);
 13.2592 - 		if (unlikely(err != 1))
 13.2593 - 			break;
 13.2594 - 	}
 13.2595 -@@ -175,6 +175,41 @@ static int xfrm6_output_finish(struct sk
 13.2596 - 	return err;
 13.2597 - }
 13.2598 - 
 13.2599 -+static int xfrm6_output_finish(struct sk_buff *skb)
 13.2600 -+{
 13.2601 -+	struct sk_buff *segs;
 13.2602 -+
 13.2603 -+	if (!skb_shinfo(skb)->gso_size)
 13.2604 -+		return xfrm6_output_finish2(skb);
 13.2605 -+
 13.2606 -+	skb->protocol = htons(ETH_P_IP);
 13.2607 -+	segs = skb_gso_segment(skb, 0);
 13.2608 -+	kfree_skb(skb);
 13.2609 -+	if (unlikely(IS_ERR(segs)))
 13.2610 -+		return PTR_ERR(segs);
 13.2611 -+
 13.2612 -+	do {
 13.2613 -+		struct sk_buff *nskb = segs->next;
 13.2614 -+		int err;
 13.2615 -+
 13.2616 -+		segs->next = NULL;
 13.2617 -+		err = xfrm6_output_finish2(segs);
 13.2618 -+
 13.2619 -+		if (unlikely(err)) {
 13.2620 -+			while ((segs = nskb)) {
 13.2621 -+				nskb = segs->next;
 13.2622 -+				segs->next = NULL;
 13.2623 -+				kfree_skb(segs);
 13.2624 -+			}
 13.2625 -+			return err;
 13.2626 -+		}
 13.2627 -+
 13.2628 -+		segs = nskb;
 13.2629 -+	} while (segs);
 13.2630 -+
 13.2631 -+	return 0;
 13.2632 -+}
 13.2633 -+
 13.2634 - int xfrm6_output(struct sk_buff *skb)
 13.2635 - {
 13.2636 - 	return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev,
 13.2637 -diff -pruN ../orig-linux-2.6.16.29/net/sched/sch_generic.c ./net/sched/sch_generic.c
 13.2638 ---- ../orig-linux-2.6.16.29/net/sched/sch_generic.c	2006-09-12 19:02:10.000000000 +0100
 13.2639 -+++ ./net/sched/sch_generic.c	2006-09-19 13:59:20.000000000 +0100
 13.2640 -@@ -72,9 +72,9 @@ void qdisc_unlock_tree(struct net_device
 13.2641 -    dev->queue_lock serializes queue accesses for this device
 13.2642 -    AND dev->qdisc pointer itself.
 13.2643 - 
 13.2644 --   dev->xmit_lock serializes accesses to device driver.
 13.2645 -+   netif_tx_lock serializes accesses to device driver.
 13.2646 - 
 13.2647 --   dev->queue_lock and dev->xmit_lock are mutually exclusive,
 13.2648 -+   dev->queue_lock and netif_tx_lock are mutually exclusive,
 13.2649 -    if one is grabbed, another must be free.
 13.2650 -  */
 13.2651 - 
 13.2652 -@@ -90,14 +90,17 @@ void qdisc_unlock_tree(struct net_device
 13.2653 -    NOTE: Called under dev->queue_lock with locally disabled BH.
 13.2654 - */
 13.2655 - 
 13.2656 --int qdisc_restart(struct net_device *dev)
 13.2657 -+static inline int qdisc_restart(struct net_device *dev)
 13.2658 - {
 13.2659 - 	struct Qdisc *q = dev->qdisc;
 13.2660 - 	struct sk_buff *skb;
 13.2661 - 
 13.2662 - 	/* Dequeue packet */
 13.2663 --	if ((skb = q->dequeue(q)) != NULL) {
 13.2664 -+	if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) {
 13.2665 - 		unsigned nolock = (dev->features & NETIF_F_LLTX);
 13.2666 -+
 13.2667 -+		dev->gso_skb = NULL;
 13.2668 -+
 13.2669 - 		/*
 13.2670 - 		 * When the driver has LLTX set it does its own locking
 13.2671 - 		 * in start_xmit. No need to add additional overhead by
 13.2672 -@@ -108,7 +111,7 @@ int qdisc_restart(struct net_device *dev
 13.2673 - 		 * will be requeued.
 13.2674 - 		 */
 13.2675 - 		if (!nolock) {
 13.2676 --			if (!spin_trylock(&dev->xmit_lock)) {
 13.2677 -+			if (!netif_tx_trylock(dev)) {
 13.2678 - 			collision:
 13.2679 - 				/* So, someone grabbed the driver. */
 13.2680 - 				
 13.2681 -@@ -126,8 +129,6 @@ int qdisc_restart(struct net_device *dev
 13.2682 - 				__get_cpu_var(netdev_rx_stat).cpu_collision++;
 13.2683 - 				goto requeue;
 13.2684 - 			}
 13.2685 --			/* Remember that the driver is grabbed by us. */
 13.2686 --			dev->xmit_lock_owner = smp_processor_id();
 13.2687 - 		}
 13.2688 - 		
 13.2689 - 		{
 13.2690 -@@ -136,14 +137,11 @@ int qdisc_restart(struct net_device *dev
 13.2691 - 
 13.2692 - 			if (!netif_queue_stopped(dev)) {
 13.2693 - 				int ret;
 13.2694 --				if (netdev_nit)
 13.2695 --					dev_queue_xmit_nit(skb, dev);
 13.2696 - 
 13.2697 --				ret = dev->hard_start_xmit(skb, dev);
 13.2698 -+				ret = dev_hard_start_xmit(skb, dev);
 13.2699 - 				if (ret == NETDEV_TX_OK) { 
 13.2700 - 					if (!nolock) {
 13.2701 --						dev->xmit_lock_owner = -1;
 13.2702 --						spin_unlock(&dev->xmit_lock);
 13.2703 -+						netif_tx_unlock(dev);
 13.2704 - 					}
 13.2705 - 					spin_lock(&dev->queue_lock);
 13.2706 - 					return -1;
 13.2707 -@@ -157,8 +155,7 @@ int qdisc_restart(struct net_device *dev
 13.2708 - 			/* NETDEV_TX_BUSY - we need to requeue */
 13.2709 - 			/* Release the driver */
 13.2710 - 			if (!nolock) { 
 13.2711 --				dev->xmit_lock_owner = -1;
 13.2712 --				spin_unlock(&dev->xmit_lock);
 13.2713 -+				netif_tx_unlock(dev);
 13.2714 - 			} 
 13.2715 - 			spin_lock(&dev->queue_lock);
 13.2716 - 			q = dev->qdisc;
 13.2717 -@@ -175,7 +172,10 @@ int qdisc_restart(struct net_device *dev
 13.2718 - 		 */
 13.2719 - 
 13.2720 - requeue:
 13.2721 --		q->ops->requeue(skb, q);
 13.2722 -+		if (skb->next)
 13.2723 -+			dev->gso_skb = skb;
 13.2724 -+		else
 13.2725 -+			q->ops->requeue(skb, q);
 13.2726 - 		netif_schedule(dev);
 13.2727 - 		return 1;
 13.2728 - 	}
 13.2729 -@@ -183,11 +183,23 @@ requeue:
 13.2730 - 	return q->q.qlen;
 13.2731 - }
 13.2732 - 
 13.2733 -+void __qdisc_run(struct net_device *dev)
 13.2734 -+{
 13.2735 -+	if (unlikely(dev->qdisc == &noop_qdisc))
 13.2736 -+		goto out;
 13.2737 -+
 13.2738 -+	while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev))
 13.2739 -+		/* NOTHING */;
 13.2740 -+
 13.2741 -+out:
 13.2742 -+	clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
 13.2743 -+}
 13.2744 -+
 13.2745 - static void dev_watchdog(unsigned long arg)
 13.2746 - {
 13.2747 - 	struct net_device *dev = (struct net_device *)arg;
 13.2748 - 
 13.2749 --	spin_lock(&dev->xmit_lock);
 13.2750 -+	netif_tx_lock(dev);
 13.2751 - 	if (dev->qdisc != &noop_qdisc) {
 13.2752 - 		if (netif_device_present(dev) &&
 13.2753 - 		    netif_running(dev) &&
 13.2754 -@@ -201,7 +213,7 @@ static void dev_watchdog(unsigned long a
 13.2755 - 				dev_hold(dev);
 13.2756 - 		}
 13.2757 - 	}
 13.2758 --	spin_unlock(&dev->xmit_lock);
 13.2759 -+	netif_tx_unlock(dev);
 13.2760 - 
 13.2761 - 	dev_put(dev);
 13.2762 - }
 13.2763 -@@ -225,17 +237,17 @@ void __netdev_watchdog_up(struct net_dev
 13.2764 - 
 13.2765 - static void dev_watchdog_up(struct net_device *dev)
 13.2766 - {
 13.2767 --	spin_lock_bh(&dev->xmit_lock);
 13.2768 -+	netif_tx_lock_bh(dev);
 13.2769 - 	__netdev_watchdog_up(dev);
 13.2770 --	spin_unlock_bh(&dev->xmit_lock);
 13.2771 -+	netif_tx_unlock_bh(dev);
 13.2772 - }
 13.2773 - 
 13.2774 - static void dev_watchdog_down(struct net_device *dev)
 13.2775 - {
 13.2776 --	spin_lock_bh(&dev->xmit_lock);
 13.2777 -+	netif_tx_lock_bh(dev);
 13.2778 - 	if (del_timer(&dev->watchdog_timer))
 13.2779 - 		__dev_put(dev);
 13.2780 --	spin_unlock_bh(&dev->xmit_lock);
 13.2781 -+	netif_tx_unlock_bh(dev);
 13.2782 - }
 13.2783 - 
 13.2784 - void netif_carrier_on(struct net_device *dev)
 13.2785 -@@ -577,10 +589,17 @@ void dev_deactivate(struct net_device *d
 13.2786 - 
 13.2787 - 	dev_watchdog_down(dev);
 13.2788 - 
 13.2789 --	while (test_bit(__LINK_STATE_SCHED, &dev->state))
 13.2790 -+	/* Wait for outstanding dev_queue_xmit calls. */
 13.2791 -+	synchronize_rcu();
 13.2792 -+
 13.2793 -+	/* Wait for outstanding qdisc_run calls. */
 13.2794 -+	while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
 13.2795 - 		yield();
 13.2796 - 
 13.2797 --	spin_unlock_wait(&dev->xmit_lock);
 13.2798 -+	if (dev->gso_skb) {
 13.2799 -+		kfree_skb(dev->gso_skb);
 13.2800 -+		dev->gso_skb = NULL;
 13.2801 -+	}
 13.2802 - }
 13.2803 - 
 13.2804 - void dev_init_scheduler(struct net_device *dev)
 13.2805 -@@ -622,6 +641,5 @@ EXPORT_SYMBOL(qdisc_create_dflt);
 13.2806 - EXPORT_SYMBOL(qdisc_alloc);
 13.2807 - EXPORT_SYMBOL(qdisc_destroy);
 13.2808 - EXPORT_SYMBOL(qdisc_reset);
 13.2809 --EXPORT_SYMBOL(qdisc_restart);
 13.2810 - EXPORT_SYMBOL(qdisc_lock_tree);
 13.2811 - EXPORT_SYMBOL(qdisc_unlock_tree);
 13.2812 -diff -pruN ../orig-linux-2.6.16.29/net/sched/sch_teql.c ./net/sched/sch_teql.c
 13.2813 ---- ../orig-linux-2.6.16.29/net/sched/sch_teql.c	2006-09-12 19:02:10.000000000 +0100
 13.2814 -+++ ./net/sched/sch_teql.c	2006-09-19 13:59:20.000000000 +0100
 13.2815 -@@ -302,20 +302,17 @@ restart:
 13.2816 - 
 13.2817 - 		switch (teql_resolve(skb, skb_res, slave)) {
 13.2818 - 		case 0:
 13.2819 --			if (spin_trylock(&slave->xmit_lock)) {
 13.2820 --				slave->xmit_lock_owner = smp_processor_id();
 13.2821 -+			if (netif_tx_trylock(slave)) {
 13.2822 - 				if (!netif_queue_stopped(slave) &&
 13.2823 - 				    slave->hard_start_xmit(skb, slave) == 0) {
 13.2824 --					slave->xmit_lock_owner = -1;
 13.2825 --					spin_unlock(&slave->xmit_lock);
 13.2826 -+					netif_tx_unlock(slave);
 13.2827 - 					master->slaves = NEXT_SLAVE(q);
 13.2828 - 					netif_wake_queue(dev);
 13.2829 - 					master->stats.tx_packets++;
 13.2830 - 					master->stats.tx_bytes += len;
 13.2831 - 					return 0;
 13.2832 - 				}
 13.2833 --				slave->xmit_lock_owner = -1;
 13.2834 --				spin_unlock(&slave->xmit_lock);
 13.2835 -+				netif_tx_unlock(slave);
 13.2836 - 			}
 13.2837 - 			if (netif_queue_stopped(dev))
 13.2838 - 				busy = 1;
    14.1 --- a/patches/linux-2.6.16.31/net-gso-1-check-dodgy.patch	Mon Nov 27 13:50:02 2006 +0000
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,27 +0,0 @@
    14.4 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/tcp.c ./net/ipv4/tcp.c
    14.5 ---- ../orig-linux-2.6.16.29/net/ipv4/tcp.c	2006-09-19 13:59:20.000000000 +0100
    14.6 -+++ ./net/ipv4/tcp.c	2006-09-19 13:59:42.000000000 +0100
    14.7 -@@ -2042,13 +2042,19 @@ struct sk_buff *tcp_tso_segment(struct s
    14.8 - 	if (!pskb_may_pull(skb, thlen))
    14.9 - 		goto out;
   14.10 - 
   14.11 --	segs = NULL;
   14.12 --	if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST))
   14.13 --		goto out;
   14.14 --
   14.15 - 	oldlen = (u16)~skb->len;
   14.16 - 	__skb_pull(skb, thlen);
   14.17 - 
   14.18 -+	if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
   14.19 -+		/* Packet is from an untrusted source, reset gso_segs. */
   14.20 -+		int mss = skb_shinfo(skb)->gso_size;
   14.21 -+
   14.22 -+		skb_shinfo(skb)->gso_segs = (skb->len + mss - 1) / mss;
   14.23 -+
   14.24 -+		segs = NULL;
   14.25 -+		goto out;
   14.26 -+	}
   14.27 -+
   14.28 - 	segs = skb_segment(skb, features);
   14.29 - 	if (IS_ERR(segs))
   14.30 - 		goto out;
    15.1 --- a/patches/linux-2.6.16.31/net-gso-2-checksum-fix.patch	Mon Nov 27 13:50:02 2006 +0000
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,451 +0,0 @@
    15.4 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/bnx2.c ./drivers/net/bnx2.c
    15.5 ---- ../orig-linux-2.6.16.29/drivers/net/bnx2.c	2006-09-19 13:59:20.000000000 +0100
    15.6 -+++ ./drivers/net/bnx2.c	2006-09-19 13:59:46.000000000 +0100
    15.7 -@@ -1593,7 +1593,7 @@ bnx2_tx_int(struct bnx2 *bp)
    15.8 - 		skb = tx_buf->skb;
    15.9 - #ifdef BCM_TSO 
   15.10 - 		/* partial BD completions possible with TSO packets */
   15.11 --		if (skb_shinfo(skb)->gso_size) {
   15.12 -+		if (skb_is_gso(skb)) {
   15.13 - 			u16 last_idx, last_ring_idx;
   15.14 - 
   15.15 - 			last_idx = sw_cons +
   15.16 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/chelsio/sge.c ./drivers/net/chelsio/sge.c
   15.17 ---- ../orig-linux-2.6.16.29/drivers/net/chelsio/sge.c	2006-09-19 13:59:20.000000000 +0100
   15.18 -+++ ./drivers/net/chelsio/sge.c	2006-09-19 13:59:46.000000000 +0100
   15.19 -@@ -1419,7 +1419,7 @@ int t1_start_xmit(struct sk_buff *skb, s
   15.20 - 	struct cpl_tx_pkt *cpl;
   15.21 - 
   15.22 - #ifdef NETIF_F_TSO
   15.23 --	if (skb_shinfo(skb)->gso_size) {
   15.24 -+	if (skb_is_gso(skb)) {
   15.25 - 		int eth_type;
   15.26 - 		struct cpl_tx_pkt_lso *hdr;
   15.27 - 
   15.28 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/e1000/e1000_main.c ./drivers/net/e1000/e1000_main.c
   15.29 ---- ../orig-linux-2.6.16.29/drivers/net/e1000/e1000_main.c	2006-09-19 13:59:20.000000000 +0100
   15.30 -+++ ./drivers/net/e1000/e1000_main.c	2006-09-19 13:59:46.000000000 +0100
   15.31 -@@ -2526,7 +2526,7 @@ e1000_tso(struct e1000_adapter *adapter,
   15.32 - 	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
   15.33 - 	int err;
   15.34 - 
   15.35 --	if (skb_shinfo(skb)->gso_size) {
   15.36 -+	if (skb_is_gso(skb)) {
   15.37 - 		if (skb_header_cloned(skb)) {
   15.38 - 			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
   15.39 - 			if (err)
   15.40 -@@ -2651,7 +2651,7 @@ e1000_tx_map(struct e1000_adapter *adapt
   15.41 - 		 * tso gets written back prematurely before the data is fully
   15.42 - 		 * DMAd to the controller */
   15.43 - 		if (!skb->data_len && tx_ring->last_tx_tso &&
   15.44 --				!skb_shinfo(skb)->gso_size) {
   15.45 -+		    !skb_is_gso(skb)) {
   15.46 - 			tx_ring->last_tx_tso = 0;
   15.47 - 			size -= 4;
   15.48 - 		}
   15.49 -@@ -2934,8 +2934,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
   15.50 - 
   15.51 - #ifdef NETIF_F_TSO
   15.52 - 	/* Controller Erratum workaround */
   15.53 --	if (!skb->data_len && tx_ring->last_tx_tso &&
   15.54 --		!skb_shinfo(skb)->gso_size)
   15.55 -+	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
   15.56 - 		count++;
   15.57 - #endif
   15.58 - 
   15.59 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/forcedeth.c ./drivers/net/forcedeth.c
   15.60 ---- ../orig-linux-2.6.16.29/drivers/net/forcedeth.c	2006-09-19 13:59:20.000000000 +0100
   15.61 -+++ ./drivers/net/forcedeth.c	2006-09-19 13:59:46.000000000 +0100
   15.62 -@@ -1105,7 +1105,7 @@ static int nv_start_xmit(struct sk_buff 
   15.63 - 	np->tx_skbuff[nr] = skb;
   15.64 - 
   15.65 - #ifdef NETIF_F_TSO
   15.66 --	if (skb_shinfo(skb)->gso_size)
   15.67 -+	if (skb_is_gso(skb))
   15.68 - 		tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT);
   15.69 - 	else
   15.70 - #endif
   15.71 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/ixgb/ixgb_main.c ./drivers/net/ixgb/ixgb_main.c
   15.72 ---- ../orig-linux-2.6.16.29/drivers/net/ixgb/ixgb_main.c	2006-09-19 13:59:20.000000000 +0100
   15.73 -+++ ./drivers/net/ixgb/ixgb_main.c	2006-09-19 13:59:46.000000000 +0100
   15.74 -@@ -1163,7 +1163,7 @@ ixgb_tso(struct ixgb_adapter *adapter, s
   15.75 - 	uint16_t ipcse, tucse, mss;
   15.76 - 	int err;
   15.77 - 
   15.78 --	if(likely(skb_shinfo(skb)->gso_size)) {
   15.79 -+	if (likely(skb_is_gso(skb))) {
   15.80 - 		if (skb_header_cloned(skb)) {
   15.81 - 			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
   15.82 - 			if (err)
   15.83 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/loopback.c ./drivers/net/loopback.c
   15.84 ---- ../orig-linux-2.6.16.29/drivers/net/loopback.c	2006-09-19 13:59:20.000000000 +0100
   15.85 -+++ ./drivers/net/loopback.c	2006-09-19 13:59:46.000000000 +0100
   15.86 -@@ -139,7 +139,7 @@ static int loopback_xmit(struct sk_buff 
   15.87 - #endif
   15.88 - 
   15.89 - #ifdef LOOPBACK_TSO
   15.90 --	if (skb_shinfo(skb)->gso_size) {
   15.91 -+	if (skb_is_gso(skb)) {
   15.92 - 		BUG_ON(skb->protocol != htons(ETH_P_IP));
   15.93 - 		BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP);
   15.94 - 
   15.95 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/sky2.c ./drivers/net/sky2.c
   15.96 ---- ../orig-linux-2.6.16.29/drivers/net/sky2.c	2006-09-19 13:59:20.000000000 +0100
   15.97 -+++ ./drivers/net/sky2.c	2006-09-19 13:59:46.000000000 +0100
   15.98 -@@ -1125,7 +1125,7 @@ static unsigned tx_le_req(const struct s
   15.99 - 	count = sizeof(dma_addr_t) / sizeof(u32);
  15.100 - 	count += skb_shinfo(skb)->nr_frags * count;
  15.101 - 
  15.102 --	if (skb_shinfo(skb)->gso_size)
  15.103 -+	if (skb_is_gso(skb))
  15.104 - 		++count;
  15.105 - 
  15.106 - 	if (skb->ip_summed == CHECKSUM_HW)
  15.107 -diff -pruN ../orig-linux-2.6.16.29/drivers/net/typhoon.c ./drivers/net/typhoon.c
  15.108 ---- ../orig-linux-2.6.16.29/drivers/net/typhoon.c	2006-09-19 13:59:20.000000000 +0100
  15.109 -+++ ./drivers/net/typhoon.c	2006-09-19 13:59:46.000000000 +0100
  15.110 -@@ -805,7 +805,7 @@ typhoon_start_tx(struct sk_buff *skb, st
  15.111 - 	 * If problems develop with TSO, check this first.
  15.112 - 	 */
  15.113 - 	numDesc = skb_shinfo(skb)->nr_frags + 1;
  15.114 --	if(skb_tso_size(skb))
  15.115 -+	if (skb_is_gso(skb))
  15.116 - 		numDesc++;
  15.117 - 
  15.118 - 	/* When checking for free space in the ring, we need to also
  15.119 -@@ -845,7 +845,7 @@ typhoon_start_tx(struct sk_buff *skb, st
  15.120 - 				TYPHOON_TX_PF_VLAN_TAG_SHIFT);
  15.121 - 	}
  15.122 - 
  15.123 --	if(skb_tso_size(skb)) {
  15.124 -+	if (skb_is_gso(skb)) {
  15.125 - 		first_txd->processFlags |= TYPHOON_TX_PF_TCP_SEGMENT;
  15.126 - 		first_txd->numDesc++;
  15.127 - 
  15.128 -diff -pruN ../orig-linux-2.6.16.29/drivers/s390/net/qeth_main.c ./drivers/s390/net/qeth_main.c
  15.129 ---- ../orig-linux-2.6.16.29/drivers/s390/net/qeth_main.c	2006-09-19 13:59:20.000000000 +0100
  15.130 -+++ ./drivers/s390/net/qeth_main.c	2006-09-19 13:59:46.000000000 +0100
  15.131 -@@ -4454,7 +4454,7 @@ qeth_send_packet(struct qeth_card *card,
  15.132 - 	queue = card->qdio.out_qs
  15.133 - 		[qeth_get_priority_queue(card, skb, ipv, cast_type)];
  15.134 - 
  15.135 --	if (skb_shinfo(skb)->gso_size)
  15.136 -+	if (skb_is_gso(skb))
  15.137 - 		large_send = card->options.large_send;
  15.138 - 
  15.139 - 	/*are we able to do TSO ? If so ,prepare and send it from here */
  15.140 -@@ -4501,8 +4501,7 @@ qeth_send_packet(struct qeth_card *card,
  15.141 - 		card->stats.tx_packets++;
  15.142 - 		card->stats.tx_bytes += skb->len;
  15.143 - #ifdef CONFIG_QETH_PERF_STATS
  15.144 --		if (skb_shinfo(skb)->gso_size &&
  15.145 --		   !(large_send == QETH_LARGE_SEND_NO)) {
  15.146 -+		if (skb_is_gso(skb) && !(large_send == QETH_LARGE_SEND_NO)) {
  15.147 - 			card->perf_stats.large_send_bytes += skb->len;
  15.148 - 			card->perf_stats.large_send_cnt++;
  15.149 - 		}
  15.150 -diff -pruN ../orig-linux-2.6.16.29/include/linux/netdevice.h ./include/linux/netdevice.h
  15.151 ---- ../orig-linux-2.6.16.29/include/linux/netdevice.h	2006-09-19 13:59:20.000000000 +0100
  15.152 -+++ ./include/linux/netdevice.h	2006-09-19 13:59:46.000000000 +0100
  15.153 -@@ -541,6 +541,7 @@ struct packet_type {
  15.154 - 					 struct net_device *);
  15.155 - 	struct sk_buff		*(*gso_segment)(struct sk_buff *skb,
  15.156 - 						int features);
  15.157 -+	int			(*gso_send_check)(struct sk_buff *skb);
  15.158 - 	void			*af_packet_priv;
  15.159 - 	struct list_head	list;
  15.160 - };
  15.161 -@@ -1001,14 +1002,15 @@ extern void linkwatch_run_queue(void);
  15.162 - 
  15.163 - static inline int skb_gso_ok(struct sk_buff *skb, int features)
  15.164 - {
  15.165 --	int feature = skb_shinfo(skb)->gso_size ?
  15.166 --		      skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0;
  15.167 -+	int feature = skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT;
  15.168 - 	return (features & feature) == feature;
  15.169 - }
  15.170 - 
  15.171 - static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
  15.172 - {
  15.173 --	return !skb_gso_ok(skb, dev->features);
  15.174 -+	return skb_is_gso(skb) &&
  15.175 -+	       (!skb_gso_ok(skb, dev->features) ||
  15.176 -+		unlikely(skb->ip_summed != CHECKSUM_HW));
  15.177 - }
  15.178 - 
  15.179 - #endif /* __KERNEL__ */
  15.180 -diff -pruN ../orig-linux-2.6.16.29/include/linux/skbuff.h ./include/linux/skbuff.h
  15.181 ---- ../orig-linux-2.6.16.29/include/linux/skbuff.h	2006-09-19 13:59:20.000000000 +0100
  15.182 -+++ ./include/linux/skbuff.h	2006-09-19 13:59:46.000000000 +0100
  15.183 -@@ -1403,5 +1403,10 @@ static inline void nf_bridge_get(struct 
  15.184 - static inline void nf_reset(struct sk_buff *skb) {}
  15.185 - #endif /* CONFIG_NETFILTER */
  15.186 - 
  15.187 -+static inline int skb_is_gso(const struct sk_buff *skb)
  15.188 -+{
  15.189 -+	return skb_shinfo(skb)->gso_size;
  15.190 -+}
  15.191 -+
  15.192 - #endif	/* __KERNEL__ */
  15.193 - #endif	/* _LINUX_SKBUFF_H */
  15.194 -diff -pruN ../orig-linux-2.6.16.29/include/net/protocol.h ./include/net/protocol.h
  15.195 ---- ../orig-linux-2.6.16.29/include/net/protocol.h	2006-09-19 13:59:20.000000000 +0100
  15.196 -+++ ./include/net/protocol.h	2006-09-19 13:59:46.000000000 +0100
  15.197 -@@ -37,6 +37,7 @@
  15.198 - struct net_protocol {
  15.199 - 	int			(*handler)(struct sk_buff *skb);
  15.200 - 	void			(*err_handler)(struct sk_buff *skb, u32 info);
  15.201 -+	int			(*gso_send_check)(struct sk_buff *skb);
  15.202 - 	struct sk_buff	       *(*gso_segment)(struct sk_buff *skb,
  15.203 - 					       int features);
  15.204 - 	int			no_policy;
  15.205 -diff -pruN ../orig-linux-2.6.16.29/include/net/tcp.h ./include/net/tcp.h
  15.206 ---- ../orig-linux-2.6.16.29/include/net/tcp.h	2006-09-19 13:59:20.000000000 +0100
  15.207 -+++ ./include/net/tcp.h	2006-09-19 13:59:46.000000000 +0100
  15.208 -@@ -1063,6 +1063,7 @@ extern struct request_sock_ops tcp_reque
  15.209 - 
  15.210 - extern int tcp_v4_destroy_sock(struct sock *sk);
  15.211 - 
  15.212 -+extern int tcp_v4_gso_send_check(struct sk_buff *skb);
  15.213 - extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features);
  15.214 - 
  15.215 - #ifdef CONFIG_PROC_FS
  15.216 -diff -pruN ../orig-linux-2.6.16.29/net/bridge/br_forward.c ./net/bridge/br_forward.c
  15.217 ---- ../orig-linux-2.6.16.29/net/bridge/br_forward.c	2006-09-19 13:59:20.000000000 +0100
  15.218 -+++ ./net/bridge/br_forward.c	2006-09-19 13:59:46.000000000 +0100
  15.219 -@@ -32,7 +32,7 @@ static inline int should_deliver(const s
  15.220 - int br_dev_queue_push_xmit(struct sk_buff *skb)
  15.221 - {
  15.222 - 	/* drop mtu oversized packets except tso */
  15.223 --	if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->gso_size)
  15.224 -+	if (skb->len > skb->dev->mtu && !skb_is_gso(skb))
  15.225 - 		kfree_skb(skb);
  15.226 - 	else {
  15.227 - #ifdef CONFIG_BRIDGE_NETFILTER
  15.228 -diff -pruN ../orig-linux-2.6.16.29/net/bridge/br_netfilter.c ./net/bridge/br_netfilter.c
  15.229 ---- ../orig-linux-2.6.16.29/net/bridge/br_netfilter.c	2006-09-19 13:59:20.000000000 +0100
  15.230 -+++ ./net/bridge/br_netfilter.c	2006-09-19 13:59:46.000000000 +0100
  15.231 -@@ -743,7 +743,7 @@ static int br_nf_dev_queue_xmit(struct s
  15.232 - {
  15.233 - 	if (skb->protocol == htons(ETH_P_IP) &&
  15.234 - 	    skb->len > skb->dev->mtu &&
  15.235 --	    !skb_shinfo(skb)->gso_size)
  15.236 -+	    !skb_is_gso(skb))
  15.237 - 		return ip_fragment(skb, br_dev_queue_push_xmit);
  15.238 - 	else
  15.239 - 		return br_dev_queue_push_xmit(skb);
  15.240 -diff -pruN ../orig-linux-2.6.16.29/net/core/dev.c ./net/core/dev.c
  15.241 ---- ../orig-linux-2.6.16.29/net/core/dev.c	2006-09-19 13:59:20.000000000 +0100
  15.242 -+++ ./net/core/dev.c	2006-09-19 13:59:46.000000000 +0100
  15.243 -@@ -1083,9 +1083,17 @@ int skb_checksum_help(struct sk_buff *sk
  15.244 - 	unsigned int csum;
  15.245 - 	int ret = 0, offset = skb->h.raw - skb->data;
  15.246 - 
  15.247 --	if (inward) {
  15.248 --		skb->ip_summed = CHECKSUM_NONE;
  15.249 --		goto out;
  15.250 -+	if (inward)
  15.251 -+		goto out_set_summed;
  15.252 -+
  15.253 -+	if (unlikely(skb_shinfo(skb)->gso_size)) {
  15.254 -+		static int warned;
  15.255 -+
  15.256 -+		WARN_ON(!warned);
  15.257 -+		warned = 1;
  15.258 -+
  15.259 -+		/* Let GSO fix up the checksum. */
  15.260 -+		goto out_set_summed;
  15.261 - 	}
  15.262 - 
  15.263 - 	if (skb_cloned(skb)) {
  15.264 -@@ -1102,6 +1110,8 @@ int skb_checksum_help(struct sk_buff *sk
  15.265 - 	BUG_ON(skb->csum + 2 > offset);
  15.266 - 
  15.267 - 	*(u16*)(skb->h.raw + skb->csum) = csum_fold(csum);
  15.268 -+
  15.269 -+out_set_summed:
  15.270 - 	skb->ip_summed = CHECKSUM_NONE;
  15.271 - out:	
  15.272 - 	return ret;
  15.273 -@@ -1122,17 +1132,35 @@ struct sk_buff *skb_gso_segment(struct s
  15.274 - 	struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
  15.275 - 	struct packet_type *ptype;
  15.276 - 	int type = skb->protocol;
  15.277 -+	int err;
  15.278 - 
  15.279 - 	BUG_ON(skb_shinfo(skb)->frag_list);
  15.280 --	BUG_ON(skb->ip_summed != CHECKSUM_HW);
  15.281 - 
  15.282 - 	skb->mac.raw = skb->data;
  15.283 - 	skb->mac_len = skb->nh.raw - skb->data;
  15.284 - 	__skb_pull(skb, skb->mac_len);
  15.285 - 
  15.286 -+	if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
  15.287 -+		static int warned;
  15.288 -+
  15.289 -+		WARN_ON(!warned);
  15.290 -+		warned = 1;
  15.291 -+
  15.292 -+		if (skb_header_cloned(skb) &&
  15.293 -+		    (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
  15.294 -+			return ERR_PTR(err);
  15.295 -+	}
  15.296 -+
  15.297 - 	rcu_read_lock();
  15.298 - 	list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
  15.299 - 		if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
  15.300 -+			if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
  15.301 -+				err = ptype->gso_send_check(skb);
  15.302 -+				segs = ERR_PTR(err);
  15.303 -+				if (err || skb_gso_ok(skb, features))
  15.304 -+					break;
  15.305 -+				__skb_push(skb, skb->data - skb->nh.raw);
  15.306 -+			}
  15.307 - 			segs = ptype->gso_segment(skb, features);
  15.308 - 			break;
  15.309 - 		}
  15.310 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/af_inet.c ./net/ipv4/af_inet.c
  15.311 ---- ../orig-linux-2.6.16.29/net/ipv4/af_inet.c	2006-09-19 13:59:20.000000000 +0100
  15.312 -+++ ./net/ipv4/af_inet.c	2006-09-19 13:59:46.000000000 +0100
  15.313 -@@ -1085,6 +1085,40 @@ int inet_sk_rebuild_header(struct sock *
  15.314 - 
  15.315 - EXPORT_SYMBOL(inet_sk_rebuild_header);
  15.316 - 
  15.317 -+static int inet_gso_send_check(struct sk_buff *skb)
  15.318 -+{
  15.319 -+	struct iphdr *iph;
  15.320 -+	struct net_protocol *ops;
  15.321 -+	int proto;
  15.322 -+	int ihl;
  15.323 -+	int err = -EINVAL;
  15.324 -+
  15.325 -+	if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
  15.326 -+		goto out;
  15.327 -+
  15.328 -+	iph = skb->nh.iph;
  15.329 -+	ihl = iph->ihl * 4;
  15.330 -+	if (ihl < sizeof(*iph))
  15.331 -+		goto out;
  15.332 -+
  15.333 -+	if (unlikely(!pskb_may_pull(skb, ihl)))
  15.334 -+		goto out;
  15.335 -+
  15.336 -+	skb->h.raw = __skb_pull(skb, ihl);
  15.337 -+	iph = skb->nh.iph;
  15.338 -+	proto = iph->protocol & (MAX_INET_PROTOS - 1);
  15.339 -+	err = -EPROTONOSUPPORT;
  15.340 -+
  15.341 -+	rcu_read_lock();
  15.342 -+	ops = rcu_dereference(inet_protos[proto]);
  15.343 -+	if (likely(ops && ops->gso_send_check))
  15.344 -+		err = ops->gso_send_check(skb);
  15.345 -+	rcu_read_unlock();
  15.346 -+
  15.347 -+out:
  15.348 -+	return err;
  15.349 -+}
  15.350 -+
  15.351 - static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
  15.352 - {
  15.353 - 	struct sk_buff *segs = ERR_PTR(-EINVAL);
  15.354 -@@ -1142,6 +1176,7 @@ static struct net_protocol igmp_protocol
  15.355 - static struct net_protocol tcp_protocol = {
  15.356 - 	.handler =	tcp_v4_rcv,
  15.357 - 	.err_handler =	tcp_v4_err,
  15.358 -+	.gso_send_check = tcp_v4_gso_send_check,
  15.359 - 	.gso_segment =	tcp_tso_segment,
  15.360 - 	.no_policy =	1,
  15.361 - };
  15.362 -@@ -1188,6 +1223,7 @@ static int ipv4_proc_init(void);
  15.363 - static struct packet_type ip_packet_type = {
  15.364 - 	.type = __constant_htons(ETH_P_IP),
  15.365 - 	.func = ip_rcv,
  15.366 -+	.gso_send_check = inet_gso_send_check,
  15.367 - 	.gso_segment = inet_gso_segment,
  15.368 - };
  15.369 - 
  15.370 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/ip_output.c ./net/ipv4/ip_output.c
  15.371 ---- ../orig-linux-2.6.16.29/net/ipv4/ip_output.c	2006-09-19 13:59:20.000000000 +0100
  15.372 -+++ ./net/ipv4/ip_output.c	2006-09-19 13:59:46.000000000 +0100
  15.373 -@@ -210,7 +210,7 @@ static inline int ip_finish_output(struc
  15.374 - 		return dst_output(skb);
  15.375 - 	}
  15.376 - #endif
  15.377 --	if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size)
  15.378 -+	if (skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb))
  15.379 - 		return ip_fragment(skb, ip_finish_output2);
  15.380 - 	else
  15.381 - 		return ip_finish_output2(skb);
  15.382 -@@ -1095,7 +1095,7 @@ ssize_t	ip_append_page(struct sock *sk, 
  15.383 - 	while (size > 0) {
  15.384 - 		int i;
  15.385 - 
  15.386 --		if (skb_shinfo(skb)->gso_size)
  15.387 -+		if (skb_is_gso(skb))
  15.388 - 			len = size;
  15.389 - 		else {
  15.390 - 
  15.391 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/tcp_ipv4.c ./net/ipv4/tcp_ipv4.c
  15.392 ---- ../orig-linux-2.6.16.29/net/ipv4/tcp_ipv4.c	2006-09-12 19:02:10.000000000 +0100
  15.393 -+++ ./net/ipv4/tcp_ipv4.c	2006-09-19 13:59:46.000000000 +0100
  15.394 -@@ -495,6 +495,24 @@ void tcp_v4_send_check(struct sock *sk, 
  15.395 - 	}
  15.396 - }
  15.397 - 
  15.398 -+int tcp_v4_gso_send_check(struct sk_buff *skb)
  15.399 -+{
  15.400 -+	struct iphdr *iph;
  15.401 -+	struct tcphdr *th;
  15.402 -+
  15.403 -+	if (!pskb_may_pull(skb, sizeof(*th)))
  15.404 -+		return -EINVAL;
  15.405 -+
  15.406 -+	iph = skb->nh.iph;
  15.407 -+	th = skb->h.th;
  15.408 -+
  15.409 -+	th->check = 0;
  15.410 -+	th->check = ~tcp_v4_check(th, skb->len, iph->saddr, iph->daddr, 0);
  15.411 -+	skb->csum = offsetof(struct tcphdr, check);
  15.412 -+	skb->ip_summed = CHECKSUM_HW;
  15.413 -+	return 0;
  15.414 -+}
  15.415 -+
  15.416 - /*
  15.417 -  *	This routine will send an RST to the other tcp.
  15.418 -  *
  15.419 -diff -pruN ../orig-linux-2.6.16.29/net/ipv4/xfrm4_output.c ./net/ipv4/xfrm4_output.c
  15.420 ---- ../orig-linux-2.6.16.29/net/ipv4/xfrm4_output.c	2006-09-19 13:59:20.000000000 +0100
  15.421 -+++ ./net/ipv4/xfrm4_output.c	2006-09-19 13:59:46.000000000 +0100
  15.422 -@@ -195,7 +195,7 @@ static int xfrm4_output_finish(struct sk
  15.423 - 	}
  15.424 - #endif
  15.425 - 
  15.426 --	if (!skb_shinfo(skb)->gso_size)
  15.427 -+	if (!skb_is_gso(skb))
  15.428 - 		return xfrm4_output_finish2(skb);
  15.429 - 
  15.430 - 	skb->protocol = htons(ETH_P_IP);
  15.431 -diff -pruN ../orig-linux-2.6.16.29/net/ipv6/ip6_output.c ./net/ipv6/ip6_output.c
  15.432 ---- ../orig-linux-2.6.16.29/net/ipv6/ip6_output.c	2006-09-19 13:59:20.000000000 +0100
  15.433 -+++ ./net/ipv6/ip6_output.c	2006-09-19 13:59:46.000000000 +0100
  15.434 -@@ -147,7 +147,7 @@ static int ip6_output2(struct sk_buff *s
  15.435 - 
  15.436 - int ip6_output(struct sk_buff *skb)
  15.437 - {
  15.438 --	if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->gso_size) ||
  15.439 -+	if ((skb->len > dst_mtu(skb->dst) && !skb_is_gso(skb)) ||
  15.440 - 				dst_allfrag(skb->dst))
  15.441 - 		return ip6_fragment(skb, ip6_output2);
  15.442 - 	else
  15.443 -diff -pruN ../orig-linux-2.6.16.29/net/ipv6/xfrm6_output.c ./net/ipv6/xfrm6_output.c
  15.444 ---- ../orig-linux-2.6.16.29/net/ipv6/xfrm6_output.c	2006-09-19 13:59:20.000000000 +0100
  15.445 -+++ ./net/ipv6/xfrm6_output.c	2006-09-19 13:59:46.000000000 +0100
  15.446 -@@ -179,7 +179,7 @@ static int xfrm6_output_finish(struct sk
  15.447 - {
  15.448 - 	struct sk_buff *segs;
  15.449 - 
  15.450 --	if (!skb_shinfo(skb)->gso_size)
  15.451 -+	if (!skb_is_gso(skb))
  15.452 - 		return xfrm6_output_finish2(skb);
  15.453 - 
  15.454 - 	skb->protocol = htons(ETH_P_IP);
    16.1 --- a/patches/linux-2.6.16.31/net-gso-3-fix-errorcheck.patch	Mon Nov 27 13:50:02 2006 +0000
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,17 +0,0 @@
    16.4 -diff -pruN ../orig-linux-2.6.16.29/include/linux/netdevice.h ./include/linux/netdevice.h
    16.5 ---- ../orig-linux-2.6.16.29/include/linux/netdevice.h	2006-09-19 13:59:46.000000000 +0100
    16.6 -+++ ./include/linux/netdevice.h	2006-09-19 14:05:28.000000000 +0100
    16.7 -@@ -930,10 +930,10 @@ static inline void netif_tx_lock_bh(stru
    16.8 - 
    16.9 - static inline int netif_tx_trylock(struct net_device *dev)
   16.10 - {
   16.11 --	int err = spin_trylock(&dev->_xmit_lock);
   16.12 --	if (!err)
   16.13 -+	int ok = spin_trylock(&dev->_xmit_lock);
   16.14 -+	if (likely(ok))
   16.15 - 		dev->xmit_lock_owner = smp_processor_id();
   16.16 --	return err;
   16.17 -+	return ok;
   16.18 - }
   16.19 - 
   16.20 - static inline void netif_tx_unlock(struct net_device *dev)
    17.1 --- a/patches/linux-2.6.16.31/net-gso-4-kill-warnon.patch	Mon Nov 27 13:50:02 2006 +0000
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,27 +0,0 @@
    17.4 -diff -pruN ../orig-linux-2.6.16.29/net/core/dev.c ./net/core/dev.c
    17.5 ---- ../orig-linux-2.6.16.29/net/core/dev.c	2006-09-19 13:59:46.000000000 +0100
    17.6 -+++ ./net/core/dev.c	2006-09-19 14:05:32.000000000 +0100
    17.7 -@@ -1087,11 +1087,6 @@ int skb_checksum_help(struct sk_buff *sk
    17.8 - 		goto out_set_summed;
    17.9 - 
   17.10 - 	if (unlikely(skb_shinfo(skb)->gso_size)) {
   17.11 --		static int warned;
   17.12 --
   17.13 --		WARN_ON(!warned);
   17.14 --		warned = 1;
   17.15 --
   17.16 - 		/* Let GSO fix up the checksum. */
   17.17 - 		goto out_set_summed;
   17.18 - 	}
   17.19 -@@ -1141,11 +1136,6 @@ struct sk_buff *skb_gso_segment(struct s
   17.20 - 	__skb_pull(skb, skb->mac_len);
   17.21 - 
   17.22 - 	if (unlikely(skb->ip_summed != CHECKSUM_HW)) {
   17.23 --		static int warned;
   17.24 --
   17.25 --		WARN_ON(!warned);
   17.26 --		warned = 1;
   17.27 --
   17.28 - 		if (skb_header_cloned(skb) &&
   17.29 - 		    (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
   17.30 - 			return ERR_PTR(err);
    18.1 --- a/patches/linux-2.6.16.31/net-gso-5-rcv-mss.patch	Mon Nov 27 13:50:02 2006 +0000
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,13 +0,0 @@
    18.4 -diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
    18.5 -index 104af5d..1fa1536 100644
    18.6 ---- a/net/ipv4/tcp_input.c
    18.7 -+++ b/net/ipv4/tcp_input.c
    18.8 -@@ -127,7 +127,7 @@ static void tcp_measure_rcv_mss(struct s
    18.9 - 	/* skb->len may jitter because of SACKs, even if peer
   18.10 - 	 * sends good full-sized frames.
   18.11 - 	 */
   18.12 --	len = skb->len;
   18.13 -+	len = skb_shinfo(skb)->gso_size ?: skb->len;
   18.14 - 	if (len >= icsk->icsk_ack.rcv_mss) {
   18.15 - 		icsk->icsk_ack.rcv_mss = len;
   18.16 - 	} else {
    19.1 --- a/patches/linux-2.6.16.31/pci-mmconfig-fix-from-2.6.17.patch	Mon Nov 27 13:50:02 2006 +0000
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,292 +0,0 @@
    19.4 -diff -pruN ../orig-linux-2.6.16.29/arch/i386/pci/mmconfig.c ./arch/i386/pci/mmconfig.c
    19.5 ---- ../orig-linux-2.6.16.29/arch/i386/pci/mmconfig.c	2006-09-12 19:02:10.000000000 +0100
    19.6 -+++ ./arch/i386/pci/mmconfig.c	2006-09-21 09:35:27.000000000 +0100
    19.7 -@@ -12,14 +12,22 @@
    19.8 - #include <linux/pci.h>
    19.9 - #include <linux/init.h>
   19.10 - #include <linux/acpi.h>
   19.11 -+#include <asm/e820.h>
   19.12 - #include "pci.h"
   19.13 - 
   19.14 -+/* aperture is up to 256MB but BIOS may reserve less */
   19.15 -+#define MMCONFIG_APER_MIN	(2 * 1024*1024)
   19.16 -+#define MMCONFIG_APER_MAX	(256 * 1024*1024)
   19.17 -+
   19.18 -+/* Assume systems with more busses have correct MCFG */
   19.19 -+#define MAX_CHECK_BUS 16
   19.20 -+
   19.21 - #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
   19.22 - 
   19.23 - /* The base address of the last MMCONFIG device accessed */
   19.24 - static u32 mmcfg_last_accessed_device;
   19.25 - 
   19.26 --static DECLARE_BITMAP(fallback_slots, 32);
   19.27 -+static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32);
   19.28 - 
   19.29 - /*
   19.30 -  * Functions for accessing PCI configuration space with MMCONFIG accesses
   19.31 -@@ -29,8 +37,8 @@ static u32 get_base_addr(unsigned int se
   19.32 - 	int cfg_num = -1;
   19.33 - 	struct acpi_table_mcfg_config *cfg;
   19.34 - 
   19.35 --	if (seg == 0 && bus == 0 &&
   19.36 --	    test_bit(PCI_SLOT(devfn), fallback_slots))
   19.37 -+	if (seg == 0 && bus < MAX_CHECK_BUS &&
   19.38 -+	    test_bit(PCI_SLOT(devfn) + 32*bus, fallback_slots))
   19.39 - 		return 0;
   19.40 - 
   19.41 - 	while (1) {
   19.42 -@@ -74,8 +82,10 @@ static int pci_mmcfg_read(unsigned int s
   19.43 - 	unsigned long flags;
   19.44 - 	u32 base;
   19.45 - 
   19.46 --	if (!value || (bus > 255) || (devfn > 255) || (reg > 4095))
   19.47 -+	if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
   19.48 -+		*value = -1;
   19.49 - 		return -EINVAL;
   19.50 -+	}
   19.51 - 
   19.52 - 	base = get_base_addr(seg, bus, devfn);
   19.53 - 	if (!base)
   19.54 -@@ -146,30 +156,66 @@ static struct pci_raw_ops pci_mmcfg = {
   19.55 -    Normally this can be expressed in the MCFG by not listing them
   19.56 -    and assigning suitable _SEGs, but this isn't implemented in some BIOS.
   19.57 -    Instead try to discover all devices on bus 0 that are unreachable using MM
   19.58 --   and fallback for them.
   19.59 --   We only do this for bus 0/seg 0 */
   19.60 -+   and fallback for them. */
   19.61 - static __init void unreachable_devices(void)
   19.62 - {
   19.63 --	int i;
   19.64 -+	int i, k;
   19.65 - 	unsigned long flags;
   19.66 - 
   19.67 --	for (i = 0; i < 32; i++) {
   19.68 --		u32 val1;
   19.69 --		u32 addr;
   19.70 -+	for (k = 0; k < MAX_CHECK_BUS; k++) {
   19.71 -+		for (i = 0; i < 32; i++) {
   19.72 -+			u32 val1;
   19.73 -+			u32 addr;
   19.74 -+
   19.75 -+			pci_conf1_read(0, k, PCI_DEVFN(i, 0), 0, 4, &val1);
   19.76 -+			if (val1 == 0xffffffff)
   19.77 -+				continue;
   19.78 -+
   19.79 -+			/* Locking probably not needed, but safer */
   19.80 -+			spin_lock_irqsave(&pci_config_lock, flags);
   19.81 -+			addr = get_base_addr(0, k, PCI_DEVFN(i, 0));
   19.82 -+			if (addr != 0)
   19.83 -+				pci_exp_set_dev_base(addr, k, PCI_DEVFN(i, 0));
   19.84 -+			if (addr == 0 ||
   19.85 -+			    readl((u32 __iomem *)mmcfg_virt_addr) != val1) {
   19.86 -+				set_bit(i, fallback_slots);
   19.87 -+				printk(KERN_NOTICE
   19.88 -+			"PCI: No mmconfig possible on %x:%x\n", k, i);
   19.89 -+			}
   19.90 -+			spin_unlock_irqrestore(&pci_config_lock, flags);
   19.91 -+		}
   19.92 -+	}
   19.93 -+}
   19.94 - 
   19.95 --		pci_conf1_read(0, 0, PCI_DEVFN(i, 0), 0, 4, &val1);
   19.96 --		if (val1 == 0xffffffff)
   19.97 -+/* NB. Ripped from arch/i386/kernel/setup.c for this Xen bugfix patch. */
   19.98 -+#ifdef CONFIG_XEN
   19.99 -+extern struct e820map machine_e820;
  19.100 -+#define e820 machine_e820
  19.101 -+#endif
  19.102 -+static int __init
  19.103 -+e820_all_mapped(unsigned long s, unsigned long e, unsigned type)
  19.104 -+{
  19.105 -+	u64 start = s;
  19.106 -+	u64 end = e;
  19.107 -+	int i;
  19.108 -+	for (i = 0; i < e820.nr_map; i++) {
  19.109 -+		struct e820entry *ei = &e820.map[i];
  19.110 -+		if (type && ei->type != type)
  19.111 - 			continue;
  19.112 --
  19.113 --		/* Locking probably not needed, but safer */
  19.114 --		spin_lock_irqsave(&pci_config_lock, flags);
  19.115 --		addr = get_base_addr(0, 0, PCI_DEVFN(i, 0));
  19.116 --		if (addr != 0)
  19.117 --			pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0));
  19.118 --		if (addr == 0 || readl((u32 __iomem *)mmcfg_virt_addr) != val1)
  19.119 --			set_bit(i, fallback_slots);
  19.120 --		spin_unlock_irqrestore(&pci_config_lock, flags);
  19.121 -+		/* is the region (part) in overlap with the current region ?*/
  19.122 -+		if (ei->addr >= end || ei->addr + ei->size <= start)
  19.123 -+			continue;
  19.124 -+		/* if the region is at the beginning of <start,end> we move
  19.125 -+		 * start to the end of the region since it's ok until there
  19.126 -+		 */
  19.127 -+		if (ei->addr <= start)
  19.128 -+			start = ei->addr + ei->size;
  19.129 -+		/* if start is now at or beyond end, we're done, full
  19.130 -+		 * coverage */
  19.131 -+		if (start >= end)
  19.132 -+			return 1; /* we're done */
  19.133 - 	}
  19.134 -+	return 0;
  19.135 - }
  19.136 - 
  19.137 - static int __init pci_mmcfg_init(void)
  19.138 -@@ -183,6 +229,15 @@ static int __init pci_mmcfg_init(void)
  19.139 - 	    (pci_mmcfg_config[0].base_address == 0))
  19.140 - 		goto out;
  19.141 - 
  19.142 -+	if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
  19.143 -+			pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
  19.144 -+			E820_RESERVED)) {
  19.145 -+		printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
  19.146 -+				pci_mmcfg_config[0].base_address);
  19.147 -+		printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
  19.148 -+		goto out;
  19.149 -+	}
  19.150 -+
  19.151 - 	printk(KERN_INFO "PCI: Using MMCONFIG\n");
  19.152 - 	raw_pci_ops = &pci_mmcfg;
  19.153 - 	pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
  19.154 -diff -pruN ../orig-linux-2.6.16.29/arch/x86_64/pci/mmconfig.c ./arch/x86_64/pci/mmconfig.c
  19.155 ---- ../orig-linux-2.6.16.29/arch/x86_64/pci/mmconfig.c	2006-09-12 19:02:10.000000000 +0100
  19.156 -+++ ./arch/x86_64/pci/mmconfig.c	2006-09-21 09:35:40.000000000 +0100
  19.157 -@@ -9,11 +9,19 @@
  19.158 - #include <linux/init.h>
  19.159 - #include <linux/acpi.h>
  19.160 - #include <linux/bitmap.h>
  19.161 -+#include <asm/e820.h>
  19.162 -+
  19.163 - #include "pci.h"
  19.164 - 
  19.165 --#define MMCONFIG_APER_SIZE (256*1024*1024)
  19.166 -+/* aperture is up to 256MB but BIOS may reserve less */
  19.167 -+#define MMCONFIG_APER_MIN	(2 * 1024*1024)
  19.168 -+#define MMCONFIG_APER_MAX	(256 * 1024*1024)
  19.169 -+
  19.170 -+/* Verify the first 16 busses. We assume that systems with more busses
  19.171 -+   get MCFG right. */
  19.172 -+#define MAX_CHECK_BUS 16
  19.173 - 
  19.174 --static DECLARE_BITMAP(fallback_slots, 32);
  19.175 -+static DECLARE_BITMAP(fallback_slots, 32*MAX_CHECK_BUS);
  19.176 - 
  19.177 - /* Static virtual mapping of the MMCONFIG aperture */
  19.178 - struct mmcfg_virt {
  19.179 -@@ -55,7 +63,8 @@ static char __iomem *get_virt(unsigned i
  19.180 - static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
  19.181 - {
  19.182 - 	char __iomem *addr;
  19.183 --	if (seg == 0 && bus == 0 && test_bit(PCI_SLOT(devfn), &fallback_slots))
  19.184 -+	if (seg == 0 && bus < MAX_CHECK_BUS &&
  19.185 -+		test_bit(32*bus + PCI_SLOT(devfn), fallback_slots))
  19.186 - 		return NULL;
  19.187 - 	addr = get_virt(seg, bus);
  19.188 - 	if (!addr)
  19.189 -@@ -69,8 +78,10 @@ static int pci_mmcfg_read(unsigned int s
  19.190 - 	char __iomem *addr;
  19.191 - 
  19.192 - 	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
  19.193 --	if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
  19.194 -+	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
  19.195 -+		*value = -1;
  19.196 - 		return -EINVAL;
  19.197 -+	}
  19.198 - 
  19.199 - 	addr = pci_dev_base(seg, bus, devfn);
  19.200 - 	if (!addr)
  19.201 -@@ -129,23 +140,56 @@ static struct pci_raw_ops pci_mmcfg = {
  19.202 -    Normally this can be expressed in the MCFG by not listing them
  19.203 -    and assigning suitable _SEGs, but this isn't implemented in some BIOS.
  19.204 -    Instead try to discover all devices on bus 0 that are unreachable using MM
  19.205 --   and fallback for them.
  19.206 --   We only do this for bus 0/seg 0 */
  19.207 -+   and fallback for them. */
  19.208 - static __init void unreachable_devices(void)
  19.209 - {
  19.210 --	int i;
  19.211 --	for (i = 0; i < 32; i++) {
  19.212 --		u32 val1;
  19.213 --		char __iomem *addr;
  19.214 -+	int i, k;
  19.215 -+	/* Use the max bus number from ACPI here? */
  19.216 -+	for (k = 0; k < MAX_CHECK_BUS; k++) {
  19.217 -+		for (i = 0; i < 32; i++) {
  19.218 -+			u32 val1;
  19.219 -+			char __iomem *addr;
  19.220 -+
  19.221 -+			pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1);
  19.222 -+			if (val1 == 0xffffffff)
  19.223 -+				continue;
  19.224 -+			addr = pci_dev_base(0, k, PCI_DEVFN(i, 0));
  19.225 -+			if (addr == NULL|| readl(addr) != val1) {
  19.226 -+				set_bit(i + 32*k, fallback_slots);
  19.227 -+				printk(KERN_NOTICE
  19.228 -+				"PCI: No mmconfig possible on device %x:%x\n",
  19.229 -+					k, i);
  19.230 -+			}
  19.231 -+		}
  19.232 -+	}
  19.233 -+}
  19.234 - 
  19.235 --		pci_conf1_read(0, 0, PCI_DEVFN(i,0), 0, 4, &val1);
  19.236 --		if (val1 == 0xffffffff)
  19.237 -+/* NB. Ripped from arch/x86_64/kernel/e820.c for this Xen bugfix patch. */
  19.238 -+#ifdef CONFIG_XEN
  19.239 -+extern struct e820map machine_e820;
  19.240 -+#define e820 machine_e820
  19.241 -+#endif
  19.242 -+static int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type)
  19.243 -+{
  19.244 -+	int i;
  19.245 -+	for (i = 0; i < e820.nr_map; i++) {
  19.246 -+		struct e820entry *ei = &e820.map[i];
  19.247 -+		if (type && ei->type != type)
  19.248 - 			continue;
  19.249 --		addr = pci_dev_base(0, 0, PCI_DEVFN(i, 0));
  19.250 --		if (addr == NULL|| readl(addr) != val1) {
  19.251 --			set_bit(i, &fallback_slots);
  19.252 --		}
  19.253 -+		/* is the region (part) in overlap with the current region ?*/
  19.254 -+		if (ei->addr >= end || ei->addr + ei->size <= start)
  19.255 -+			continue;
  19.256 -+
  19.257 -+		/* if the region is at the beginning of <start,end> we move
  19.258 -+		 * start to the end of the region since it's ok until there
  19.259 -+		 */
  19.260 -+		if (ei->addr <= start)
  19.261 -+			start = ei->addr + ei->size;
  19.262 -+		/* if start is now at or beyond end, we're done, full coverage */
  19.263 -+		if (start >= end)
  19.264 -+			return 1; /* we're done */
  19.265 - 	}
  19.266 -+	return 0;
  19.267 - }
  19.268 - 
  19.269 - static int __init pci_mmcfg_init(void)
  19.270 -@@ -161,6 +205,15 @@ static int __init pci_mmcfg_init(void)
  19.271 - 	    (pci_mmcfg_config[0].base_address == 0))
  19.272 - 		return 0;
  19.273 - 
  19.274 -+	if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
  19.275 -+			pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
  19.276 -+			E820_RESERVED)) {
  19.277 -+		printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
  19.278 -+				pci_mmcfg_config[0].base_address);
  19.279 -+		printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
  19.280 -+		return 0;
  19.281 -+	}
  19.282 -+
  19.283 - 	/* RED-PEN i386 doesn't do _nocache right now */
  19.284 - 	pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
  19.285 - 	if (pci_mmcfg_virt == NULL) {
  19.286 -@@ -169,7 +222,8 @@ static int __init pci_mmcfg_init(void)
  19.287 - 	}
  19.288 - 	for (i = 0; i < pci_mmcfg_config_num; ++i) {
  19.289 - 		pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
  19.290 --		pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE);
  19.291 -+		pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address,
  19.292 -+							 MMCONFIG_APER_MAX);
  19.293 - 		if (!pci_mmcfg_virt[i].virt) {
  19.294 - 			printk("PCI: Cannot map mmconfig aperture for segment %d\n",
  19.295 - 			       pci_mmcfg_config[i].pci_segment_group_number);
    20.1 --- a/patches/linux-2.6.16.31/pmd-shared.patch	Mon Nov 27 13:50:02 2006 +0000
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,111 +0,0 @@
    20.4 -diff -pruN ../orig-linux-2.6.16.29/arch/i386/mm/pageattr.c ./arch/i386/mm/pageattr.c
    20.5 ---- ../orig-linux-2.6.16.29/arch/i386/mm/pageattr.c	2006-09-12 19:02:10.000000000 +0100
    20.6 -+++ ./arch/i386/mm/pageattr.c	2006-09-19 14:05:35.000000000 +0100
    20.7 -@@ -78,7 +78,7 @@ static void set_pmd_pte(pte_t *kpte, uns
    20.8 - 	unsigned long flags;
    20.9 - 
   20.10 - 	set_pte_atomic(kpte, pte); 	/* change init_mm */
   20.11 --	if (PTRS_PER_PMD > 1)
   20.12 -+	if (HAVE_SHARED_KERNEL_PMD)
   20.13 - 		return;
   20.14 - 
   20.15 - 	spin_lock_irqsave(&pgd_lock, flags);
   20.16 -diff -pruN ../orig-linux-2.6.16.29/arch/i386/mm/pgtable.c ./arch/i386/mm/pgtable.c
   20.17 ---- ../orig-linux-2.6.16.29/arch/i386/mm/pgtable.c	2006-09-12 19:02:10.000000000 +0100
   20.18 -+++ ./arch/i386/mm/pgtable.c	2006-09-19 14:05:35.000000000 +0100
   20.19 -@@ -215,9 +215,10 @@ void pgd_ctor(void *pgd, kmem_cache_t *c
   20.20 - 		spin_lock_irqsave(&pgd_lock, flags);
   20.21 - 	}
   20.22 - 
   20.23 --	clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
   20.24 --			swapper_pg_dir + USER_PTRS_PER_PGD,
   20.25 --			KERNEL_PGD_PTRS);
   20.26 -+	if (PTRS_PER_PMD == 1 || HAVE_SHARED_KERNEL_PMD)
   20.27 -+		clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD,
   20.28 -+				swapper_pg_dir + USER_PTRS_PER_PGD,
   20.29 -+				KERNEL_PGD_PTRS);
   20.30 - 	if (PTRS_PER_PMD > 1)
   20.31 - 		return;
   20.32 - 
   20.33 -@@ -249,6 +250,30 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
   20.34 - 			goto out_oom;
   20.35 - 		set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
   20.36 - 	}
   20.37 -+
   20.38 -+	if (!HAVE_SHARED_KERNEL_PMD) {
   20.39 -+		unsigned long flags;
   20.40 -+
   20.41 -+		for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
   20.42 -+			pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
   20.43 -+			if (!pmd)
   20.44 -+				goto out_oom;
   20.45 -+			set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(1 + __pa(pmd)));
   20.46 -+		}
   20.47 -+
   20.48 -+		spin_lock_irqsave(&pgd_lock, flags);
   20.49 -+		for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
   20.50 -+			unsigned long v = (unsigned long)i << PGDIR_SHIFT;
   20.51 -+			pgd_t *kpgd = pgd_offset_k(v);
   20.52 -+			pud_t *kpud = pud_offset(kpgd, v);
   20.53 -+			pmd_t *kpmd = pmd_offset(kpud, v);
   20.54 -+			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
   20.55 -+			memcpy(pmd, kpmd, PAGE_SIZE);
   20.56 -+		}
   20.57 -+		pgd_list_add(pgd);
   20.58 -+		spin_unlock_irqrestore(&pgd_lock, flags);
   20.59 -+	}
   20.60 -+
   20.61 - 	return pgd;
   20.62 - 
   20.63 - out_oom:
   20.64 -@@ -263,9 +288,23 @@ void pgd_free(pgd_t *pgd)
   20.65 - 	int i;
   20.66 - 
   20.67 - 	/* in the PAE case user pgd entries are overwritten before usage */
   20.68 --	if (PTRS_PER_PMD > 1)
   20.69 --		for (i = 0; i < USER_PTRS_PER_PGD; ++i)
   20.70 --			kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1));
   20.71 -+	if (PTRS_PER_PMD > 1) {
   20.72 -+		for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
   20.73 -+			pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
   20.74 -+			kmem_cache_free(pmd_cache, pmd);
   20.75 -+		}
   20.76 -+		if (!HAVE_SHARED_KERNEL_PMD) {
   20.77 -+			unsigned long flags;
   20.78 -+			spin_lock_irqsave(&pgd_lock, flags);
   20.79 -+			pgd_list_del(pgd);
   20.80 -+			spin_unlock_irqrestore(&pgd_lock, flags);
   20.81 -+			for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) {
   20.82 -+				pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
   20.83 -+				memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
   20.84 -+				kmem_cache_free(pmd_cache, pmd);
   20.85 -+			}
   20.86 -+		}
   20.87 -+	}
   20.88 - 	/* in the non-PAE case, free_pgtables() clears user pgd entries */
   20.89 - 	kmem_cache_free(pgd_cache, pgd);
   20.90 - }
   20.91 -diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/pgtable-2level-defs.h ./include/asm-i386/pgtable-2level-defs.h
   20.92 ---- ../orig-linux-2.6.16.29/include/asm-i386/pgtable-2level-defs.h	2006-09-12 19:02:10.000000000 +0100
   20.93 -+++ ./include/asm-i386/pgtable-2level-defs.h	2006-09-19 14:05:35.000000000 +0100
   20.94 -@@ -1,6 +1,8 @@
   20.95 - #ifndef _I386_PGTABLE_2LEVEL_DEFS_H
   20.96 - #define _I386_PGTABLE_2LEVEL_DEFS_H
   20.97 - 
   20.98 -+#define HAVE_SHARED_KERNEL_PMD 0
   20.99 -+
  20.100 - /*
  20.101 -  * traditional i386 two-level paging structure:
  20.102 -  */
  20.103 -diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/pgtable-3level-defs.h ./include/asm-i386/pgtable-3level-defs.h
  20.104 ---- ../orig-linux-2.6.16.29/include/asm-i386/pgtable-3level-defs.h	2006-09-12 19:02:10.000000000 +0100
  20.105 -+++ ./include/asm-i386/pgtable-3level-defs.h	2006-09-19 14:05:35.000000000 +0100
  20.106 -@@ -1,6 +1,8 @@
  20.107 - #ifndef _I386_PGTABLE_3LEVEL_DEFS_H
  20.108 - #define _I386_PGTABLE_3LEVEL_DEFS_H
  20.109 - 
  20.110 -+#define HAVE_SHARED_KERNEL_PMD 1
  20.111 -+
  20.112 - /*
  20.113 -  * PGDIR_SHIFT determines what a top-level page table entry can map
  20.114 -  */
    21.1 --- a/patches/linux-2.6.16.31/rcu_needs_cpu.patch	Mon Nov 27 13:50:02 2006 +0000
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,35 +0,0 @@
    21.4 -diff -pruN ../orig-linux-2.6.16.29/include/linux/rcupdate.h ./include/linux/rcupdate.h
    21.5 ---- ../orig-linux-2.6.16.29/include/linux/rcupdate.h	2006-09-12 19:02:10.000000000 +0100
    21.6 -+++ ./include/linux/rcupdate.h	2006-09-19 14:05:39.000000000 +0100
    21.7 -@@ -134,6 +134,7 @@ static inline void rcu_bh_qsctr_inc(int 
    21.8 - }
    21.9 - 
   21.10 - extern int rcu_pending(int cpu);
   21.11 -+extern int rcu_needs_cpu(int cpu);
   21.12 - 
   21.13 - /**
   21.14 -  * rcu_read_lock - mark the beginning of an RCU read-side critical section.
   21.15 -diff -pruN ../orig-linux-2.6.16.29/kernel/rcupdate.c ./kernel/rcupdate.c
   21.16 ---- ../orig-linux-2.6.16.29/kernel/rcupdate.c	2006-09-12 19:02:10.000000000 +0100
   21.17 -+++ ./kernel/rcupdate.c	2006-09-19 14:05:39.000000000 +0100
   21.18 -@@ -485,6 +485,20 @@ int rcu_pending(int cpu)
   21.19 - 		__rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu));
   21.20 - }
   21.21 - 
   21.22 -+/*
   21.23 -+ * Check to see if any future RCU-related work will need to be done
   21.24 -+ * by the current CPU, even if none need be done immediately, returning
   21.25 -+ * 1 if so.  This function is part of the RCU implementation; it is -not-
   21.26 -+ * an exported member of the RCU API.
   21.27 -+ */
   21.28 -+int rcu_needs_cpu(int cpu)
   21.29 -+{
   21.30 -+	struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
   21.31 -+	struct rcu_data *rdp_bh = &per_cpu(rcu_bh_data, cpu);
   21.32 -+
   21.33 -+	return (!!rdp->curlist || !!rdp_bh->curlist || rcu_pending(cpu));
   21.34 -+}
   21.35 -+
   21.36 - void rcu_check_callbacks(int cpu, int user)
   21.37 - {
   21.38 - 	if (user || 
    22.1 --- a/patches/linux-2.6.16.31/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch	Mon Nov 27 13:50:02 2006 +0000
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,30 +0,0 @@
    22.4 -diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/entry.S ./arch/i386/kernel/entry.S
    22.5 ---- ../orig-linux-2.6.16.29/arch/i386/kernel/entry.S	2006-09-12 19:02:10.000000000 +0100
    22.6 -+++ ./arch/i386/kernel/entry.S	2006-09-19 14:05:44.000000000 +0100
    22.7 -@@ -177,7 +177,7 @@ need_resched:
    22.8 - 
    22.9 - 	# sysenter call handler stub
   22.10 - ENTRY(sysenter_entry)
   22.11 --	movl TSS_sysenter_esp0(%esp),%esp
   22.12 -+	movl SYSENTER_stack_esp0(%esp),%esp
   22.13 - sysenter_past_esp:
   22.14 - 	sti
   22.15 - 	pushl $(__USER_DS)
   22.16 -@@ -492,7 +492,7 @@ device_not_available_emulate:
   22.17 -  * that sets up the real kernel stack. Check here, since we can't
   22.18 -  * allow the wrong stack to be used.
   22.19 -  *
   22.20 -- * "TSS_sysenter_esp0+12" is because the NMI/debug handler will have
   22.21 -+ * "SYSENTER_stack_esp0+12" is because the NMI/debug handler will have
   22.22 -  * already pushed 3 words if it hits on the sysenter instruction:
   22.23 -  * eflags, cs and eip.
   22.24 -  *
   22.25 -@@ -504,7 +504,7 @@ device_not_available_emulate:
   22.26 - 	cmpw $__KERNEL_CS,4(%esp);		\
   22.27 - 	jne ok;					\
   22.28 - label:						\
   22.29 --	movl TSS_sysenter_esp0+offset(%esp),%esp;	\
   22.30 -+	movl SYSENTER_stack_esp0+offset(%esp),%esp;	\
   22.31 - 	pushfl;					\
   22.32 - 	pushl $__KERNEL_CS;			\
   22.33 - 	pushl $sysenter_past_esp
    23.1 --- a/patches/linux-2.6.16.31/series	Mon Nov 27 13:50:02 2006 +0000
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,25 +0,0 @@
    23.4 -blktap-aio-16_03_06.patch
    23.5 -device_bind.patch
    23.6 -fix-hz-suspend.patch
    23.7 -fix-ide-cd-pio-mode.patch
    23.8 -i386-mach-io-check-nmi.patch
    23.9 -ipv6-no-autoconf.patch
   23.10 -net-csum.patch
   23.11 -net-gso-0-base.patch
   23.12 -net-gso-1-check-dodgy.patch
   23.13 -net-gso-2-checksum-fix.patch
   23.14 -net-gso-3-fix-errorcheck.patch
   23.15 -net-gso-4-kill-warnon.patch
   23.16 -net-gso-5-rcv-mss.patch
   23.17 -pci-mmconfig-fix-from-2.6.17.patch
   23.18 -pmd-shared.patch
   23.19 -rcu_needs_cpu.patch
   23.20 -rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch
   23.21 -smp-alts.patch
   23.22 -tpm_plugin_2.6.17.patch
   23.23 -x86-increase-interrupt-vector-range.patch
   23.24 -xen-hotplug.patch
   23.25 -xenoprof-generic.patch
   23.26 -x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
   23.27 -x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
   23.28 -x86-elfnote-as-preprocessor-macro.patch
    24.1 --- a/patches/linux-2.6.16.31/smp-alts.patch	Mon Nov 27 13:50:02 2006 +0000
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,591 +0,0 @@
    24.4 -diff -pruN ../orig-linux-2.6.16.29/arch/i386/Kconfig ./arch/i386/Kconfig
    24.5 ---- ../orig-linux-2.6.16.29/arch/i386/Kconfig	2006-09-12 19:02:10.000000000 +0100
    24.6 -+++ ./arch/i386/Kconfig	2006-09-19 14:05:48.000000000 +0100
    24.7 -@@ -202,6 +202,19 @@ config SMP
    24.8 - 
    24.9 - 	  If you don't know what to do here, say N.
   24.10 - 
   24.11 -+config SMP_ALTERNATIVES
   24.12 -+	bool "SMP alternatives support (EXPERIMENTAL)"
   24.13 -+	depends on SMP && EXPERIMENTAL
   24.14 -+	help
   24.15 -+	  Try to reduce the overhead of running an SMP kernel on a uniprocessor
   24.16 -+	  host slightly by replacing certain key instruction sequences
   24.17 -+	  according to whether we currently have more than one CPU available.
   24.18 -+	  This should provide a noticeable boost to performance when
   24.19 -+	  running SMP kernels on UP machines, and have negligible impact
   24.20 -+	  when running on an true SMP host.
   24.21 -+
   24.22 -+          If unsure, say N.
   24.23 -+	  
   24.24 - config NR_CPUS
   24.25 - 	int "Maximum number of CPUs (2-255)"
   24.26 - 	range 2 255
   24.27 -diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/Makefile ./arch/i386/kernel/Makefile
   24.28 ---- ../orig-linux-2.6.16.29/arch/i386/kernel/Makefile	2006-09-12 19:02:10.000000000 +0100
   24.29 -+++ ./arch/i386/kernel/Makefile	2006-09-19 14:05:48.000000000 +0100
   24.30 -@@ -37,6 +37,7 @@ obj-$(CONFIG_EFI) 		+= efi.o efi_stub.o
   24.31 - obj-$(CONFIG_DOUBLEFAULT) 	+= doublefault.o
   24.32 - obj-$(CONFIG_VM86)		+= vm86.o
   24.33 - obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
   24.34 -+obj-$(CONFIG_SMP_ALTERNATIVES)  += smpalts.o
   24.35 - 
   24.36 - EXTRA_AFLAGS   := -traditional
   24.37 - 
   24.38 -diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/smpalts.c ./arch/i386/kernel/smpalts.c
   24.39 ---- ../orig-linux-2.6.16.29/arch/i386/kernel/smpalts.c	1970-01-01 01:00:00.000000000 +0100
   24.40 -+++ ./arch/i386/kernel/smpalts.c	2006-09-19 14:05:48.000000000 +0100
   24.41 -@@ -0,0 +1,85 @@
   24.42 -+#include <linux/kernel.h>
   24.43 -+#include <asm/system.h>
   24.44 -+#include <asm/smp_alt.h>
   24.45 -+#include <asm/processor.h>
   24.46 -+#include <asm/string.h>
   24.47 -+
   24.48 -+struct smp_replacement_record {
   24.49 -+	unsigned char targ_size;
   24.50 -+	unsigned char smp1_size;
   24.51 -+	unsigned char smp2_size;
   24.52 -+	unsigned char up_size;
   24.53 -+	unsigned char feature;
   24.54 -+	unsigned char data[0];
   24.55 -+};
   24.56 -+
   24.57 -+struct smp_alternative_record {
   24.58 -+	void *targ_start;
   24.59 -+	struct smp_replacement_record *repl;
   24.60 -+};
   24.61 -+
   24.62 -+extern struct smp_alternative_record __start_smp_alternatives_table,
   24.63 -+  __stop_smp_alternatives_table;
   24.64 -+extern unsigned long __init_begin, __init_end;
   24.65 -+
   24.66 -+void prepare_for_smp(void)
   24.67 -+{
   24.68 -+	struct smp_alternative_record *r;
   24.69 -+	printk(KERN_INFO "Enabling SMP...\n");
   24.70 -+	for (r = &__start_smp_alternatives_table;
   24.71 -+	     r != &__stop_smp_alternatives_table;
   24.72 -+	     r++) {
   24.73 -+		BUG_ON(r->repl->targ_size < r->repl->smp1_size);
   24.74 -+		BUG_ON(r->repl->targ_size < r->repl->smp2_size);
   24.75 -+		BUG_ON(r->repl->targ_size < r->repl->up_size);
   24.76 -+               if (system_state == SYSTEM_RUNNING &&
   24.77 -+                   r->targ_start >= (void *)&__init_begin &&
   24.78 -+                   r->targ_start < (void *)&__init_end)
   24.79 -+                       continue;
   24.80 -+		if (r->repl->feature != (unsigned char)-1 &&
   24.81 -+		    boot_cpu_has(r->repl->feature)) {
   24.82 -+			memcpy(r->targ_start,
   24.83 -+			       r->repl->data + r->repl->smp1_size,
   24.84 -+			       r->repl->smp2_size);
   24.85 -+			memset(r->targ_start + r->repl->smp2_size,
   24.86 -+			       0x90,
   24.87 -+			       r->repl->targ_size - r->repl->smp2_size);
   24.88 -+		} else {
   24.89 -+			memcpy(r->targ_start,
   24.90 -+			       r->repl->data,
   24.91 -+			       r->repl->smp1_size);
   24.92 -+			memset(r->targ_start + r->repl->smp1_size,
   24.93 -+			       0x90,
   24.94 -+			       r->repl->targ_size - r->repl->smp1_size);
   24.95 -+		}
   24.96 -+	}
   24.97 -+	/* Paranoia */
   24.98 -+	asm volatile ("jmp 1f\n1:");
   24.99 -+	mb();
  24.100 -+}
  24.101 -+
  24.102 -+void unprepare_for_smp(void)
  24.103 -+{
  24.104 -+	struct smp_alternative_record *r;
  24.105 -+	printk(KERN_INFO "Disabling SMP...\n");
  24.106 -+	for (r = &__start_smp_alternatives_table;
  24.107 -+	     r != &__stop_smp_alternatives_table;
  24.108 -+	     r++) {
  24.109 -+		BUG_ON(r->repl->targ_size < r->repl->smp1_size);
  24.110 -+		BUG_ON(r->repl->targ_size < r->repl->smp2_size);
  24.111 -+		BUG_ON(r->repl->targ_size < r->repl->up_size);
  24.112 -+               if (system_state == SYSTEM_RUNNING &&
  24.113 -+                   r->targ_start >= (void *)&__init_begin &&
  24.114 -+                   r->targ_start < (void *)&__init_end)
  24.115 -+                       continue;
  24.116 -+		memcpy(r->targ_start,
  24.117 -+		       r->repl->data + r->repl->smp1_size + r->repl->smp2_size,
  24.118 -+		       r->repl->up_size);
  24.119 -+		memset(r->targ_start + r->repl->up_size,
  24.120 -+		       0x90,
  24.121 -+		       r->repl->targ_size - r->repl->up_size);
  24.122 -+	}
  24.123 -+	/* Paranoia */
  24.124 -+	asm volatile ("jmp 1f\n1:");
  24.125 -+	mb();
  24.126 -+}
  24.127 -diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/smpboot.c ./arch/i386/kernel/smpboot.c
  24.128 ---- ../orig-linux-2.6.16.29/arch/i386/kernel/smpboot.c	2006-09-12 19:02:10.000000000 +0100
  24.129 -+++ ./arch/i386/kernel/smpboot.c	2006-09-19 14:05:48.000000000 +0100
  24.130 -@@ -1218,6 +1218,11 @@ static void __init smp_boot_cpus(unsigne
  24.131 - 		if (max_cpus <= cpucount+1)
  24.132 - 			continue;
  24.133 - 
  24.134 -+#ifdef CONFIG_SMP_ALTERNATIVES
  24.135 -+		if (kicked == 1)
  24.136 -+			prepare_for_smp();
  24.137 -+#endif
  24.138 -+
  24.139 - 		if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
  24.140 - 			printk("CPU #%d not responding - cannot use it.\n",
  24.141 - 								apicid);
  24.142 -@@ -1396,6 +1401,11 @@ int __devinit __cpu_up(unsigned int cpu)
  24.143 - 		return -EIO;
  24.144 - 	}
  24.145 - 
  24.146 -+#ifdef CONFIG_SMP_ALTERNATIVES
  24.147 -+	if (num_online_cpus() == 1)
  24.148 -+		prepare_for_smp();
  24.149 -+#endif
  24.150 -+
  24.151 - 	local_irq_enable();
  24.152 - 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
  24.153 - 	/* Unleash the CPU! */
  24.154 -diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/vmlinux.lds.S ./arch/i386/kernel/vmlinux.lds.S
  24.155 ---- ../orig-linux-2.6.16.29/arch/i386/kernel/vmlinux.lds.S	2006-09-12 19:02:10.000000000 +0100
  24.156 -+++ ./arch/i386/kernel/vmlinux.lds.S	2006-09-19 14:05:48.000000000 +0100
  24.157 -@@ -34,6 +34,13 @@ SECTIONS
  24.158 -   __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
  24.159 -   __stop___ex_table = .;
  24.160 - 
  24.161 -+  . = ALIGN(16);
  24.162 -+  __start_smp_alternatives_table = .;
  24.163 -+  __smp_alternatives : { *(__smp_alternatives) }
  24.164 -+  __stop_smp_alternatives_table = .;
  24.165 -+
  24.166 -+  __smp_replacements : { *(__smp_replacements) }
  24.167 -+
  24.168 -   RODATA
  24.169 - 
  24.170 -   /* writeable */
  24.171 -diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/atomic.h ./include/asm-i386/atomic.h
  24.172 ---- ../orig-linux-2.6.16.29/include/asm-i386/atomic.h	2006-09-12 19:02:10.000000000 +0100
  24.173 -+++ ./include/asm-i386/atomic.h	2006-09-19 14:05:48.000000000 +0100
  24.174 -@@ -4,18 +4,13 @@
  24.175 - #include <linux/config.h>
  24.176 - #include <linux/compiler.h>
  24.177 - #include <asm/processor.h>
  24.178 -+#include <asm/smp_alt.h>
  24.179 - 
  24.180 - /*
  24.181 -  * Atomic operations that C can't guarantee us.  Useful for
  24.182 -  * resource counting etc..
  24.183 -  */
  24.184 - 
  24.185 --#ifdef CONFIG_SMP
  24.186 --#define LOCK "lock ; "
  24.187 --#else
  24.188 --#define LOCK ""
  24.189 --#endif
  24.190 --
  24.191 - /*
  24.192 -  * Make sure gcc doesn't try to be clever and move things around
  24.193 -  * on us. We need to use _exactly_ the address the user gave us,
  24.194 -diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/bitops.h ./include/asm-i386/bitops.h
  24.195 ---- ../orig-linux-2.6.16.29/include/asm-i386/bitops.h	2006-09-12 19:02:10.000000000 +0100
  24.196 -+++ ./include/asm-i386/bitops.h	2006-09-19 14:05:48.000000000 +0100
  24.197 -@@ -7,6 +7,7 @@
  24.198 - 
  24.199 - #include <linux/config.h>
  24.200 - #include <linux/compiler.h>
  24.201 -+#include <asm/smp_alt.h>
  24.202 - 
  24.203 - /*
  24.204 -  * These have to be done with inline assembly: that way the bit-setting
  24.205 -@@ -16,12 +17,6 @@
  24.206 -  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  24.207 -  */
  24.208 - 
  24.209 --#ifdef CONFIG_SMP
  24.210 --#define LOCK_PREFIX "lock ; "
  24.211 --#else
  24.212 --#define LOCK_PREFIX ""
  24.213 --#endif
  24.214 --
  24.215 - #define ADDR (*(volatile long *) addr)
  24.216 - 
  24.217 - /**
  24.218 -@@ -41,7 +36,7 @@
  24.219 -  */
  24.220 - static inline void set_bit(int nr, volatile unsigned long * addr)
  24.221 - {
  24.222 --	__asm__ __volatile__( LOCK_PREFIX
  24.223 -+	__asm__ __volatile__( LOCK
  24.224 - 		"btsl %1,%0"
  24.225 - 		:"+m" (ADDR)
  24.226 - 		:"Ir" (nr));
  24.227 -@@ -76,7 +71,7 @@ static inline void __set_bit(int nr, vol
  24.228 -  */
  24.229 - static inline void clear_bit(int nr, volatile unsigned long * addr)
  24.230 - {
  24.231 --	__asm__ __volatile__( LOCK_PREFIX
  24.232 -+	__asm__ __volatile__( LOCK
  24.233 - 		"btrl %1,%0"
  24.234 - 		:"+m" (ADDR)
  24.235 - 		:"Ir" (nr));
  24.236 -@@ -121,7 +116,7 @@ static inline void __change_bit(int nr, 
  24.237 -  */
  24.238 - static inline void change_bit(int nr, volatile unsigned long * addr)
  24.239 - {
  24.240 --	__asm__ __volatile__( LOCK_PREFIX
  24.241 -+	__asm__ __volatile__( LOCK
  24.242 - 		"btcl %1,%0"
  24.243 - 		:"+m" (ADDR)
  24.244 - 		:"Ir" (nr));
  24.245 -@@ -140,7 +135,7 @@ static inline int test_and_set_bit(int n
  24.246 - {
  24.247 - 	int oldbit;
  24.248 - 
  24.249 --	__asm__ __volatile__( LOCK_PREFIX
  24.250 -+	__asm__ __volatile__( LOCK
  24.251 - 		"btsl %2,%1\n\tsbbl %0,%0"
  24.252 - 		:"=r" (oldbit),"+m" (ADDR)
  24.253 - 		:"Ir" (nr) : "memory");
  24.254 -@@ -180,7 +175,7 @@ static inline int test_and_clear_bit(int
  24.255 - {
  24.256 - 	int oldbit;
  24.257 - 
  24.258 --	__asm__ __volatile__( LOCK_PREFIX
  24.259 -+	__asm__ __volatile__( LOCK
  24.260 - 		"btrl %2,%1\n\tsbbl %0,%0"
  24.261 - 		:"=r" (oldbit),"+m" (ADDR)
  24.262 - 		:"Ir" (nr) : "memory");
  24.263 -@@ -231,7 +226,7 @@ static inline int test_and_change_bit(in
  24.264 - {
  24.265 - 	int oldbit;
  24.266 - 
  24.267 --	__asm__ __volatile__( LOCK_PREFIX
  24.268 -+	__asm__ __volatile__( LOCK
  24.269 - 		"btcl %2,%1\n\tsbbl %0,%0"
  24.270 - 		:"=r" (oldbit),"+m" (ADDR)
  24.271 - 		:"Ir" (nr) : "memory");
  24.272 -diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/futex.h ./include/asm-i386/futex.h
  24.273 ---- ../orig-linux-2.6.16.29/include/asm-i386/futex.h	2006-09-12 19:02:10.000000000 +0100
  24.274 -+++ ./include/asm-i386/futex.h	2006-09-19 14:05:48.000000000 +0100
  24.275 -@@ -28,7 +28,7 @@
  24.276 - "1:	movl	%2, %0\n\
  24.277 - 	movl	%0, %3\n"					\
  24.278 - 	insn "\n"						\
  24.279 --"2:	" LOCK_PREFIX "cmpxchgl %3, %2\n\
  24.280 -+"2:	" LOCK "cmpxchgl %3, %2\n\
  24.281 - 	jnz	1b\n\
  24.282 - 3:	.section .fixup,\"ax\"\n\
  24.283 - 4:	mov	%5, %1\n\
  24.284 -@@ -68,7 +68,7 @@ futex_atomic_op_inuser (int encoded_op, 
  24.285 - #endif
  24.286 - 		switch (op) {
  24.287 - 		case FUTEX_OP_ADD:
  24.288 --			__futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
  24.289 -+			__futex_atomic_op1(LOCK "xaddl %0, %2", ret,
  24.290 - 					   oldval, uaddr, oparg);
  24.291 - 			break;
  24.292 - 		case FUTEX_OP_OR:
  24.293 -diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/rwsem.h ./include/asm-i386/rwsem.h
  24.294 ---- ../orig-linux-2.6.16.29/include/asm-i386/rwsem.h	2006-09-12 19:02:10.000000000 +0100
  24.295 -+++ ./include/asm-i386/rwsem.h	2006-09-19 14:05:48.000000000 +0100
  24.296 -@@ -40,6 +40,7 @@
  24.297 - 
  24.298 - #include <linux/list.h>
  24.299 - #include <linux/spinlock.h>
  24.300 -+#include <asm/smp_alt.h>
  24.301 - 
  24.302 - struct rwsem_waiter;
  24.303 - 
  24.304 -@@ -99,7 +100,7 @@ static inline void __down_read(struct rw
  24.305 - {
  24.306 - 	__asm__ __volatile__(
  24.307 - 		"# beginning down_read\n\t"
  24.308 --LOCK_PREFIX	"  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
  24.309 -+LOCK	        "  incl      (%%eax)\n\t" /* adds 0x00000001, returns the old value */
  24.310 - 		"  js        2f\n\t" /* jump if we weren't granted the lock */
  24.311 - 		"1:\n\t"
  24.312 - 		LOCK_SECTION_START("")
  24.313 -@@ -130,7 +131,7 @@ static inline int __down_read_trylock(st
  24.314 - 		"  movl	     %1,%2\n\t"
  24.315 - 		"  addl      %3,%2\n\t"
  24.316 - 		"  jle	     2f\n\t"
  24.317 --LOCK_PREFIX	"  cmpxchgl  %2,%0\n\t"
  24.318 -+LOCK	        "  cmpxchgl  %2,%0\n\t"
  24.319 - 		"  jnz	     1b\n\t"
  24.320 - 		"2:\n\t"
  24.321 - 		"# ending __down_read_trylock\n\t"
  24.322 -@@ -150,7 +151,7 @@ static inline void __down_write(struct r
  24.323 - 	tmp = RWSEM_ACTIVE_WRITE_BIAS;
  24.324 - 	__asm__ __volatile__(
  24.325 - 		"# beginning down_write\n\t"
  24.326 --LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
  24.327 -+LOCK	        "  xadd      %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */
  24.328 - 		"  testl     %%edx,%%edx\n\t" /* was the count 0 before? */
  24.329 - 		"  jnz       2f\n\t" /* jump if we weren't granted the lock */
  24.330 - 		"1:\n\t"
  24.331 -@@ -188,7 +189,7 @@ static inline void __up_read(struct rw_s
  24.332 - 	__s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
  24.333 - 	__asm__ __volatile__(
  24.334 - 		"# beginning __up_read\n\t"
  24.335 --LOCK_PREFIX	"  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
  24.336 -+LOCK	        "  xadd      %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */
  24.337 - 		"  js        2f\n\t" /* jump if the lock is being waited upon */
  24.338 - 		"1:\n\t"
  24.339 - 		LOCK_SECTION_START("")
  24.340 -@@ -214,7 +215,7 @@ static inline void __up_write(struct rw_
  24.341 - 	__asm__ __volatile__(
  24.342 - 		"# beginning __up_write\n\t"
  24.343 - 		"  movl      %2,%%edx\n\t"
  24.344 --LOCK_PREFIX	"  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
  24.345 -+LOCK	        "  xaddl     %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
  24.346 - 		"  jnz       2f\n\t" /* jump if the lock is being waited upon */
  24.347 - 		"1:\n\t"
  24.348 - 		LOCK_SECTION_START("")
  24.349 -@@ -239,7 +240,7 @@ static inline void __downgrade_write(str
  24.350 - {
  24.351 - 	__asm__ __volatile__(
  24.352 - 		"# beginning __downgrade_write\n\t"
  24.353 --LOCK_PREFIX	"  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
  24.354 -+LOCK	        "  addl      %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
  24.355 - 		"  js        2f\n\t" /* jump if the lock is being waited upon */
  24.356 - 		"1:\n\t"
  24.357 - 		LOCK_SECTION_START("")
  24.358 -@@ -263,7 +264,7 @@ LOCK_PREFIX	"  addl      %2,(%%eax)\n\t"
  24.359 - static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
  24.360 - {
  24.361 - 	__asm__ __volatile__(
  24.362 --LOCK_PREFIX	"addl %1,%0"
  24.363 -+LOCK	          "addl %1,%0"
  24.364 - 		: "=m"(sem->count)
  24.365 - 		: "ir"(delta), "m"(sem->count));
  24.366 - }
  24.367 -@@ -276,7 +277,7 @@ static inline int rwsem_atomic_update(in
  24.368 - 	int tmp = delta;
  24.369 - 
  24.370 - 	__asm__ __volatile__(
  24.371 --LOCK_PREFIX	"xadd %0,(%2)"
  24.372 -+LOCK  	          "xadd %0,(%2)"
  24.373 - 		: "+r"(tmp), "=m"(sem->count)
  24.374 - 		: "r"(sem), "m"(sem->count)
  24.375 - 		: "memory");
  24.376 -diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/smp_alt.h ./include/asm-i386/smp_alt.h
  24.377 ---- ../orig-linux-2.6.16.29/include/asm-i386/smp_alt.h	1970-01-01 01:00:00.000000000 +0100
  24.378 -+++ ./include/asm-i386/smp_alt.h	2006-09-19 14:05:48.000000000 +0100
  24.379 -@@ -0,0 +1,32 @@
  24.380 -+#ifndef __ASM_SMP_ALT_H__
  24.381 -+#define __ASM_SMP_ALT_H__
  24.382 -+
  24.383 -+#include <linux/config.h>
  24.384 -+
  24.385 -+#ifdef CONFIG_SMP
  24.386 -+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
  24.387 -+#define LOCK \
  24.388 -+        "6677: nop\n" \
  24.389 -+	".section __smp_alternatives,\"a\"\n" \
  24.390 -+	".long 6677b\n" \
  24.391 -+	".long 6678f\n" \
  24.392 -+	".previous\n" \
  24.393 -+	".section __smp_replacements,\"a\"\n" \
  24.394 -+	"6678: .byte 1\n" \
  24.395 -+	".byte 1\n" \
  24.396 -+	".byte 0\n" \
  24.397 -+        ".byte 1\n" \
  24.398 -+	".byte -1\n" \
  24.399 -+	"lock\n" \
  24.400 -+	"nop\n" \
  24.401 -+	".previous\n"
  24.402 -+void prepare_for_smp(void);
  24.403 -+void unprepare_for_smp(void);
  24.404 -+#else
  24.405 -+#define LOCK "lock ; "
  24.406 -+#endif
  24.407 -+#else
  24.408 -+#define LOCK ""
  24.409 -+#endif
  24.410 -+
  24.411 -+#endif /* __ASM_SMP_ALT_H__ */
  24.412 -diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/spinlock.h ./include/asm-i386/spinlock.h
  24.413 ---- ../orig-linux-2.6.16.29/include/asm-i386/spinlock.h	2006-09-12 19:02:10.000000000 +0100
  24.414 -+++ ./include/asm-i386/spinlock.h	2006-09-19 14:05:48.000000000 +0100
  24.415 -@@ -6,6 +6,7 @@
  24.416 - #include <asm/page.h>
  24.417 - #include <linux/config.h>
  24.418 - #include <linux/compiler.h>
  24.419 -+#include <asm/smp_alt.h>
  24.420 - 
  24.421 - /*
  24.422 -  * Your basic SMP spinlocks, allowing only a single CPU anywhere
  24.423 -@@ -23,7 +24,8 @@
  24.424 - 
  24.425 - #define __raw_spin_lock_string \
  24.426 - 	"\n1:\t" \
  24.427 --	"lock ; decb %0\n\t" \
  24.428 -+	LOCK \
  24.429 -+	"decb %0\n\t" \
  24.430 - 	"jns 3f\n" \
  24.431 - 	"2:\t" \
  24.432 - 	"rep;nop\n\t" \
  24.433 -@@ -34,7 +36,8 @@
  24.434 - 
  24.435 - #define __raw_spin_lock_string_flags \
  24.436 - 	"\n1:\t" \
  24.437 --	"lock ; decb %0\n\t" \
  24.438 -+	LOCK \
  24.439 -+	"decb %0\n\t" \
  24.440 - 	"jns 4f\n\t" \
  24.441 - 	"2:\t" \
  24.442 - 	"testl $0x200, %1\n\t" \
  24.443 -@@ -65,10 +68,34 @@ static inline void __raw_spin_lock_flags
  24.444 - static inline int __raw_spin_trylock(raw_spinlock_t *lock)
  24.445 - {
  24.446 - 	char oldval;
  24.447 -+#ifdef CONFIG_SMP_ALTERNATIVES
  24.448 - 	__asm__ __volatile__(
  24.449 --		"xchgb %b0,%1"
  24.450 -+		"1:movb %1,%b0\n"
  24.451 -+		"movb $0,%1\n"
  24.452 -+		"2:"
  24.453 -+		".section __smp_alternatives,\"a\"\n"
  24.454 -+		".long 1b\n"
  24.455 -+		".long 3f\n"
  24.456 -+		".previous\n"
  24.457 -+		".section __smp_replacements,\"a\"\n"
  24.458 -+		"3: .byte 2b - 1b\n"
  24.459 -+		".byte 5f-4f\n"
  24.460 -+		".byte 0\n"
  24.461 -+		".byte 6f-5f\n"
  24.462 -+		".byte -1\n"
  24.463 -+		"4: xchgb %b0,%1\n"
  24.464 -+		"5: movb %1,%b0\n"
  24.465 -+		"movb $0,%1\n"
  24.466 -+		"6:\n"
  24.467 -+		".previous\n"
  24.468 - 		:"=q" (oldval), "=m" (lock->slock)
  24.469 - 		:"0" (0) : "memory");
  24.470 -+#else
  24.471 -+	__asm__ __volatile__(
  24.472 -+		"xchgb %b0,%1\n"
  24.473 -+		:"=q" (oldval), "=m" (lock->slock)
  24.474 -+		:"0" (0) : "memory");
  24.475 -+#endif
  24.476 - 	return oldval > 0;
  24.477 - }
  24.478 - 
  24.479 -@@ -178,12 +205,12 @@ static inline int __raw_write_trylock(ra
  24.480 - 
  24.481 - static inline void __raw_read_unlock(raw_rwlock_t *rw)
  24.482 - {
  24.483 --	asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory");
  24.484 -+	asm volatile(LOCK "incl %0" :"=m" (rw->lock) : : "memory");
  24.485 - }
  24.486 - 
  24.487 - static inline void __raw_write_unlock(raw_rwlock_t *rw)
  24.488 - {
  24.489 --	asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0"
  24.490 -+	asm volatile(LOCK "addl $" RW_LOCK_BIAS_STR ", %0"
  24.491 - 				 : "=m" (rw->lock) : : "memory");
  24.492 - }
  24.493 - 
  24.494 -diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/system.h ./include/asm-i386/system.h
  24.495 ---- ../orig-linux-2.6.16.29/include/asm-i386/system.h	2006-09-12 19:02:10.000000000 +0100
  24.496 -+++ ./include/asm-i386/system.h	2006-09-19 14:05:48.000000000 +0100
  24.497 -@@ -5,7 +5,7 @@
  24.498 - #include <linux/kernel.h>
  24.499 - #include <asm/segment.h>
  24.500 - #include <asm/cpufeature.h>
  24.501 --#include <linux/bitops.h> /* for LOCK_PREFIX */
  24.502 -+#include <asm/smp_alt.h>
  24.503 - 
  24.504 - #ifdef __KERNEL__
  24.505 - 
  24.506 -@@ -271,19 +271,19 @@ static inline unsigned long __cmpxchg(vo
  24.507 - 	unsigned long prev;
  24.508 - 	switch (size) {
  24.509 - 	case 1:
  24.510 --		__asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
  24.511 -+		__asm__ __volatile__(LOCK "cmpxchgb %b1,%2"
  24.512 - 				     : "=a"(prev)
  24.513 - 				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
  24.514 - 				     : "memory");
  24.515 - 		return prev;
  24.516 - 	case 2:
  24.517 --		__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
  24.518 -+		__asm__ __volatile__(LOCK "cmpxchgw %w1,%2"
  24.519 - 				     : "=a"(prev)
  24.520 - 				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
  24.521 - 				     : "memory");
  24.522 - 		return prev;
  24.523 - 	case 4:
  24.524 --		__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
  24.525 -+		__asm__ __volatile__(LOCK "cmpxchgl %1,%2"
  24.526 - 				     : "=a"(prev)
  24.527 - 				     : "r"(new), "m"(*__xg(ptr)), "0"(old)
  24.528 - 				     : "memory");
  24.529 -@@ -336,7 +336,7 @@ static inline unsigned long long __cmpxc
  24.530 - 				      unsigned long long new)
  24.531 - {
  24.532 - 	unsigned long long prev;
  24.533 --	__asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
  24.534 -+	__asm__ __volatile__(LOCK "cmpxchg8b %3"
  24.535 - 			     : "=A"(prev)
  24.536 - 			     : "b"((unsigned long)new),
  24.537 - 			       "c"((unsigned long)(new >> 32)),
  24.538 -@@ -503,11 +503,55 @@ struct alt_instr { 
  24.539 - #endif
  24.540 - 
  24.541 - #ifdef CONFIG_SMP
  24.542 -+#if defined(CONFIG_SMP_ALTERNATIVES) && !defined(MODULE)
  24.543 -+#define smp_alt_mb(instr)                                           \
  24.544 -+__asm__ __volatile__("6667:\nnop\nnop\nnop\nnop\nnop\nnop\n6668:\n" \
  24.545 -+		     ".section __smp_alternatives,\"a\"\n"          \
  24.546 -+		     ".long 6667b\n"                                \
  24.547 -+                     ".long 6673f\n"                                \
  24.548 -+		     ".previous\n"                                  \
  24.549 -+		     ".section __smp_replacements,\"a\"\n"          \
  24.550 -+		     "6673:.byte 6668b-6667b\n"                     \
  24.551 -+		     ".byte 6670f-6669f\n"                          \
  24.552 -+		     ".byte 6671f-6670f\n"                          \
  24.553 -+                     ".byte 0\n"                                    \
  24.554 -+		     ".byte %c0\n"                                  \
  24.555 -+		     "6669:lock;addl $0,0(%%esp)\n"                 \
  24.556 -+		     "6670:" instr "\n"                             \
  24.557 -+		     "6671:\n"                                      \
  24.558 -+		     ".previous\n"                                  \
  24.559 -+		     :                                              \
  24.560 -+		     : "i" (X86_FEATURE_XMM2)                       \
  24.561 -+		     : "memory")
  24.562 -+#define smp_rmb() smp_alt_mb("lfence")
  24.563 -+#define smp_mb()  smp_alt_mb("mfence")
  24.564 -+#define set_mb(var, value) do {                                     \
  24.565 -+unsigned long __set_mb_temp;                                        \
  24.566 -+__asm__ __volatile__("6667:movl %1, %0\n6668:\n"                    \
  24.567 -+		     ".section __smp_alternatives,\"a\"\n"          \
  24.568 -+		     ".long 6667b\n"                                \
  24.569 -+		     ".long 6673f\n"                                \
  24.570 -+		     ".previous\n"                                  \
  24.571 -+		     ".section __smp_replacements,\"a\"\n"          \
  24.572 -+		     "6673: .byte 6668b-6667b\n"                    \
  24.573 -+		     ".byte 6670f-6669f\n"                          \
  24.574 -+		     ".byte 0\n"                                    \
  24.575 -+		     ".byte 6671f-6670f\n"                          \
  24.576 -+		     ".byte -1\n"                                   \
  24.577 -+		     "6669: xchg %1, %0\n"                          \
  24.578 -+		     "6670:movl %1, %0\n"                           \
  24.579 -+		     "6671:\n"                                      \
  24.580 -+		     ".previous\n"                                  \
  24.581 -+		     : "=m" (var), "=r" (__set_mb_temp)             \
  24.582 -+		     : "1" (value)                                  \
  24.583 -+		     : "memory"); } while (0)
  24.584 -+#else
  24.585 - #define smp_mb()	mb()
  24.586 - #define smp_rmb()	rmb()
  24.587 -+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
  24.588 -+#endif
  24.589 - #define smp_wmb()	wmb()
  24.590 - #define smp_read_barrier_depends()	read_barrier_depends()
  24.591 --#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
  24.592 - #else
  24.593 - #define smp_mb()	barrier()
  24.594 - #define smp_rmb()	barrier()
    25.1 --- a/patches/linux-2.6.16.31/tpm_plugin_2.6.17.patch	Mon Nov 27 13:50:02 2006 +0000
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,1545 +0,0 @@
    25.4 -diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_atmel.c ./drivers/char/tpm/tpm_atmel.c
    25.5 ---- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_atmel.c	2006-09-12 19:02:10.000000000 +0100
    25.6 -+++ ./drivers/char/tpm/tpm_atmel.c	2006-09-19 14:05:52.000000000 +0100
    25.7 -@@ -47,12 +47,12 @@ static int tpm_atml_recv(struct tpm_chip
    25.8 - 		return -EIO;
    25.9 - 
   25.10 - 	for (i = 0; i < 6; i++) {
   25.11 --		status = ioread8(chip->vendor->iobase + 1);
   25.12 -+		status = ioread8(chip->vendor.iobase + 1);
   25.13 - 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
   25.14 - 			dev_err(chip->dev, "error reading header\n");
   25.15 - 			return -EIO;
   25.16 - 		}
   25.17 --		*buf++ = ioread8(chip->vendor->iobase);
   25.18 -+		*buf++ = ioread8(chip->vendor.iobase);
   25.19 - 	}
   25.20 - 
   25.21 - 	/* size of the data received */
   25.22 -@@ -63,7 +63,7 @@ static int tpm_atml_recv(struct tpm_chip
   25.23 - 		dev_err(chip->dev,
   25.24 - 			"Recv size(%d) less than available space\n", size);
   25.25 - 		for (; i < size; i++) {	/* clear the waiting data anyway */
   25.26 --			status = ioread8(chip->vendor->iobase + 1);
   25.27 -+			status = ioread8(chip->vendor.iobase + 1);
   25.28 - 			if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
   25.29 - 				dev_err(chip->dev, "error reading data\n");
   25.30 - 				return -EIO;
   25.31 -@@ -74,16 +74,16 @@ static int tpm_atml_recv(struct tpm_chip
   25.32 - 
   25.33 - 	/* read all the data available */
   25.34 - 	for (; i < size; i++) {
   25.35 --		status = ioread8(chip->vendor->iobase + 1);
   25.36 -+		status = ioread8(chip->vendor.iobase + 1);
   25.37 - 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
   25.38 - 			dev_err(chip->dev, "error reading data\n");
   25.39 - 			return -EIO;
   25.40 - 		}
   25.41 --		*buf++ = ioread8(chip->vendor->iobase);
   25.42 -+		*buf++ = ioread8(chip->vendor.iobase);
   25.43 - 	}
   25.44 - 
   25.45 - 	/* make sure data available is gone */
   25.46 --	status = ioread8(chip->vendor->iobase + 1);
   25.47 -+	status = ioread8(chip->vendor.iobase + 1);
   25.48 - 
   25.49 - 	if (status & ATML_STATUS_DATA_AVAIL) {
   25.50 - 		dev_err(chip->dev, "data available is stuck\n");
   25.51 -@@ -100,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip
   25.52 - 	dev_dbg(chip->dev, "tpm_atml_send:\n");
   25.53 - 	for (i = 0; i < count; i++) {
   25.54 - 		dev_dbg(chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
   25.55 -- 		iowrite8(buf[i], chip->vendor->iobase);
   25.56 -+ 		iowrite8(buf[i], chip->vendor.iobase);
   25.57 - 	}
   25.58 - 
   25.59 - 	return count;
   25.60 -@@ -108,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip
   25.61 - 
   25.62 - static void tpm_atml_cancel(struct tpm_chip *chip)
   25.63 - {
   25.64 --	iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1);
   25.65 -+	iowrite8(ATML_STATUS_ABORT, chip->vendor.iobase + 1);
   25.66 - }
   25.67 - 
   25.68 - static u8 tpm_atml_status(struct tpm_chip *chip)
   25.69 - {
   25.70 --	return ioread8(chip->vendor->iobase + 1);
   25.71 -+	return ioread8(chip->vendor.iobase + 1);
   25.72 - }
   25.73 - 
   25.74 - static struct file_operations atmel_ops = {
   25.75 -@@ -140,7 +140,7 @@ static struct attribute* atmel_attrs[] =
   25.76 - 
   25.77 - static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
   25.78 - 
   25.79 --static struct tpm_vendor_specific tpm_atmel = {
   25.80 -+static const struct tpm_vendor_specific tpm_atmel = {
   25.81 - 	.recv = tpm_atml_recv,
   25.82 - 	.send = tpm_atml_send,
   25.83 - 	.cancel = tpm_atml_cancel,
   25.84 -@@ -159,10 +159,10 @@ static void atml_plat_remove(void)
   25.85 - 	struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
   25.86 - 
   25.87 - 	if (chip) {
   25.88 --		if (chip->vendor->have_region)
   25.89 --			atmel_release_region(chip->vendor->base,
   25.90 --					     chip->vendor->region_size);
   25.91 --		atmel_put_base_addr(chip->vendor);
   25.92 -+		if (chip->vendor.have_region)
   25.93 -+			atmel_release_region(chip->vendor.base,
   25.94 -+					     chip->vendor.region_size);
   25.95 -+		atmel_put_base_addr(chip->vendor.iobase);
   25.96 - 		tpm_remove_hardware(chip->dev);
   25.97 - 		platform_device_unregister(pdev);
   25.98 - 	}
   25.99 -@@ -179,18 +179,22 @@ static struct device_driver atml_drv = {
  25.100 - static int __init init_atmel(void)
  25.101 - {
  25.102 - 	int rc = 0;
  25.103 -+	void __iomem *iobase = NULL;
  25.104 -+	int have_region, region_size;
  25.105 -+	unsigned long base;
  25.106 -+	struct  tpm_chip *chip;
  25.107 - 
  25.108 - 	driver_register(&atml_drv);
  25.109 - 
  25.110 --	if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) {
  25.111 -+	if ((iobase = atmel_get_base_addr(&base, &region_size)) == NULL) {
  25.112 - 		rc = -ENODEV;
  25.113 - 		goto err_unreg_drv;
  25.114 - 	}
  25.115 - 
  25.116 --	tpm_atmel.have_region =
  25.117 -+	have_region =
  25.118 - 	    (atmel_request_region
  25.119 --	     (tpm_atmel.base, tpm_atmel.region_size,
  25.120 --	      "tpm_atmel0") == NULL) ? 0 : 1;
  25.121 -+	     (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
  25.122 -+
  25.123 - 
  25.124 - 	if (IS_ERR
  25.125 - 	    (pdev =
  25.126 -@@ -199,17 +203,25 @@ static int __init init_atmel(void)
  25.127 - 		goto err_rel_reg;
  25.128 - 	}
  25.129 - 
  25.130 --	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
  25.131 -+	if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
  25.132 -+		rc = -ENODEV;
  25.133 - 		goto err_unreg_dev;
  25.134 -+	}
  25.135 -+
  25.136 -+	chip->vendor.iobase = iobase;
  25.137 -+	chip->vendor.base = base;
  25.138 -+	chip->vendor.have_region = have_region;
  25.139 -+	chip->vendor.region_size = region_size;
  25.140 -+
  25.141 - 	return 0;
  25.142 - 
  25.143 - err_unreg_dev:
  25.144 - 	platform_device_unregister(pdev);
  25.145 - err_rel_reg:
  25.146 --	atmel_put_base_addr(&tpm_atmel);
  25.147 --	if (tpm_atmel.have_region)
  25.148 --		atmel_release_region(tpm_atmel.base,
  25.149 --				     tpm_atmel.region_size);
  25.150 -+	atmel_put_base_addr(iobase);
  25.151 -+	if (have_region)
  25.152 -+		atmel_release_region(base,
  25.153 -+				     region_size);
  25.154 - err_unreg_drv:
  25.155 - 	driver_unregister(&atml_drv);
  25.156 - 	return rc;
  25.157 -diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_atmel.h ./drivers/char/tpm/tpm_atmel.h
  25.158 ---- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_atmel.h	2006-09-12 19:02:10.000000000 +0100
  25.159 -+++ ./drivers/char/tpm/tpm_atmel.h	2006-09-19 14:05:52.000000000 +0100
  25.160 -@@ -28,13 +28,12 @@
  25.161 - #define atmel_request_region request_mem_region
  25.162 - #define atmel_release_region release_mem_region
  25.163 - 
  25.164 --static inline void atmel_put_base_addr(struct tpm_vendor_specific
  25.165 --					 *vendor)
  25.166 -+static inline void atmel_put_base_addr(void __iomem *iobase)
  25.167 - {
  25.168 --	iounmap(vendor->iobase);
  25.169 -+	iounmap(iobase);
  25.170 - }
  25.171 - 
  25.172 --static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
  25.173 -+static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
  25.174 - {
  25.175 - 	struct device_node *dn;
  25.176 - 	unsigned long address, size;
  25.177 -@@ -71,9 +70,9 @@ static void __iomem * atmel_get_base_add
  25.178 - 	else
  25.179 - 		size = reg[naddrc];
  25.180 - 
  25.181 --	vendor->base = address;
  25.182 --	vendor->region_size = size;
  25.183 --	return ioremap(vendor->base, vendor->region_size);
  25.184 -+	*base = address;
  25.185 -+	*region_size = size;
  25.186 -+	return ioremap(*base, *region_size);
  25.187 - }
  25.188 - #else
  25.189 - #define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
  25.190 -@@ -106,14 +105,12 @@ static int atmel_verify_tpm11(void)
  25.191 - 	return 0;
  25.192 - }
  25.193 - 
  25.194 --static inline void atmel_put_base_addr(struct tpm_vendor_specific
  25.195 --					 *vendor)
  25.196 -+static inline void atmel_put_base_addr(void __iomem *iobase)
  25.197 - {
  25.198 - }
  25.199 - 
  25.200 - /* Determine where to talk to device */
  25.201 --static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
  25.202 --					 *vendor)
  25.203 -+static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
  25.204 - {
  25.205 - 	int lo, hi;
  25.206 - 
  25.207 -@@ -123,9 +120,9 @@ static void __iomem * atmel_get_base_add
  25.208 - 	lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
  25.209 - 	hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
  25.210 - 
  25.211 --	vendor->base = (hi << 8) | lo;
  25.212 --	vendor->region_size = 2;
  25.213 -+	*base = (hi << 8) | lo;
  25.214 -+	*region_size = 2;
  25.215 - 
  25.216 --	return ioport_map(vendor->base, vendor->region_size);
  25.217 -+	return ioport_map(*base, *region_size);
  25.218 - }
  25.219 - #endif
  25.220 -diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_bios.c ./drivers/char/tpm/tpm_bios.c
  25.221 ---- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_bios.c	2006-09-12 19:02:10.000000000 +0100
  25.222 -+++ ./drivers/char/tpm/tpm_bios.c	2006-09-19 14:05:52.000000000 +0100
  25.223 -@@ -29,6 +29,11 @@
  25.224 - #define MAX_TEXT_EVENT		1000	/* Max event string length */
  25.225 - #define ACPI_TCPA_SIG		"TCPA"	/* 0x41504354 /'TCPA' */
  25.226 - 
  25.227 -+enum bios_platform_class {
  25.228 -+	BIOS_CLIENT = 0x00,
  25.229 -+	BIOS_SERVER = 0x01,
  25.230 -+};
  25.231 -+
  25.232 - struct tpm_bios_log {
  25.233 - 	void *bios_event_log;
  25.234 - 	void *bios_event_log_end;
  25.235 -@@ -36,9 +41,18 @@ struct tpm_bios_log {
  25.236 - 
  25.237 - struct acpi_tcpa {
  25.238 - 	struct acpi_table_header hdr;
  25.239 --	u16 reserved;
  25.240 --	u32 log_max_len __attribute__ ((packed));
  25.241 --	u32 log_start_addr __attribute__ ((packed));
  25.242 -+	u16 platform_class;
  25.243 -+	union {
  25.244 -+		struct client_hdr {
  25.245 -+			u32 log_max_len __attribute__ ((packed));
  25.246 -+			u64 log_start_addr __attribute__ ((packed));
  25.247 -+		} client;
  25.248 -+		struct server_hdr {
  25.249 -+			u16 reserved;
  25.250 -+			u64 log_max_len __attribute__ ((packed));
  25.251 -+			u64 log_start_addr __attribute__ ((packed));
  25.252 -+		} server;
  25.253 -+	};
  25.254 - };
  25.255 - 
  25.256 - struct tcpa_event {
  25.257 -@@ -91,6 +105,12 @@ static const char* tcpa_event_type_strin
  25.258 - 	"Non-Host Info"
  25.259 - };
  25.260 - 
  25.261 -+struct tcpa_pc_event {
  25.262 -+	u32 event_id;
  25.263 -+	u32 event_size;
  25.264 -+	u8 event_data[0];
  25.265 -+};
  25.266 -+
  25.267 - enum tcpa_pc_event_ids {
  25.268 - 	SMBIOS = 1,
  25.269 - 	BIS_CERT,
  25.270 -@@ -100,14 +120,15 @@ enum tcpa_pc_event_ids {
  25.271 - 	NVRAM,
  25.272 - 	OPTION_ROM_EXEC,
  25.273 - 	OPTION_ROM_CONFIG,
  25.274 --	OPTION_ROM_MICROCODE,
  25.275 -+	OPTION_ROM_MICROCODE = 10,
  25.276 - 	S_CRTM_VERSION,
  25.277 - 	S_CRTM_CONTENTS,
  25.278 - 	POST_CONTENTS,
  25.279 -+	HOST_TABLE_OF_DEVICES,
  25.280 - };
  25.281 - 
  25.282 - static const char* tcpa_pc_event_id_strings[] = {
  25.283 --	""
  25.284 -+	"",
  25.285 - 	"SMBIOS",
  25.286 - 	"BIS Certificate",
  25.287 - 	"POST BIOS ",
  25.288 -@@ -116,10 +137,12 @@ static const char* tcpa_pc_event_id_stri
  25.289 - 	"NVRAM",
  25.290 - 	"Option ROM",
  25.291 - 	"Option ROM config",
  25.292 --	"Option ROM microcode",
  25.293 -+	"",
  25.294 -+	"Option ROM microcode ",
  25.295 - 	"S-CRTM Version",
  25.296 --	"S-CRTM Contents",
  25.297 --	"S-CRTM POST Contents",
  25.298 -+	"S-CRTM Contents ",
  25.299 -+	"POST Contents ",
  25.300 -+	"Table of Devices",
  25.301 - };
  25.302 - 
  25.303 - /* returns pointer to start of pos. entry of tcg log */
  25.304 -@@ -191,7 +214,7 @@ static int get_event_name(char *dest, st
  25.305 - 	const char *name = "";
  25.306 - 	char data[40] = "";
  25.307 - 	int i, n_len = 0, d_len = 0;
  25.308 --	u32 event_id;
  25.309 -+	struct tcpa_pc_event *pc_event;
  25.310 - 
  25.311 - 	switch(event->event_type) {
  25.312 - 	case PREBOOT:
  25.313 -@@ -220,31 +243,32 @@ static int get_event_name(char *dest, st
  25.314 - 		}
  25.315 - 		break;
  25.316 - 	case EVENT_TAG:
  25.317 --		event_id = be32_to_cpu(*((u32 *)event_entry));
  25.318 -+		pc_event = (struct tcpa_pc_event *)event_entry;
  25.319 - 
  25.320 - 		/* ToDo Row data -> Base64 */
  25.321 - 
  25.322 --		switch (event_id) {
  25.323 -+		switch (pc_event->event_id) {
  25.324 - 		case SMBIOS:
  25.325 - 		case BIS_CERT:
  25.326 - 		case CMOS:
  25.327 - 		case NVRAM:
  25.328 - 		case OPTION_ROM_EXEC:
  25.329 - 		case OPTION_ROM_CONFIG:
  25.330 --		case OPTION_ROM_MICROCODE:
  25.331 - 		case S_CRTM_VERSION:
  25.332 --		case S_CRTM_CONTENTS:
  25.333 --		case POST_CONTENTS:
  25.334 --			name = tcpa_pc_event_id_strings[event_id];
  25.335 -+			name = tcpa_pc_event_id_strings[pc_event->event_id];
  25.336 - 			n_len = strlen(name);
  25.337 - 			break;
  25.338 -+		/* hash data */
  25.339 - 		case POST_BIOS_ROM:
  25.340 - 		case ESCD:
  25.341 --			name = tcpa_pc_event_id_strings[event_id];
  25.342 -+		case OPTION_ROM_MICROCODE:
  25.343 -+		case S_CRTM_CONTENTS:
  25.344 -+		case POST_CONTENTS:
  25.345 -+			name = tcpa_pc_event_id_strings[pc_event->event_id];
  25.346 - 			n_len = strlen(name);
  25.347 - 			for (i = 0; i < 20; i++)
  25.348 --				d_len += sprintf(data, "%02x",
  25.349 --						event_entry[8 + i]);
  25.350 -+				d_len += sprintf(&data[2*i], "%02x",
  25.351 -+						pc_event->event_data[i]);
  25.352 - 			break;
  25.353 - 		default:
  25.354 - 			break;
  25.355 -@@ -260,52 +284,13 @@ static int get_event_name(char *dest, st
  25.356 - 
  25.357 - static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
  25.358 - {
  25.359 -+	struct tcpa_event *event = v;
  25.360 -+	char *data = v;
  25.361 -+	int i;
  25.362 - 
  25.363 --	char *eventname;
  25.364 --	char data[4];
  25.365 --	u32 help;
  25.366 --	int i, len;
  25.367 --	struct tcpa_event *event = (struct tcpa_event *) v;
  25.368 --	unsigned char *event_entry =
  25.369 --	    (unsigned char *) (v + sizeof(struct tcpa_event));
  25.370 --
  25.371 --	eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
  25.372 --	if (!eventname) {
  25.373 --		printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
  25.374 --		       __func__);
  25.375 --		return -ENOMEM;
  25.376 --	}
  25.377 --
  25.378 --	/* 1st: PCR used is in little-endian format (4 bytes) */
  25.379 --	help = le32_to_cpu(event->pcr_index);
  25.380 --	memcpy(data, &help, 4);
  25.381 --	for (i = 0; i < 4; i++)
  25.382 --		seq_putc(m, data[i]);
  25.383 --
  25.384 --	/* 2nd: SHA1 (20 bytes) */
  25.385 --	for (i = 0; i < 20; i++)
  25.386 --		seq_putc(m, event->pcr_value[i]);
  25.387 --
  25.388 --	/* 3rd: event type identifier (4 bytes) */
  25.389 --	help = le32_to_cpu(event->event_type);
  25.390 --	memcpy(data, &help, 4);
  25.391 --	for (i = 0; i < 4; i++)
  25.392 -+	for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
  25.393 - 		seq_putc(m, data[i]);
  25.394 - 
  25.395 --	len = 0;
  25.396 --
  25.397 --	len += get_event_name(eventname, event, event_entry);
  25.398 --
  25.399 --	/* 4th:  filename <= 255 + \'0' delimiter */
  25.400 --	if (len > TCG_EVENT_NAME_LEN_MAX)
  25.401 --		len = TCG_EVENT_NAME_LEN_MAX;
  25.402 --
  25.403 --	for (i = 0; i < len; i++)
  25.404 --		seq_putc(m, eventname[i]);
  25.405 --
  25.406 --	/* 5th: delimiter */
  25.407 --	seq_putc(m, '\0');
  25.408 --
  25.409 - 	return 0;
  25.410 - }
  25.411 - 
  25.412 -@@ -353,6 +338,7 @@ static int tpm_ascii_bios_measurements_s
  25.413 - 	/* 4th: eventname <= max + \'0' delimiter */
  25.414 - 	seq_printf(m, " %s\n", eventname);
  25.415 - 
  25.416 -+	kfree(eventname);
  25.417 - 	return 0;
  25.418 - }
  25.419 - 
  25.420 -@@ -376,6 +362,7 @@ static int read_log(struct tpm_bios_log 
  25.421 - 	struct acpi_tcpa *buff;
  25.422 - 	acpi_status status;
  25.423 - 	struct acpi_table_header *virt;
  25.424 -+	u64 len, start;
  25.425 - 
  25.426 - 	if (log->bios_event_log != NULL) {
  25.427 - 		printk(KERN_ERR
  25.428 -@@ -396,27 +383,37 @@ static int read_log(struct tpm_bios_log 
  25.429 - 		return -EIO;
  25.430 - 	}
  25.431 - 
  25.432 --	if (buff->log_max_len == 0) {
  25.433 -+	switch(buff->platform_class) {
  25.434 -+	case BIOS_SERVER:
  25.435 -+		len = buff->server.log_max_len;
  25.436 -+		start = buff->server.log_start_addr;
  25.437 -+		break;
  25.438 -+	case BIOS_CLIENT:
  25.439 -+	default:
  25.440 -+		len = buff->client.log_max_len;
  25.441 -+		start = buff->client.log_start_addr;
  25.442 -+		break;
  25.443 -+	}
  25.444 -+	if (!len) {
  25.445 - 		printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
  25.446 - 		return -EIO;
  25.447 - 	}
  25.448 - 
  25.449 - 	/* malloc EventLog space */
  25.450 --	log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
  25.451 -+	log->bios_event_log = kmalloc(len, GFP_KERNEL);
  25.452 - 	if (!log->bios_event_log) {
  25.453 --		printk
  25.454 --		    ("%s: ERROR - Not enough  Memory for BIOS measurements\n",
  25.455 --		     __func__);
  25.456 -+		printk("%s: ERROR - Not enough  Memory for BIOS measurements\n",
  25.457 -+			__func__);
  25.458 - 		return -ENOMEM;
  25.459 - 	}
  25.460 - 
  25.461 --	log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
  25.462 -+	log->bios_event_log_end = log->bios_event_log + len;
  25.463 - 
  25.464 --	acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt);
  25.465 -+	acpi_os_map_memory(start, len, (void *) &virt);
  25.466 - 
  25.467 --	memcpy(log->bios_event_log, virt, buff->log_max_len);
  25.468 -+	memcpy(log->bios_event_log, virt, len);
  25.469 - 
  25.470 --	acpi_os_unmap_memory(virt, buff->log_max_len);
  25.471 -+	acpi_os_unmap_memory(virt, len);
  25.472 - 	return 0;
  25.473 - }
  25.474 - 
  25.475 -diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_infineon.c ./drivers/char/tpm/tpm_infineon.c
  25.476 ---- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_infineon.c	2006-09-12 19:02:10.000000000 +0100
  25.477 -+++ ./drivers/char/tpm/tpm_infineon.c	2006-09-19 14:05:52.000000000 +0100
  25.478 -@@ -15,6 +15,7 @@
  25.479 -  * License.
  25.480 -  */
  25.481 - 
  25.482 -+#include <linux/init.h>
  25.483 - #include <linux/pnp.h>
  25.484 - #include "tpm.h"
  25.485 - 
  25.486 -@@ -104,7 +105,7 @@ static int empty_fifo(struct tpm_chip *c
  25.487 - 
  25.488 - 	if (clear_wrfifo) {
  25.489 - 		for (i = 0; i < 4096; i++) {
  25.490 --			status = inb(chip->vendor->base + WRFIFO);
  25.491 -+			status = inb(chip->vendor.base + WRFIFO);
  25.492 - 			if (status == 0xff) {
  25.493 - 				if (check == 5)
  25.494 - 					break;
  25.495 -@@ -124,8 +125,8 @@ static int empty_fifo(struct tpm_chip *c
  25.496 - 	 */
  25.497 - 	i = 0;
  25.498 - 	do {
  25.499 --		status = inb(chip->vendor->base + RDFIFO);
  25.500 --		status = inb(chip->vendor->base + STAT);
  25.501 -+		status = inb(chip->vendor.base + RDFIFO);
  25.502 -+		status = inb(chip->vendor.base + STAT);
  25.503 - 		i++;
  25.504 - 		if (i == TPM_MAX_TRIES)
  25.505 - 			return -EIO;
  25.506 -@@ -138,7 +139,7 @@ static int wait(struct tpm_chip *chip, i
  25.507 - 	int status;
  25.508 - 	int i;
  25.509 - 	for (i = 0; i < TPM_MAX_TRIES; i++) {
  25.510 --		status = inb(chip->vendor->base + STAT);
  25.511 -+		status = inb(chip->vendor.base + STAT);
  25.512 - 		/* check the status-register if wait_for_bit is set */
  25.513 - 		if (status & 1 << wait_for_bit)
  25.514 - 			break;
  25.515 -@@ -157,7 +158,7 @@ static int wait(struct tpm_chip *chip, i
  25.516 - static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
  25.517 - {
  25.518 - 	wait(chip, STAT_XFE);
  25.519 --	outb(sendbyte, chip->vendor->base + WRFIFO);
  25.520 -+	outb(sendbyte, chip->vendor.base + WRFIFO);
  25.521 - }
  25.522 - 
  25.523 -     /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
  25.524 -@@ -204,7 +205,7 @@ recv_begin:
  25.525 - 		ret = wait(chip, STAT_RDA);
  25.526 - 		if (ret)
  25.527 - 			return -EIO;
  25.528 --		buf[i] = inb(chip->vendor->base + RDFIFO);
  25.529 -+		buf[i] = inb(chip->vendor.base + RDFIFO);
  25.530 - 	}
  25.531 - 
  25.532 - 	if (buf[0] != TPM_VL_VER) {
  25.533 -@@ -219,7 +220,7 @@ recv_begin:
  25.534 - 
  25.535 - 		for (i = 0; i < size; i++) {
  25.536 - 			wait(chip, STAT_RDA);
  25.537 --			buf[i] = inb(chip->vendor->base + RDFIFO);
  25.538 -+			buf[i] = inb(chip->vendor.base + RDFIFO);
  25.539 - 		}
  25.540 - 
  25.541 - 		if ((size == 0x6D00) && (buf[1] == 0x80)) {
  25.542 -@@ -268,7 +269,7 @@ static int tpm_inf_send(struct tpm_chip 
  25.543 - 	u8 count_high, count_low, count_4, count_3, count_2, count_1;
  25.544 - 
  25.545 - 	/* Disabling Reset, LP and IRQC */
  25.546 --	outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);
  25.547 -+	outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD);
  25.548 - 
  25.549 - 	ret = empty_fifo(chip, 1);
  25.550 - 	if (ret) {
  25.551 -@@ -319,7 +320,7 @@ static void tpm_inf_cancel(struct tpm_ch
  25.552 - 
  25.553 - static u8 tpm_inf_status(struct tpm_chip *chip)
  25.554 - {
  25.555 --	return inb(chip->vendor->base + STAT);
  25.556 -+	return inb(chip->vendor.base + STAT);
  25.557 - }
  25.558 - 
  25.559 - static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
  25.560 -@@ -346,7 +347,7 @@ static struct file_operations inf_ops = 
  25.561 - 	.release = tpm_release,
  25.562 - };
  25.563 - 
  25.564 --static struct tpm_vendor_specific tpm_inf = {
  25.565 -+static const struct tpm_vendor_specific tpm_inf = {
  25.566 - 	.recv = tpm_inf_recv,
  25.567 - 	.send = tpm_inf_send,
  25.568 - 	.cancel = tpm_inf_cancel,
  25.569 -@@ -375,6 +376,7 @@ static int __devinit tpm_inf_pnp_probe(s
  25.570 - 	int version[2];
  25.571 - 	int productid[2];
  25.572 - 	char chipname[20];
  25.573 -+	struct tpm_chip *chip;
  25.574 - 
  25.575 - 	/* read IO-ports through PnP */
  25.576 - 	if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
  25.577 -@@ -395,14 +397,13 @@ static int __devinit tpm_inf_pnp_probe(s
  25.578 - 			goto err_last;
  25.579 - 		}
  25.580 - 		/* publish my base address and request region */
  25.581 --		tpm_inf.base = TPM_INF_BASE;
  25.582 - 		if (request_region
  25.583 --		    (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
  25.584 -+		    (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
  25.585 - 			rc = -EINVAL;
  25.586 - 			goto err_last;
  25.587 - 		}
  25.588 --		if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN,
  25.589 --				"tpm_infineon0") == NULL) {
  25.590 -+		if (request_region
  25.591 -+		    (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) {
  25.592 - 			rc = -EINVAL;
  25.593 - 			goto err_last;
  25.594 - 		}
  25.595 -@@ -442,9 +443,9 @@ static int __devinit tpm_inf_pnp_probe(s
  25.596 - 
  25.597 - 		/* configure TPM with IO-ports */
  25.598 - 		outb(IOLIMH, TPM_INF_ADDR);
  25.599 --		outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
  25.600 -+		outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA);
  25.601 - 		outb(IOLIML, TPM_INF_ADDR);
  25.602 --		outb((tpm_inf.base & 0xff), TPM_INF_DATA);
  25.603 -+		outb((TPM_INF_BASE & 0xff), TPM_INF_DATA);
  25.604 - 
  25.605 - 		/* control if IO-ports are set correctly */
  25.606 - 		outb(IOLIMH, TPM_INF_ADDR);
  25.607 -@@ -452,10 +453,10 @@ static int __devinit tpm_inf_pnp_probe(s
  25.608 - 		outb(IOLIML, TPM_INF_ADDR);
  25.609 - 		iol = inb(TPM_INF_DATA);
  25.610 - 
  25.611 --		if ((ioh << 8 | iol) != tpm_inf.base) {
  25.612 -+		if ((ioh << 8 | iol) != TPM_INF_BASE) {
  25.613 - 			dev_err(&dev->dev,
  25.614 --				"Could not set IO-ports to 0x%lx\n",
  25.615 --				tpm_inf.base);
  25.616 -+				"Could not set IO-ports to 0x%x\n",
  25.617 -+				TPM_INF_BASE);
  25.618 - 			rc = -EIO;
  25.619 - 			goto err_release_region;
  25.620 - 		}
  25.621 -@@ -466,15 +467,15 @@ static int __devinit tpm_inf_pnp_probe(s
  25.622 - 		outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
  25.623 - 
  25.624 - 		/* disable RESET, LP and IRQC */
  25.625 --		outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
  25.626 -+		outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD);
  25.627 - 
  25.628 - 		/* Finally, we're done, print some infos */
  25.629 - 		dev_info(&dev->dev, "TPM found: "
  25.630 - 			 "config base 0x%x, "
  25.631 - 			 "io base 0x%x, "
  25.632 --			 "chip version %02x%02x, "
  25.633 --			 "vendor id %x%x (Infineon), "
  25.634 --			 "product id %02x%02x"
  25.635 -+			 "chip version 0x%02x%02x, "
  25.636 -+			 "vendor id 0x%x%x (Infineon), "
  25.637 -+			 "product id 0x%02x%02x"
  25.638 - 			 "%s\n",
  25.639 - 			 TPM_INF_ADDR,
  25.640 - 			 TPM_INF_BASE,
  25.641 -@@ -482,11 +483,10 @@ static int __devinit tpm_inf_pnp_probe(s
  25.642 - 			 vendorid[0], vendorid[1],
  25.643 - 			 productid[0], productid[1], chipname);
  25.644 - 
  25.645 --		rc = tpm_register_hardware(&dev->dev, &tpm_inf);
  25.646 --		if (rc < 0) {
  25.647 --			rc = -ENODEV;
  25.648 -+		if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) {
  25.649 - 			goto err_release_region;
  25.650 - 		}
  25.651 -+		chip->vendor.base = TPM_INF_BASE;
  25.652 - 		return 0;
  25.653 - 	} else {
  25.654 - 		rc = -ENODEV;
  25.655 -@@ -494,7 +494,7 @@ static int __devinit tpm_inf_pnp_probe(s
  25.656 - 	}
  25.657 - 
  25.658 - err_release_region:
  25.659 --	release_region(tpm_inf.base, TPM_INF_PORT_LEN);
  25.660 -+	release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
  25.661 - 	release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
  25.662 - 
  25.663 - err_last:
  25.664 -@@ -506,7 +506,8 @@ static __devexit void tpm_inf_pnp_remove
  25.665 - 	struct tpm_chip *chip = pnp_get_drvdata(dev);
  25.666 - 
  25.667 - 	if (chip) {
  25.668 --		release_region(chip->vendor->base, TPM_INF_PORT_LEN);
  25.669 -+		release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
  25.670 -+		release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
  25.671 - 		tpm_remove_hardware(chip->dev);
  25.672 - 	}
  25.673 - }
  25.674 -@@ -520,7 +521,7 @@ static struct pnp_driver tpm_inf_pnp = {
  25.675 - 	},
  25.676 - 	.id_table = tpm_pnp_tbl,
  25.677 - 	.probe = tpm_inf_pnp_probe,
  25.678 --	.remove = tpm_inf_pnp_remove,
  25.679 -+	.remove = __devexit_p(tpm_inf_pnp_remove),
  25.680 - };
  25.681 - 
  25.682 - static int __init init_inf(void)
  25.683 -@@ -538,5 +539,5 @@ module_exit(cleanup_inf);
  25.684 - 
  25.685 - MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
  25.686 - MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
  25.687 --MODULE_VERSION("1.7");
  25.688 -+MODULE_VERSION("1.8");
  25.689 - MODULE_LICENSE("GPL");
  25.690 -diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_nsc.c ./drivers/char/tpm/tpm_nsc.c
  25.691 ---- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_nsc.c	2006-09-12 19:02:10.000000000 +0100
  25.692 -+++ ./drivers/char/tpm/tpm_nsc.c	2006-09-19 14:05:52.000000000 +0100
  25.693 -@@ -71,7 +71,7 @@ static int wait_for_stat(struct tpm_chip
  25.694 - 	unsigned long stop;
  25.695 - 
  25.696 - 	/* status immediately available check */
  25.697 --	*data = inb(chip->vendor->base + NSC_STATUS);
  25.698 -+	*data = inb(chip->vendor.base + NSC_STATUS);
  25.699 - 	if ((*data & mask) == val)
  25.700 - 		return 0;
  25.701 - 
  25.702 -@@ -79,7 +79,7 @@ static int wait_for_stat(struct tpm_chip
  25.703 - 	stop = jiffies + 10 * HZ;
  25.704 - 	do {
  25.705 - 		msleep(TPM_TIMEOUT);
  25.706 --		*data = inb(chip->vendor->base + 1);
  25.707 -+		*data = inb(chip->vendor.base + 1);
  25.708 - 		if ((*data & mask) == val)
  25.709 - 			return 0;
  25.710 - 	}
  25.711 -@@ -94,9 +94,9 @@ static int nsc_wait_for_ready(struct tpm
  25.712 - 	unsigned long stop;
  25.713 - 
  25.714 - 	/* status immediately available check */
  25.715 --	status = inb(chip->vendor->base + NSC_STATUS);
  25.716 -+	status = inb(chip->vendor.base + NSC_STATUS);
  25.717 - 	if (status & NSC_STATUS_OBF)
  25.718 --		status = inb(chip->vendor->base + NSC_DATA);
  25.719 -+		status = inb(chip->vendor.base + NSC_DATA);
  25.720 - 	if (status & NSC_STATUS_RDY)
  25.721 - 		return 0;
  25.722 - 
  25.723 -@@ -104,9 +104,9 @@ static int nsc_wait_for_ready(struct tpm
  25.724 - 	stop = jiffies + 100;
  25.725 - 	do {
  25.726 - 		msleep(TPM_TIMEOUT);
  25.727 --		status = inb(chip->vendor->base + NSC_STATUS);
  25.728 -+		status = inb(chip->vendor.base + NSC_STATUS);
  25.729 - 		if (status & NSC_STATUS_OBF)
  25.730 --			status = inb(chip->vendor->base + NSC_DATA);
  25.731 -+			status = inb(chip->vendor.base + NSC_DATA);
  25.732 - 		if (status & NSC_STATUS_RDY)
  25.733 - 			return 0;
  25.734 - 	}
  25.735 -@@ -132,7 +132,7 @@ static int tpm_nsc_recv(struct tpm_chip 
  25.736 - 		return -EIO;
  25.737 - 	}
  25.738 - 	if ((data =
  25.739 --	     inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
  25.740 -+	     inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
  25.741 - 		dev_err(chip->dev, "not in normal mode (0x%x)\n",
  25.742 - 			data);
  25.743 - 		return -EIO;
  25.744 -@@ -148,7 +148,7 @@ static int tpm_nsc_recv(struct tpm_chip 
  25.745 - 		}
  25.746 - 		if (data & NSC_STATUS_F0)
  25.747 - 			break;
  25.748 --		*p = inb(chip->vendor->base + NSC_DATA);
  25.749 -+		*p = inb(chip->vendor.base + NSC_DATA);
  25.750 - 	}
  25.751 - 
  25.752 - 	if ((data & NSC_STATUS_F0) == 0 &&
  25.753 -@@ -156,7 +156,7 @@ static int tpm_nsc_recv(struct tpm_chip 
  25.754 - 		dev_err(chip->dev, "F0 not set\n");
  25.755 - 		return -EIO;
  25.756 - 	}
  25.757 --	if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
  25.758 -+	if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
  25.759 - 		dev_err(chip->dev,
  25.760 - 			"expected end of command(0x%x)\n", data);
  25.761 - 		return -EIO;
  25.762 -@@ -182,7 +182,7 @@ static int tpm_nsc_send(struct tpm_chip 
  25.763 - 	 * fix it. Not sure why this is needed, we followed the flow
  25.764 - 	 * chart in the manual to the letter.
  25.765 - 	 */
  25.766 --	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
  25.767 -+	outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
  25.768 - 
  25.769 - 	if (nsc_wait_for_ready(chip) != 0)
  25.770 - 		return -EIO;
  25.771 -@@ -192,7 +192,7 @@ static int tpm_nsc_send(struct tpm_chip 
  25.772 - 		return -EIO;
  25.773 - 	}
  25.774 - 
  25.775 --	outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
  25.776 -+	outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
  25.777 - 	if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
  25.778 - 		dev_err(chip->dev, "IBR timeout\n");
  25.779 - 		return -EIO;
  25.780 -@@ -204,26 +204,26 @@ static int tpm_nsc_send(struct tpm_chip 
  25.781 - 				"IBF timeout (while writing data)\n");
  25.782 - 			return -EIO;
  25.783 - 		}
  25.784 --		outb(buf[i], chip->vendor->base + NSC_DATA);
  25.785 -+		outb(buf[i], chip->vendor.base + NSC_DATA);
  25.786 - 	}
  25.787 - 
  25.788 - 	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
  25.789 - 		dev_err(chip->dev, "IBF timeout\n");
  25.790 - 		return -EIO;
  25.791 - 	}
  25.792 --	outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
  25.793 -+	outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
  25.794 - 
  25.795 - 	return count;
  25.796 - }
  25.797 - 
  25.798 - static void tpm_nsc_cancel(struct tpm_chip *chip)
  25.799 - {
  25.800 --	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
  25.801 -+	outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
  25.802 - }
  25.803 - 
  25.804 - static u8 tpm_nsc_status(struct tpm_chip *chip)
  25.805 - {
  25.806 --	return inb(chip->vendor->base + NSC_STATUS);
  25.807 -+	return inb(chip->vendor.base + NSC_STATUS);
  25.808 - }
  25.809 - 
  25.810 - static struct file_operations nsc_ops = {
  25.811 -@@ -250,7 +250,7 @@ static struct attribute * nsc_attrs[] = 
  25.812 - 
  25.813 - static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
  25.814 - 
  25.815 --static struct tpm_vendor_specific tpm_nsc = {
  25.816 -+static const struct tpm_vendor_specific tpm_nsc = {
  25.817 - 	.recv = tpm_nsc_recv,
  25.818 - 	.send = tpm_nsc_send,
  25.819 - 	.cancel = tpm_nsc_cancel,
  25.820 -@@ -268,7 +268,7 @@ static void __devexit tpm_nsc_remove(str
  25.821 - {
  25.822 - 	struct tpm_chip *chip = dev_get_drvdata(dev);
  25.823 - 	if ( chip ) {
  25.824 --		release_region(chip->vendor->base, 2);
  25.825 -+		release_region(chip->vendor.base, 2);
  25.826 - 		tpm_remove_hardware(chip->dev);
  25.827 - 	}
  25.828 - }
  25.829 -@@ -286,7 +286,8 @@ static int __init init_nsc(void)
  25.830 - 	int rc = 0;
  25.831 - 	int lo, hi;
  25.832 - 	int nscAddrBase = TPM_ADDR;
  25.833 --
  25.834 -+	struct tpm_chip *chip;
  25.835 -+	unsigned long base;
  25.836 - 
  25.837 - 	/* verify that it is a National part (SID) */
  25.838 - 	if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
  25.839 -@@ -300,7 +301,7 @@ static int __init init_nsc(void)
  25.840 - 
  25.841 - 	hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
  25.842 - 	lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
  25.843 --	tpm_nsc.base = (hi<<8) | lo;
  25.844 -+	base = (hi<<8) | lo;
  25.845 - 
  25.846 - 	/* enable the DPM module */
  25.847 - 	tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
  25.848 -@@ -320,13 +321,15 @@ static int __init init_nsc(void)
  25.849 - 	if ((rc = platform_device_register(pdev)) < 0)
  25.850 - 		goto err_free_dev;
  25.851 - 
  25.852 --	if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
  25.853 -+	if (request_region(base, 2, "tpm_nsc0") == NULL ) {
  25.854 - 		rc = -EBUSY;
  25.855 - 		goto err_unreg_dev;
  25.856 - 	}
  25.857 - 
  25.858 --	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
  25.859 -+	if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) {
  25.860 -+		rc = -ENODEV;
  25.861 - 		goto err_rel_reg;
  25.862 -+	}
  25.863 - 
  25.864 - 	dev_dbg(&pdev->dev, "NSC TPM detected\n");
  25.865 - 	dev_dbg(&pdev->dev,
  25.866 -@@ -361,10 +364,12 @@ static int __init init_nsc(void)
  25.867 - 		 "NSC TPM revision %d\n",
  25.868 - 		 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
  25.869 - 
  25.870 -+	chip->vendor.base = base;
  25.871 -+
  25.872 - 	return 0;
  25.873 - 
  25.874 - err_rel_reg:
  25.875 --	release_region(tpm_nsc.base, 2);
  25.876 -+	release_region(base, 2);
  25.877 - err_unreg_dev:
  25.878 - 	platform_device_unregister(pdev);
  25.879 - err_free_dev:
  25.880 -diff -pruN ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_tis.c ./drivers/char/tpm/tpm_tis.c
  25.881 ---- ../orig-linux-2.6.16.29/drivers/char/tpm/tpm_tis.c	1970-01-01 01:00:00.000000000 +0100
  25.882 -+++ ./drivers/char/tpm/tpm_tis.c	2006-09-19 14:05:52.000000000 +0100
  25.883 -@@ -0,0 +1,665 @@
  25.884 -+/*
  25.885 -+ * Copyright (C) 2005, 2006 IBM Corporation
  25.886 -+ *
  25.887 -+ * Authors:
  25.888 -+ * Leendert van Doorn <leendert@watson.ibm.com>
  25.889 -+ * Kylene Hall <kjhall@us.ibm.com>
  25.890 -+ *
  25.891 -+ * Device driver for TCG/TCPA TPM (trusted platform module).
  25.892 -+ * Specifications at www.trustedcomputinggroup.org
  25.893 -+ *
  25.894 -+ * This device driver implements the TPM interface as defined in
  25.895 -+ * the TCG TPM Interface Spec version 1.2, revision 1.0.
  25.896 -+ *
  25.897 -+ * This program is free software; you can redistribute it and/or
  25.898 -+ * modify it under the terms of the GNU General Public License as
  25.899 -+ * published by the Free Software Foundation, version 2 of the
  25.900 -+ * License.
  25.901 -+ */
  25.902 -+#include <linux/init.h>
  25.903 -+#include <linux/module.h>
  25.904 -+#include <linux/moduleparam.h>
  25.905 -+#include <linux/pnp.h>
  25.906 -+#include <linux/interrupt.h>
  25.907 -+#include <linux/wait.h>
  25.908 -+#include "tpm.h"
  25.909 -+
  25.910 -+#define TPM_HEADER_SIZE 10
  25.911 -+
  25.912 -+enum tis_access {
  25.913 -+	TPM_ACCESS_VALID = 0x80,
  25.914 -+	TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
  25.915 -+	TPM_ACCESS_REQUEST_PENDING = 0x04,
  25.916 -+	TPM_ACCESS_REQUEST_USE = 0x02,
  25.917 -+};
  25.918 -+
  25.919 -+enum tis_status {
  25.920 -+	TPM_STS_VALID = 0x80,
  25.921 -+	TPM_STS_COMMAND_READY = 0x40,
  25.922 -+	TPM_STS_GO = 0x20,
  25.923 -+	TPM_STS_DATA_AVAIL = 0x10,
  25.924 -+	TPM_STS_DATA_EXPECT = 0x08,
  25.925 -+};
  25.926 -+
  25.927 -+enum tis_int_flags {
  25.928 -+	TPM_GLOBAL_INT_ENABLE = 0x80000000,
  25.929 -+	TPM_INTF_BURST_COUNT_STATIC = 0x100,
  25.930 -+	TPM_INTF_CMD_READY_INT = 0x080,
  25.931 -+	TPM_INTF_INT_EDGE_FALLING = 0x040,
  25.932 -+	TPM_INTF_INT_EDGE_RISING = 0x020,
  25.933 -+	TPM_INTF_INT_LEVEL_LOW = 0x010,
  25.934 -+	TPM_INTF_INT_LEVEL_HIGH = 0x008,
  25.935 -+	TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
  25.936 -+	TPM_INTF_STS_VALID_INT = 0x002,
  25.937 -+	TPM_INTF_DATA_AVAIL_INT = 0x001,
  25.938 -+};
  25.939 -+
  25.940 -+enum tis_defaults {
  25.941 -+	TIS_MEM_BASE = 0xFED40000,
  25.942 -+	TIS_MEM_LEN = 0x5000,
  25.943 -+	TIS_SHORT_TIMEOUT = 750,	/* ms */
  25.944 -+	TIS_LONG_TIMEOUT = 2000,	/* 2 sec */
  25.945 -+};
  25.946 -+
  25.947 -+#define	TPM_ACCESS(l)			(0x0000 | ((l) << 12))
  25.948 -+#define	TPM_INT_ENABLE(l)		(0x0008 | ((l) << 12))
  25.949 -+#define	TPM_INT_VECTOR(l)		(0x000C | ((l) << 12))
  25.950 -+#define	TPM_INT_STATUS(l)		(0x0010 | ((l) << 12))
  25.951 -+#define	TPM_INTF_CAPS(l)		(0x0014 | ((l) << 12))
  25.952 -+#define	TPM_STS(l)			(0x0018 | ((l) << 12))
  25.953 -+#define	TPM_DATA_FIFO(l)		(0x0024 | ((l) << 12))
  25.954 -+
  25.955 -+#define	TPM_DID_VID(l)			(0x0F00 | ((l) << 12))
  25.956 -+#define	TPM_RID(l)			(0x0F04 | ((l) << 12))
  25.957 -+
  25.958 -+static LIST_HEAD(tis_chips);
  25.959 -+static DEFINE_SPINLOCK(tis_lock);
  25.960 -+
  25.961 -+static int check_locality(struct tpm_chip *chip, int l)
  25.962 -+{
  25.963 -+	if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
  25.964 -+	     (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
  25.965 -+	    (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
  25.966 -+		return chip->vendor.locality = l;
  25.967 -+
  25.968 -+	return -1;
  25.969 -+}
  25.970 -+
  25.971 -+static void release_locality(struct tpm_chip *chip, int l, int force)
  25.972 -+{
  25.973 -+	if (force || (ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
  25.974 -+		      (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
  25.975 -+	    (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
  25.976 -+		iowrite8(TPM_ACCESS_ACTIVE_LOCALITY,
  25.977 -+			 chip->vendor.iobase + TPM_ACCESS(l));
  25.978 -+}
  25.979 -+
  25.980 -+static int request_locality(struct tpm_chip *chip, int l)
  25.981 -+{
  25.982 -+	unsigned long stop;
  25.983 -+	long rc;
  25.984 -+
  25.985 -+	if (check_locality(chip, l) >= 0)
  25.986 -+		return l;
  25.987 -+
  25.988 -+	iowrite8(TPM_ACCESS_REQUEST_USE,
  25.989 -+		 chip->vendor.iobase + TPM_ACCESS(l));
  25.990 -+
  25.991 -+	if (chip->vendor.irq) {
  25.992 -+		rc = wait_event_interruptible_timeout(chip->vendor.int_queue,
  25.993 -+						      (check_locality
  25.994 -+						       (chip, l) >= 0),
  25.995 -+						      chip->vendor.timeout_a);
  25.996 -+		if (rc > 0)
  25.997 -+			return l;
  25.998 -+
  25.999 -+	} else {
 25.1000 -+		/* wait for burstcount */
 25.1001 -+		stop = jiffies + chip->vendor.timeout_a;
 25.1002 -+		do {
 25.1003 -+			if (check_locality(chip, l) >= 0)
 25.1004 -+				return l;
 25.1005 -+			msleep(TPM_TIMEOUT);
 25.1006 -+		}
 25.1007 -+		while (time_before(jiffies, stop));
 25.1008 -+	}
 25.1009 -+	return -1;
 25.1010 -+}
 25.1011 -+
 25.1012 -+static u8 tpm_tis_status(struct tpm_chip *chip)
 25.1013 -+{
 25.1014 -+	return ioread8(chip->vendor.iobase +
 25.1015 -+		       TPM_STS(chip->vendor.locality));
 25.1016 -+}
 25.1017 -+
 25.1018 -+static void tpm_tis_ready(struct tpm_chip *chip)
 25.1019 -+{
 25.1020 -+	/* this causes the current command to be aborted */
 25.1021 -+	iowrite8(TPM_STS_COMMAND_READY,
 25.1022 -+		 chip->vendor.iobase + TPM_STS(chip->vendor.locality));
 25.1023 -+}
 25.1024 -+
 25.1025 -+static int get_burstcount(struct tpm_chip *chip)
 25.1026 -+{
 25.1027 -+	unsigned long stop;
 25.1028 -+	int burstcnt;
 25.1029 -+
 25.1030 -+	/* wait for burstcount */
 25.1031 -+	/* which timeout value, spec has 2 answers (c & d) */
 25.1032 -+	stop = jiffies + chip->vendor.timeout_d;
 25.1033 -+	do {
 25.1034 -+		burstcnt = ioread8(chip->vendor.iobase +
 25.1035 -+				   TPM_STS(chip->vendor.locality) + 1);
 25.1036 -+		burstcnt += ioread8(chip->vendor.iobase +
 25.1037 -+				    TPM_STS(chip->vendor.locality) +
 25.1038 -+				    2) << 8;
 25.1039 -+		if (burstcnt)
 25.1040 -+			return burstcnt;
 25.1041 -+		msleep(TPM_TIMEOUT);
 25.1042 -+	} while (time_before(jiffies, stop));
 25.1043 -+	return -EBUSY;
 25.1044 -+}
 25.1045 -+
 25.1046 -+static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
 25.1047 -+			 wait_queue_head_t *queue)
 25.1048 -+{
 25.1049 -+	unsigned long stop;
 25.1050 -+	long rc;
 25.1051 -+	u8 status;
 25.1052 -+
 25.1053 -+	/* check current status */
 25.1054 -+	status = tpm_tis_status(chip);
 25.1055 -+	if ((status & mask) == mask)
 25.1056 -+		return 0;
 25.1057 -+
 25.1058 -+	if (chip->vendor.irq) {
 25.1059 -+		rc = wait_event_interruptible_timeout(*queue,
 25.1060 -+						      ((tpm_tis_status
 25.1061 -+							(chip) & mask) ==
 25.1062 -+						       mask), timeout);
 25.1063 -+		if (rc > 0)
 25.1064 -+			return 0;
 25.1065 -+	} else {
 25.1066 -+		stop = jiffies + timeout;
 25.1067 -+		do {
 25.1068 -+			msleep(TPM_TIMEOUT);
 25.1069 -+			status = tpm_tis_status(chip);
 25.1070 -+			if ((status & mask) == mask)
 25.1071 -+				return 0;
 25.1072 -+		} while (time_before(jiffies, stop));
 25.1073 -+	}
 25.1074 -+	return -ETIME;
 25.1075 -+}
 25.1076 -+
 25.1077 -+static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
 25.1078 -+{
 25.1079 -+	int size = 0, burstcnt;
 25.1080 -+	while (size < count &&
 25.1081 -+	       wait_for_stat(chip,
 25.1082 -+			     TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 25.1083 -+			     chip->vendor.timeout_c,
 25.1084 -+			     &chip->vendor.read_queue)
 25.1085 -+	       == 0) {
 25.1086 -+		burstcnt = get_burstcount(chip);
 25.1087 -+		for (; burstcnt > 0 && size < count; burstcnt--)
 25.1088 -+			buf[size++] = ioread8(chip->vendor.iobase +
 25.1089 -+					      TPM_DATA_FIFO(chip->vendor.
 25.1090 -+							    locality));
 25.1091 -+	}
 25.1092 -+	return size;
 25.1093 -+}
 25.1094 -+
 25.1095 -+static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 25.1096 -+{
 25.1097 -+	int size = 0;
 25.1098 -+	int expected, status;
 25.1099 -+
 25.1100 -+	if (count < TPM_HEADER_SIZE) {
 25.1101 -+		size = -EIO;
 25.1102 -+		goto out;
 25.1103 -+	}
 25.1104 -+
 25.1105 -+	/* read first 10 bytes, including tag, paramsize, and result */
 25.1106 -+	if ((size =
 25.1107 -+	     recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
 25.1108 -+		dev_err(chip->dev, "Unable to read header\n");
 25.1109 -+		goto out;
 25.1110 -+	}
 25.1111 -+
 25.1112 -+	expected = be32_to_cpu(*(__be32 *) (buf + 2));
 25.1113 -+	if (expected > count) {
 25.1114 -+		size = -EIO;
 25.1115 -+		goto out;
 25.1116 -+	}
 25.1117 -+
 25.1118 -+	if ((size +=
 25.1119 -+	     recv_data(chip, &buf[TPM_HEADER_SIZE],
 25.1120 -+		       expected - TPM_HEADER_SIZE)) < expected) {
 25.1121 -+		dev_err(chip->dev, "Unable to read remainder of result\n");
 25.1122 -+		size = -ETIME;
 25.1123 -+		goto out;
 25.1124 -+	}
 25.1125 -+
 25.1126 -+	wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
 25.1127 -+		      &chip->vendor.int_queue);
 25.1128 -+	status = tpm_tis_status(chip);
 25.1129 -+	if (status & TPM_STS_DATA_AVAIL) {	/* retry? */
 25.1130 -+		dev_err(chip->dev, "Error left over data\n");
 25.1131 -+		size = -EIO;
 25.1132 -+		goto out;
 25.1133 -+	}
 25.1134 -+
 25.1135 -+out:
 25.1136 -+	tpm_tis_ready(chip);
 25.1137 -+	release_locality(chip, chip->vendor.locality, 0);
 25.1138 -+	return size;
 25.1139 -+}
 25.1140 -+
 25.1141 -+/*
 25.1142 -+ * If interrupts are used (signaled by an irq set in the vendor structure)
 25.1143 -+ * tpm.c can skip polling for the data to be available as the interrupt is
 25.1144 -+ * waited for here
 25.1145 -+ */
 25.1146 -+static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
 25.1147 -+{
 25.1148 -+	int rc, status, burstcnt;
 25.1149 -+	size_t count = 0;
 25.1150 -+	u32 ordinal;
 25.1151 -+
 25.1152 -+	if (request_locality(chip, 0) < 0)
 25.1153 -+		return -EBUSY;
 25.1154 -+
 25.1155 -+	status = tpm_tis_status(chip);
 25.1156 -+	if ((status & TPM_STS_COMMAND_READY) == 0) {
 25.1157 -+		tpm_tis_ready(chip);
 25.1158 -+		if (wait_for_stat
 25.1159 -+		    (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
 25.1160 -+		     &chip->vendor.int_queue) < 0) {
 25.1161 -+			rc = -ETIME;
 25.1162 -+			goto out_err;
 25.1163 -+		}
 25.1164 -+	}
 25.1165 -+
 25.1166 -+	while (count < len - 1) {
 25.1167 -+		burstcnt = get_burstcount(chip);
 25.1168 -+		for (; burstcnt > 0 && count < len - 1; burstcnt--) {
 25.1169 -+			iowrite8(buf[count], chip->vendor.iobase +
 25.1170 -+				 TPM_DATA_FIFO(chip->vendor.locality));
 25.1171 -+			count++;
 25.1172 -+		}
 25.1173 -+
 25.1174 -+		wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
 25.1175 -+			      &chip->vendor.int_queue);
 25.1176 -+		status = tpm_tis_status(chip);
 25.1177 -+		if ((status & TPM_STS_DATA_EXPECT) == 0) {
 25.1178 -+			rc = -EIO;
 25.1179 -+			goto out_err;
 25.1180 -+		}
 25.1181 -+	}
 25.1182 -+
 25.1183 -+	/* write last byte */
 25.1184 -+	iowrite8(buf[count],
 25.1185 -+		 chip->vendor.iobase +
 25.1186 -+		 TPM_DATA_FIFO(chip->vendor.locality));
 25.1187 -+	wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
 25.1188 -+		      &chip->vendor.int_queue);
 25.1189 -+	status = tpm_tis_status(chip);
 25.1190 -+	if ((status & TPM_STS_DATA_EXPECT) != 0) {
 25.1191 -+		rc = -EIO;
 25.1192 -+		goto out_err;
 25.1193 -+	}
 25.1194 -+
 25.1195 -+	/* go and do it */
 25.1196 -+	iowrite8(TPM_STS_GO,
 25.1197 -+		 chip->vendor.iobase + TPM_STS(chip->vendor.locality));
 25.1198 -+
 25.1199 -+	if (chip->vendor.irq) {
 25.1200 -+		ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
 25.1201 -+		if (wait_for_stat
 25.1202 -+		    (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 25.1203 -+		     tpm_calc_ordinal_duration(chip, ordinal),
 25.1204 -+		     &chip->vendor.read_queue) < 0) {
 25.1205 -+			rc = -ETIME;
 25.1206 -+			goto out_err;
 25.1207 -+		}
 25.1208 -+	}
 25.1209 -+	return len;
 25.1210 -+out_err:
 25.1211 -+	tpm_tis_ready(chip);
 25.1212 -+	release_locality(chip, chip->vendor.locality, 0);
 25.1213 -+	return rc;
 25.1214 -+}
 25.1215 -+
 25.1216 -+static struct file_operations tis_ops = {
 25.1217 -+	.owner = THIS_MODULE,
 25.1218 -+	.llseek = no_llseek,
 25.1219 -+	.open = tpm_open,
 25.1220 -+	.read = tpm_read,
 25.1221 -+	.write = tpm_write,
 25.1222 -+	.release = tpm_release,
 25.1223 -+};
 25.1224 -+
 25.1225 -+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
 25.1226 -+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
 25.1227 -+static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
 25.1228 -+static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
 25.1229 -+static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
 25.1230 -+static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
 25.1231 -+		   NULL);
 25.1232 -+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
 25.1233 -+static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
 25.1234 -+
 25.1235 -+static struct attribute *tis_attrs[] = {
 25.1236 -+	&dev_attr_pubek.attr,
 25.1237 -+	&dev_attr_pcrs.attr,
 25.1238 -+	&dev_attr_enabled.attr,
 25.1239 -+	&dev_attr_active.attr,
 25.1240 -+	&dev_attr_owned.attr,
 25.1241 -+	&dev_attr_temp_deactivated.attr,
 25.1242 -+	&dev_attr_caps.attr,
 25.1243 -+	&dev_attr_cancel.attr, NULL,
 25.1244 -+};
 25.1245 -+
 25.1246 -+static struct attribute_group tis_attr_grp = {
 25.1247 -+	.attrs = tis_attrs
 25.1248 -+};
 25.1249 -+
 25.1250 -+static struct tpm_vendor_specific tpm_tis = {
 25.1251 -+	.status = tpm_tis_status,
 25.1252 -+	.recv = tpm_tis_recv,
 25.1253 -+	.send = tpm_tis_send,
 25.1254 -+	.cancel = tpm_tis_ready,
 25.1255 -+	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 25.1256 -+	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 25.1257 -+	.req_canceled = TPM_STS_COMMAND_READY,
 25.1258 -+	.attr_group = &tis_attr_grp,
 25.1259 -+	.miscdev = {
 25.1260 -+		    .fops = &tis_ops,},
 25.1261 -+};
 25.1262 -+
 25.1263 -+static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs)
 25.1264 -+{
 25.1265 -+	struct tpm_chip *chip = (struct tpm_chip *) dev_id;
 25.1266 -+	u32 interrupt;
 25.1267 -+
 25.1268 -+	interrupt = ioread32(chip->vendor.iobase +
 25.1269 -+			     TPM_INT_STATUS(chip->vendor.locality));
 25.1270 -+
 25.1271 -+	if (interrupt == 0)
 25.1272 -+		return IRQ_NONE;
 25.1273 -+
 25.1274 -+	chip->vendor.irq = irq;
 25.1275 -+
 25.1276 -+	/* Clear interrupts handled with TPM_EOI */
 25.1277 -+	iowrite32(interrupt,
 25.1278 -+		  chip->vendor.iobase +
 25.1279 -+		  TPM_INT_STATUS(chip->vendor.locality));
 25.1280 -+	return IRQ_HANDLED;
 25.1281 -+}
 25.1282 -+
 25.1283 -+static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs)
 25.1284 -+{
 25.1285 -+	struct tpm_chip *chip = (struct tpm_chip *) dev_id;
 25.1286 -+	u32 interrupt;
 25.1287 -+	int i;
 25.1288 -+
 25.1289 -+	interrupt = ioread32(chip->vendor.iobase +
 25.1290 -+			     TPM_INT_STATUS(chip->vendor.locality));
 25.1291 -+
 25.1292 -+	if (interrupt == 0)
 25.1293 -+		return IRQ_NONE;
 25.1294 -+
 25.1295 -+	if (interrupt & TPM_INTF_DATA_AVAIL_INT)
 25.1296 -+		wake_up_interruptible(&chip->vendor.read_queue);
 25.1297 -+	if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
 25.1298 -+		for (i = 0; i < 5; i++)
 25.1299 -+			if (check_locality(chip, i) >= 0)
 25.1300 -+				break;
 25.1301 -+	if (interrupt &
 25.1302 -+	    (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
 25.1303 -+	     TPM_INTF_CMD_READY_INT))
 25.1304 -+		wake_up_interruptible(&chip->vendor.int_queue);
 25.1305 -+
 25.1306 -+	/* Clear interrupts handled with TPM_EOI */
 25.1307 -+	iowrite32(interrupt,
 25.1308 -+		  chip->vendor.iobase +
 25.1309 -+		  TPM_INT_STATUS(chip->vendor.locality));
 25.1310 -+	return IRQ_HANDLED;
 25.1311 -+}
 25.1312 -+
 25.1313 -+static int interrupts = 1;
 25.1314 -+module_param(interrupts, bool, 0444);
 25.1315 -+MODULE_PARM_DESC(interrupts, "Enable interrupts");
 25.1316 -+
 25.1317 -+static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
 25.1318 -+				      const struct pnp_device_id *pnp_id)
 25.1319 -+{
 25.1320 -+	u32 vendor, intfcaps, intmask;
 25.1321 -+	int rc, i;
 25.1322 -+	unsigned long start, len;
 25.1323 -+	struct tpm_chip *chip;
 25.1324 -+
 25.1325 -+	start = pnp_mem_start(pnp_dev, 0);
 25.1326 -+	len = pnp_mem_len(pnp_dev, 0);
 25.1327 -+
 25.1328 -+	if (!start)
 25.1329 -+		start = TIS_MEM_BASE;
 25.1330 -+	if (!len)
 25.1331 -+		len = TIS_MEM_LEN;
 25.1332 -+
 25.1333 -+	if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
 25.1334 -+		return -ENODEV;
 25.1335 -+
 25.1336 -+	chip->vendor.iobase = ioremap(start, len);
 25.1337 -+	if (!chip->vendor.iobase) {
 25.1338 -+		rc = -EIO;
 25.1339 -+		goto out_err;
 25.1340 -+	}
 25.1341 -+
 25.1342 -+	vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
 25.1343 -+
 25.1344 -+	/* Default timeouts */
 25.1345 -+	chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
 25.1346 -+	chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
 25.1347 -+	chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
 25.1348 -+	chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
 25.1349 -+
 25.1350 -+	dev_info(&pnp_dev->dev,
 25.1351 -+		 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
 25.1352 -+		 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
 25.1353 -+
 25.1354 -+	/* Figure out the capabilities */
 25.1355 -+	intfcaps =
 25.1356 -+	    ioread32(chip->vendor.iobase +
 25.1357 -+		     TPM_INTF_CAPS(chip->vendor.locality));
 25.1358 -+	dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
 25.1359 -+		intfcaps);
 25.1360 -+	if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
 25.1361 -+		dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
 25.1362 -+	if (intfcaps & TPM_INTF_CMD_READY_INT)
 25.1363 -+		dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
 25.1364 -+	if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
 25.1365 -+		dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
 25.1366 -+	if (intfcaps & TPM_INTF_INT_EDGE_RISING)
 25.1367 -+		dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
 25.1368 -+	if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
 25.1369 -+		dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
 25.1370 -+	if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
 25.1371 -+		dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
 25.1372 -+	if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
 25.1373 -+		dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
 25.1374 -+	if (intfcaps & TPM_INTF_STS_VALID_INT)
 25.1375 -+		dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
 25.1376 -+	if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
 25.1377 -+		dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
 25.1378 -+
 25.1379 -+	if (request_locality(chip, 0) != 0) {
 25.1380 -+		rc = -ENODEV;
 25.1381 -+		goto out_err;
 25.1382 -+	}
 25.1383 -+
 25.1384 -+	/* INTERRUPT Setup */
 25.1385 -+	init_waitqueue_head(&chip->vendor.read_queue);
 25.1386 -+	init_waitqueue_head(&chip->vendor.int_queue);
 25.1387 -+
 25.1388 -+	intmask =
 25.1389 -+	    ioread32(chip->vendor.iobase +
 25.1390 -+		     TPM_INT_ENABLE(chip->vendor.locality));
 25.1391 -+
 25.1392 -+	intmask |= TPM_INTF_CMD_READY_INT
 25.1393 -+	    | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
 25.1394 -+	    | TPM_INTF_STS_VALID_INT;
 25.1395 -+
 25.1396 -+	iowrite32(intmask,
 25.1397 -+		  chip->vendor.iobase +
 25.1398 -+		  TPM_INT_ENABLE(chip->vendor.locality));
 25.1399 -+	if (interrupts) {
 25.1400 -+		chip->vendor.irq =
 25.1401 -+		    ioread8(chip->vendor.iobase +
 25.1402 -+			    TPM_INT_VECTOR(chip->vendor.locality));
 25.1403 -+
 25.1404 -+		for (i = 3; i < 16 && chip->vendor.irq == 0; i++) {
 25.1405 -+			iowrite8(i, chip->vendor.iobase +
 25.1406 -+				    TPM_INT_VECTOR(chip->vendor.locality));
 25.1407 -+			if (request_irq
 25.1408 -+			    (i, tis_int_probe, SA_SHIRQ,
 25.1409 -+			     chip->vendor.miscdev.name, chip) != 0) {
 25.1410 -+				dev_info(chip->dev,
 25.1411 -+					 "Unable to request irq: %d for probe\n",
 25.1412 -+					 i);
 25.1413 -+				continue;
 25.1414 -+			}
 25.1415 -+
 25.1416 -+			/* Clear all existing */
 25.1417 -+			iowrite32(ioread32
 25.1418 -+				  (chip->vendor.iobase +
 25.1419 -+				   TPM_INT_STATUS(chip->vendor.locality)),
 25.1420 -+				  chip->vendor.iobase +
 25.1421 -+				  TPM_INT_STATUS(chip->vendor.locality));
 25.1422 -+
 25.1423 -+			/* Turn on */
 25.1424 -+			iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
 25.1425 -+				  chip->vendor.iobase +
 25.1426 -+				  TPM_INT_ENABLE(chip->vendor.locality));
 25.1427 -+
 25.1428 -+			/* Generate Interrupts */
 25.1429 -+			tpm_gen_interrupt(chip);
 25.1430 -+
 25.1431 -+			/* Turn off */
 25.1432 -+			iowrite32(intmask,
 25.1433 -+				  chip->vendor.iobase +
 25.1434 -+				  TPM_INT_ENABLE(chip->vendor.locality));
 25.1435 -+			free_irq(i, chip);
 25.1436 -+		}
 25.1437 -+	}
 25.1438 -+	if (chip->vendor.irq) {
 25.1439 -+		iowrite8(chip->vendor.irq,
 25.1440 -+			 chip->vendor.iobase +
 25.1441 -+			 TPM_INT_VECTOR(chip->vendor.locality));
 25.1442 -+		if (request_irq
 25.1443 -+		    (chip->vendor.irq, tis_int_handler, SA_SHIRQ,
 25.1444 -+		     chip->vendor.miscdev.name, chip) != 0) {
 25.1445 -+			dev_info(chip->dev,
 25.1446 -+				 "Unable to request irq: %d for use\n",
 25.1447 -+				 chip->vendor.irq);
 25.1448 -+			chip->vendor.irq = 0;
 25.1449 -+		} else {
 25.1450 -+			/* Clear all existing */
 25.1451 -+			iowrite32(ioread32
 25.1452 -+				  (chip->vendor.iobase +
 25.1453 -+				   TPM_INT_STATUS(chip->vendor.locality)),
 25.1454 -+				  chip->vendor.iobase +
 25.1455 -+				  TPM_INT_STATUS(chip->vendor.locality));
 25.1456 -+
 25.1457 -+			/* Turn on */
 25.1458 -+			iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
 25.1459 -+				  chip->vendor.iobase +
 25.1460 -+				  TPM_INT_ENABLE(chip->vendor.locality));
 25.1461 -+		}
 25.1462 -+	}
 25.1463 -+
 25.1464 -+	INIT_LIST_HEAD(&chip->vendor.list);
 25.1465 -+	spin_lock(&tis_lock);
 25.1466 -+	list_add(&chip->vendor.list, &tis_chips);
 25.1467 -+	spin_unlock(&tis_lock);
 25.1468 -+
 25.1469 -+	tpm_get_timeouts(chip);
 25.1470 -+	tpm_continue_selftest(chip);
 25.1471 -+
 25.1472 -+	return 0;
 25.1473 -+out_err:
 25.1474 -+	if (chip->vendor.iobase)
 25.1475 -+		iounmap(chip->vendor.iobase);
 25.1476 -+	tpm_remove_hardware(chip->dev);
 25.1477 -+	return rc;
 25.1478 -+}
 25.1479 -+
 25.1480 -+static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
 25.1481 -+{
 25.1482 -+	return tpm_pm_suspend(&dev->dev, msg);
 25.1483 -+}
 25.1484 -+
 25.1485 -+static int tpm_tis_pnp_resume(struct pnp_dev *dev)
 25.1486 -+{
 25.1487 -+	return tpm_pm_resume(&dev->dev);
 25.1488 -+}
 25.1489 -+
 25.1490 -+static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
 25.1491 -+	{"PNP0C31", 0},		/* TPM */
 25.1492 -+	{"ATM1200", 0},		/* Atmel */
 25.1493 -+	{"IFX0102", 0},		/* Infineon */
 25.1494 -+	{"BCM0101", 0},		/* Broadcom */
 25.1495 -+	{"NSC1200", 0},		/* National */
 25.1496 -+	/* Add new here */
 25.1497 -+	{"", 0},		/* User Specified */
 25.1498 -+	{"", 0}			/* Terminator */
 25.1499 -+};
 25.1500 -+
 25.1501 -+static struct pnp_driver tis_pnp_driver = {
 25.1502 -+	.name = "tpm_tis",
 25.1503 -+	.id_table = tpm_pnp_tbl,
 25.1504 -+	.probe = tpm_tis_pnp_init,
 25.1505 -+	.suspend = tpm_tis_pnp_suspend,
 25.1506 -+	.resume = tpm_tis_pnp_resume,
 25.1507 -+};
 25.1508 -+
 25.1509 -+#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
 25.1510 -+module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
 25.1511 -+		    sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
 25.1512 -+MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
 25.1513 -+
 25.1514 -+static int __init init_tis(void)
 25.1515 -+{
 25.1516 -+	return pnp_register_driver(&tis_pnp_driver);
 25.1517 -+}
 25.1518 -+
 25.1519 -+static void __exit cleanup_tis(void)
 25.1520 -+{
 25.1521 -+	struct tpm_vendor_specific *i, *j;
 25.1522 -+	struct tpm_chip *chip;
 25.1523 -+	spin_lock(&tis_lock);
 25.1524 -+	list_for_each_entry_safe(i, j, &tis_chips, list) {
 25.1525 -+		chip = to_tpm_chip(i);
 25.1526 -+		iowrite32(~TPM_GLOBAL_INT_ENABLE &
 25.1527 -+			  ioread32(chip->vendor.iobase +
 25.1528 -+				   TPM_INT_ENABLE(chip->vendor.
 25.1529 -+						  locality)),
 25.1530 -+			  chip->vendor.iobase +
 25.1531 -+			  TPM_INT_ENABLE(chip->vendor.locality));
 25.1532 -+		release_locality(chip, chip->vendor.locality, 1);
 25.1533 -+		if (chip->vendor.irq)
 25.1534 -+			free_irq(chip->vendor.irq, chip);
 25.1535 -+		iounmap(i->iobase);
 25.1536 -+		list_del(&i->list);
 25.1537 -+		tpm_remove_hardware(chip->dev);
 25.1538 -+	}
 25.1539 -+	spin_unlock(&tis_lock);
 25.1540 -+	pnp_unregister_driver(&tis_pnp_driver);
 25.1541 -+}
 25.1542 -+
 25.1543 -+module_init(init_tis);
 25.1544 -+module_exit(cleanup_tis);
 25.1545 -+MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
 25.1546 -+MODULE_DESCRIPTION("TPM Driver");
 25.1547 -+MODULE_VERSION("2.0");
 25.1548 -+MODULE_LICENSE("GPL");
    26.1 --- a/patches/linux-2.6.16.31/x86-elfnote-as-preprocessor-macro.patch	Mon Nov 27 13:50:02 2006 +0000
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,43 +0,0 @@
    26.4 -diff -pruN ../orig-linux-2.6.16.29/include/linux/elfnote.h ./include/linux/elfnote.h
    26.5 ---- ../orig-linux-2.6.16.29/include/linux/elfnote.h	2006-09-19 14:06:10.000000000 +0100
    26.6 -+++ ./include/linux/elfnote.h	2006-09-19 14:06:20.000000000 +0100
    26.7 -@@ -31,22 +31,24 @@
    26.8 - /*
    26.9 -  * Generate a structure with the same shape as Elf{32,64}_Nhdr (which
   26.10 -  * turn out to be the same size and shape), followed by the name and
   26.11 -- * desc data with appropriate padding.  The 'desc' argument includes
   26.12 -- * the assembler pseudo op defining the type of the data: .asciz
   26.13 -- * "hello, world"
   26.14 -+ * desc data with appropriate padding.  The 'desctype' argument is the
   26.15 -+ * assembler pseudo op defining the type of the data e.g. .asciz while
   26.16 -+ * 'descdata' is the data itself e.g.  "hello, world".
   26.17 -+ *
   26.18 -+ * e.g. ELFNOTE(XYZCo, 42, .asciz, "forty-two")
   26.19 -+ *      ELFNOTE(XYZCo, 12, .long, 0xdeadbeef)
   26.20 -  */
   26.21 --.macro ELFNOTE name type desc:vararg
   26.22 --.pushsection ".note.\name"
   26.23 --  .align 4
   26.24 --  .long 2f - 1f			/* namesz */
   26.25 --  .long 4f - 3f			/* descsz */
   26.26 --  .long \type
   26.27 --1:.asciz "\name"
   26.28 --2:.align 4
   26.29 --3:\desc
   26.30 --4:.align 4
   26.31 --.popsection
   26.32 --.endm
   26.33 -+#define ELFNOTE(name, type, desctype, descdata)	\
   26.34 -+.pushsection .note.name			;	\
   26.35 -+  .align 4				;	\
   26.36 -+  .long 2f - 1f		/* namesz */	;	\
   26.37 -+  .long 4f - 3f		/* descsz */	;	\
   26.38 -+  .long type				;	\
   26.39 -+1:.asciz "name"				;	\
   26.40 -+2:.align 4				;	\
   26.41 -+3:desctype descdata			;	\
   26.42 -+4:.align 4				;	\
   26.43 -+.popsection				;
   26.44 - #else	/* !__ASSEMBLER__ */
   26.45 - #include <linux/elf.h>
   26.46 - /*
    27.1 --- a/patches/linux-2.6.16.31/x86-increase-interrupt-vector-range.patch	Mon Nov 27 13:50:02 2006 +0000
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,89 +0,0 @@
    27.4 -diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/entry.S ./arch/i386/kernel/entry.S
    27.5 ---- ../orig-linux-2.6.16.29/arch/i386/kernel/entry.S	2006-09-19 14:05:44.000000000 +0100
    27.6 -+++ ./arch/i386/kernel/entry.S	2006-09-19 14:05:56.000000000 +0100
    27.7 -@@ -406,7 +406,7 @@ vector=0
    27.8 - ENTRY(irq_entries_start)
    27.9 - .rept NR_IRQS
   27.10 - 	ALIGN
   27.11 --1:	pushl $vector-256
   27.12 -+1:	pushl $~(vector)
   27.13 - 	jmp common_interrupt
   27.14 - .data
   27.15 - 	.long 1b
   27.16 -@@ -423,7 +423,7 @@ common_interrupt:
   27.17 - 
   27.18 - #define BUILD_INTERRUPT(name, nr)	\
   27.19 - ENTRY(name)				\
   27.20 --	pushl $nr-256;			\
   27.21 -+	pushl $~(nr);			\
   27.22 - 	SAVE_ALL			\
   27.23 - 	movl %esp,%eax;			\
   27.24 - 	call smp_/**/name;		\
   27.25 -diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/irq.c ./arch/i386/kernel/irq.c
   27.26 ---- ../orig-linux-2.6.16.29/arch/i386/kernel/irq.c	2006-09-12 19:02:10.000000000 +0100
   27.27 -+++ ./arch/i386/kernel/irq.c	2006-09-19 14:05:56.000000000 +0100
   27.28 -@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPU
   27.29 -  */
   27.30 - fastcall unsigned int do_IRQ(struct pt_regs *regs)
   27.31 - {	
   27.32 --	/* high bits used in ret_from_ code */
   27.33 --	int irq = regs->orig_eax & 0xff;
   27.34 -+	/* high bit used in ret_from_ code */
   27.35 -+	int irq = ~regs->orig_eax;
   27.36 - #ifdef CONFIG_4KSTACKS
   27.37 - 	union irq_ctx *curctx, *irqctx;
   27.38 - 	u32 *isp;
   27.39 -diff -pruN ../orig-linux-2.6.16.29/arch/x86_64/kernel/entry.S ./arch/x86_64/kernel/entry.S
   27.40 ---- ../orig-linux-2.6.16.29/arch/x86_64/kernel/entry.S	2006-09-12 19:02:10.000000000 +0100
   27.41 -+++ ./arch/x86_64/kernel/entry.S	2006-09-19 14:05:56.000000000 +0100
   27.42 -@@ -596,7 +596,7 @@ retint_kernel:	
   27.43 -  */		
   27.44 - 	.macro apicinterrupt num,func
   27.45 - 	INTR_FRAME
   27.46 --	pushq $\num-256
   27.47 -+	pushq $~(\num)
   27.48 - 	CFI_ADJUST_CFA_OFFSET 8
   27.49 - 	interrupt \func
   27.50 - 	jmp ret_from_intr
   27.51 -diff -pruN ../orig-linux-2.6.16.29/arch/x86_64/kernel/irq.c ./arch/x86_64/kernel/irq.c
   27.52 ---- ../orig-linux-2.6.16.29/arch/x86_64/kernel/irq.c	2006-09-12 19:02:10.000000000 +0100
   27.53 -+++ ./arch/x86_64/kernel/irq.c	2006-09-19 14:05:56.000000000 +0100
   27.54 -@@ -96,8 +96,8 @@ skip:
   27.55 -  */
   27.56 - asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
   27.57 - {	
   27.58 --	/* high bits used in ret_from_ code  */
   27.59 --	unsigned irq = regs->orig_rax & 0xff;
   27.60 -+	/* high bit used in ret_from_ code  */
   27.61 -+	unsigned irq = ~regs->orig_rax;
   27.62 - 
   27.63 - 	exit_idle();
   27.64 - 	irq_enter();
   27.65 -diff -pruN ../orig-linux-2.6.16.29/arch/x86_64/kernel/smp.c ./arch/x86_64/kernel/smp.c
   27.66 ---- ../orig-linux-2.6.16.29/arch/x86_64/kernel/smp.c	2006-09-12 19:02:10.000000000 +0100
   27.67 -+++ ./arch/x86_64/kernel/smp.c	2006-09-19 14:05:56.000000000 +0100
   27.68 -@@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt
   27.69 - 
   27.70 - 	cpu = smp_processor_id();
   27.71 - 	/*
   27.72 --	 * orig_rax contains the interrupt vector - 256.
   27.73 -+	 * orig_rax contains the negated interrupt vector.
   27.74 - 	 * Use that to determine where the sender put the data.
   27.75 - 	 */
   27.76 --	sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START;
   27.77 -+	sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
   27.78 - 	f = &per_cpu(flush_state, sender);
   27.79 - 
   27.80 - 	if (!cpu_isset(cpu, f->flush_cpumask))
   27.81 -diff -pruN ../orig-linux-2.6.16.29/include/asm-x86_64/hw_irq.h ./include/asm-x86_64/hw_irq.h
   27.82 ---- ../orig-linux-2.6.16.29/include/asm-x86_64/hw_irq.h	2006-09-12 19:02:10.000000000 +0100
   27.83 -+++ ./include/asm-x86_64/hw_irq.h	2006-09-19 14:05:56.000000000 +0100
   27.84 -@@ -127,7 +127,7 @@ asmlinkage void IRQ_NAME(nr); \
   27.85 - __asm__( \
   27.86 - "\n.p2align\n" \
   27.87 - "IRQ" #nr "_interrupt:\n\t" \
   27.88 --	"push $" #nr "-256 ; " \
   27.89 -+	"push $~(" #nr ") ; " \
   27.90 - 	"jmp common_interrupt");
   27.91 - 
   27.92 - #if defined(CONFIG_X86_IO_APIC)
    28.1 --- a/patches/linux-2.6.16.31/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch	Mon Nov 27 13:50:02 2006 +0000
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,143 +0,0 @@
    28.4 -diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/vmlinux.lds.S ./arch/i386/kernel/vmlinux.lds.S
    28.5 ---- ../orig-linux-2.6.16.29/arch/i386/kernel/vmlinux.lds.S	2006-09-19 14:05:48.000000000 +0100
    28.6 -+++ ./arch/i386/kernel/vmlinux.lds.S	2006-09-19 14:06:10.000000000 +0100
    28.7 -@@ -12,6 +12,12 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386"
    28.8 - OUTPUT_ARCH(i386)
    28.9 - ENTRY(phys_startup_32)
   28.10 - jiffies = jiffies_64;
   28.11 -+
   28.12 -+PHDRS {
   28.13 -+	text PT_LOAD FLAGS(5);	/* R_E */
   28.14 -+	data PT_LOAD FLAGS(7);	/* RWE */
   28.15 -+	note PT_NOTE FLAGS(4);	/* R__ */
   28.16 -+}
   28.17 - SECTIONS
   28.18 - {
   28.19 -   . = __KERNEL_START;
   28.20 -@@ -25,7 +31,7 @@ SECTIONS
   28.21 - 	KPROBES_TEXT
   28.22 - 	*(.fixup)
   28.23 - 	*(.gnu.warning)
   28.24 --	} = 0x9090
   28.25 -+	} :text = 0x9090
   28.26 - 
   28.27 -   _etext = .;			/* End of text section */
   28.28 - 
   28.29 -@@ -47,7 +53,7 @@ SECTIONS
   28.30 -   .data : AT(ADDR(.data) - LOAD_OFFSET) {	/* Data */
   28.31 - 	*(.data)
   28.32 - 	CONSTRUCTORS
   28.33 --	}
   28.34 -+	} :data
   28.35 - 
   28.36 -   . = ALIGN(4096);
   28.37 -   __nosave_begin = .;
   28.38 -@@ -154,4 +160,6 @@ SECTIONS
   28.39 -   STABS_DEBUG
   28.40 - 
   28.41 -   DWARF_DEBUG
   28.42 -+
   28.43 -+  NOTES
   28.44 - }
   28.45 -diff -pruN ../orig-linux-2.6.16.29/include/asm-generic/vmlinux.lds.h ./include/asm-generic/vmlinux.lds.h
   28.46 ---- ../orig-linux-2.6.16.29/include/asm-generic/vmlinux.lds.h	2006-09-12 19:02:10.000000000 +0100
   28.47 -+++ ./include/asm-generic/vmlinux.lds.h	2006-09-19 14:06:10.000000000 +0100
   28.48 -@@ -152,3 +152,6 @@
   28.49 - 		.stab.index 0 : { *(.stab.index) }			\
   28.50 - 		.stab.indexstr 0 : { *(.stab.indexstr) }		\
   28.51 - 		.comment 0 : { *(.comment) }
   28.52 -+
   28.53 -+#define NOTES								\
   28.54 -+		.notes : { *(.note.*) } :note
   28.55 -diff -pruN ../orig-linux-2.6.16.29/include/linux/elfnote.h ./include/linux/elfnote.h
   28.56 ---- ../orig-linux-2.6.16.29/include/linux/elfnote.h	1970-01-01 01:00:00.000000000 +0100
   28.57 -+++ ./include/linux/elfnote.h	2006-09-19 14:06:10.000000000 +0100
   28.58 -@@ -0,0 +1,88 @@
   28.59 -+#ifndef _LINUX_ELFNOTE_H
   28.60 -+#define _LINUX_ELFNOTE_H
   28.61 -+/*
   28.62 -+ * Helper macros to generate ELF Note structures, which are put into a
   28.63 -+ * PT_NOTE segment of the final vmlinux image.  These are useful for
   28.64 -+ * including name-value pairs of metadata into the kernel binary (or
   28.65 -+ * modules?) for use by external programs.
   28.66 -+ *
   28.67 -+ * Each note has three parts: a name, a type and a desc.  The name is
   28.68 -+ * intended to distinguish the note's originator, so it would be a
   28.69 -+ * company, project, subsystem, etc; it must be in a suitable form for
   28.70 -+ * use in a section name.  The type is an integer which is used to tag
   28.71 -+ * the data, and is considered to be within the "name" namespace (so
   28.72 -+ * "FooCo"'s type 42 is distinct from "BarProj"'s type 42).  The
   28.73 -+ * "desc" field is the actual data.  There are no constraints on the
   28.74 -+ * desc field's contents, though typically they're fairly small.
   28.75 -+ *
   28.76 -+ * All notes from a given NAME are put into a section named
   28.77 -+ * .note.NAME.  When the kernel image is finally linked, all the notes
   28.78 -+ * are packed into a single .notes section, which is mapped into the
   28.79 -+ * PT_NOTE segment.  Because notes for a given name are grouped into
   28.80 -+ * the same section, they'll all be adjacent the output file.
   28.81 -+ *
   28.82 -+ * This file defines macros for both C and assembler use.  Their
   28.83 -+ * syntax is slightly different, but they're semantically similar.
   28.84 -+ *
   28.85 -+ * See the ELF specification for more detail about ELF notes.
   28.86 -+ */
   28.87 -+
   28.88 -+#ifdef __ASSEMBLER__
   28.89 -+/*
   28.90 -+ * Generate a structure with the same shape as Elf{32,64}_Nhdr (which
   28.91 -+ * turn out to be the same size and shape), followed by the name and
   28.92 -+ * desc data with appropriate padding.  The 'desc' argument includes
   28.93 -+ * the assembler pseudo op defining the type of the data: .asciz
   28.94 -+ * "hello, world"
   28.95 -+ */
   28.96 -+.macro ELFNOTE name type desc:vararg
   28.97 -+.pushsection ".note.\name"
   28.98 -+  .align 4
   28.99 -+  .long 2f - 1f			/* namesz */
  28.100 -+  .long 4f - 3f			/* descsz */
  28.101 -+  .long \type
  28.102 -+1:.asciz "\name"
  28.103 -+2:.align 4
  28.104 -+3:\desc
  28.105 -+4:.align 4
  28.106 -+.popsection
  28.107 -+.endm
  28.108 -+#else	/* !__ASSEMBLER__ */
  28.109 -+#include <linux/elf.h>
  28.110 -+/*
  28.111 -+ * Use an anonymous structure which matches the shape of
  28.112 -+ * Elf{32,64}_Nhdr, but includes the name and desc data.  The size and
  28.113 -+ * type of name and desc depend on the macro arguments.  "name" must
  28.114 -+ * be a literal string, and "desc" must be passed by value.  You may
  28.115 -+ * only define one note per line, since __LINE__ is used to generate
  28.116 -+ * unique symbols.
  28.117 -+ */
  28.118 -+#define _ELFNOTE_PASTE(a,b)	a##b
  28.119 -+#define _ELFNOTE(size, name, unique, type, desc)			\
  28.120 -+	static const struct {						\
  28.121 -+		struct elf##size##_note _nhdr;				\
  28.122 -+		unsigned char _name[sizeof(name)]			\
  28.123 -+		__attribute__((aligned(sizeof(Elf##size##_Word))));	\
  28.124 -+		typeof(desc) _desc					\
  28.125 -+			     __attribute__((aligned(sizeof(Elf##size##_Word)))); \
  28.126 -+	} _ELFNOTE_PASTE(_note_, unique)				\
  28.127 -+		__attribute_used__					\
  28.128 -+		__attribute__((section(".note." name),			\
  28.129 -+			       aligned(sizeof(Elf##size##_Word)),	\
  28.130 -+			       unused)) = {				\
  28.131 -+		{							\
  28.132 -+			sizeof(name),					\
  28.133 -+			sizeof(desc),					\
  28.134 -+			type,						\
  28.135 -+		},							\
  28.136 -+		name,							\
  28.137 -+		desc							\
  28.138 -+	}
  28.139 -+#define ELFNOTE(size, name, type, desc)		\
  28.140 -+	_ELFNOTE(size, name, __LINE__, type, desc)
  28.141 -+
  28.142 -+#define ELFNOTE32(name, type, desc) ELFNOTE(32, name, type, desc)
  28.143 -+#define ELFNOTE64(name, type, desc) ELFNOTE(64, name, type, desc)
  28.144 -+#endif	/* __ASSEMBLER__ */
  28.145 -+
  28.146 -+#endif /* _LINUX_ELFNOTE_H */
    29.1 --- a/patches/linux-2.6.16.31/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch	Mon Nov 27 13:50:02 2006 +0000
    29.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.3 @@ -1,84 +0,0 @@
    29.4 -diff -pruN ../orig-linux-2.6.16.29/arch/x86_64/kernel/vmlinux.lds.S ./arch/x86_64/kernel/vmlinux.lds.S
    29.5 ---- ../orig-linux-2.6.16.29/arch/x86_64/kernel/vmlinux.lds.S	2006-09-12 19:02:10.000000000 +0100
    29.6 -+++ ./arch/x86_64/kernel/vmlinux.lds.S	2006-09-19 14:06:15.000000000 +0100
    29.7 -@@ -14,6 +14,12 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86
    29.8 - OUTPUT_ARCH(i386:x86-64)
    29.9 - ENTRY(phys_startup_64)
   29.10 - jiffies_64 = jiffies;
   29.11 -+PHDRS {
   29.12 -+	text PT_LOAD FLAGS(5);	/* R_E */
   29.13 -+	data PT_LOAD FLAGS(7);	/* RWE */
   29.14 -+	user PT_LOAD FLAGS(7);	/* RWE */
   29.15 -+	note PT_NOTE FLAGS(4);	/* R__ */
   29.16 -+}
   29.17 - SECTIONS
   29.18 - {
   29.19 -   . = __START_KERNEL;
   29.20 -@@ -26,7 +32,7 @@ SECTIONS
   29.21 - 	KPROBES_TEXT
   29.22 - 	*(.fixup)
   29.23 - 	*(.gnu.warning)
   29.24 --	} = 0x9090
   29.25 -+	} :text = 0x9090
   29.26 -   				/* out-of-line lock text */
   29.27 -   .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) }
   29.28 - 
   29.29 -@@ -43,17 +49,10 @@ SECTIONS
   29.30 -   .data : AT(ADDR(.data) - LOAD_OFFSET) {
   29.31 - 	*(.data)
   29.32 - 	CONSTRUCTORS
   29.33 --	}
   29.34 -+	} :data
   29.35 - 
   29.36 -   _edata = .;			/* End of data section */
   29.37 - 
   29.38 --  __bss_start = .;		/* BSS */
   29.39 --  .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
   29.40 --	*(.bss.page_aligned)	
   29.41 --	*(.bss)
   29.42 --	}
   29.43 --  __bss_stop = .;
   29.44 --
   29.45 -   . = ALIGN(PAGE_SIZE);
   29.46 -   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
   29.47 -   .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
   29.48 -@@ -75,7 +74,7 @@ SECTIONS
   29.49 - #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
   29.50 - 
   29.51 -   . = VSYSCALL_ADDR;
   29.52 --  .vsyscall_0 :	 AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) }
   29.53 -+  .vsyscall_0 :	 AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } :user
   29.54 -   __vsyscall_0 = VSYSCALL_VIRT_ADDR;
   29.55 - 
   29.56 -   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
   29.57 -@@ -118,7 +117,7 @@ SECTIONS
   29.58 -   . = ALIGN(8192);		/* init_task */
   29.59 -   .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
   29.60 - 	*(.data.init_task)
   29.61 --  }
   29.62 -+  } :data
   29.63 - 
   29.64 -   . = ALIGN(4096);
   29.65 -   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
   29.66 -@@ -188,6 +187,14 @@ SECTIONS
   29.67 -   . = ALIGN(4096);
   29.68 -   __nosave_end = .;
   29.69 - 
   29.70 -+  __bss_start = .;		/* BSS */
   29.71 -+  . = ALIGN(4096);
   29.72 -+  .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
   29.73 -+	*(.bss.page_aligned)
   29.74 -+	*(.bss)
   29.75 -+	}
   29.76 -+  __bss_stop = .;
   29.77 -+
   29.78 -   _end = . ;
   29.79 - 
   29.80 -   /* Sections to be discarded */
   29.81 -@@ -201,4 +208,6 @@ SECTIONS
   29.82 -   STABS_DEBUG
   29.83 - 
   29.84 -   DWARF_DEBUG
   29.85 -+
   29.86 -+  NOTES
   29.87 - }
    30.1 --- a/patches/linux-2.6.16.31/xen-hotplug.patch	Mon Nov 27 13:50:02 2006 +0000
    30.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.3 @@ -1,12 +0,0 @@
    30.4 -diff -pruN ../orig-linux-2.6.16.29/fs/proc/proc_misc.c ./fs/proc/proc_misc.c
    30.5 ---- ../orig-linux-2.6.16.29/fs/proc/proc_misc.c	2006-09-12 19:02:10.000000000 +0100
    30.6 -+++ ./fs/proc/proc_misc.c	2006-09-19 14:06:00.000000000 +0100
    30.7 -@@ -433,7 +433,7 @@ static int show_stat(struct seq_file *p,
    30.8 - 		(unsigned long long)cputime64_to_clock_t(irq),
    30.9 - 		(unsigned long long)cputime64_to_clock_t(softirq),
   30.10 - 		(unsigned long long)cputime64_to_clock_t(steal));
   30.11 --	for_each_online_cpu(i) {
   30.12 -+	for_each_cpu(i) {
   30.13 - 
   30.14 - 		/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
   30.15 - 		user = kstat_cpu(i).cpustat.user;
    31.1 --- a/patches/linux-2.6.16.31/xenoprof-generic.patch	Mon Nov 27 13:50:02 2006 +0000
    31.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.3 @@ -1,662 +0,0 @@
    31.4 -diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/buffer_sync.c ./drivers/oprofile/buffer_sync.c
    31.5 ---- ../orig-linux-2.6.16.29/drivers/oprofile/buffer_sync.c	2006-11-06 14:46:52.000000000 -0800
    31.6 -+++ ./drivers/oprofile/buffer_sync.c	2006-11-06 15:16:52.000000000 -0800
    31.7 -@@ -6,6 +6,10 @@
    31.8 -  *
    31.9 -  * @author John Levon <levon@movementarian.org>
   31.10 -  *
   31.11 -+ * Modified by Aravind Menon for Xen
   31.12 -+ * These modifications are:
   31.13 -+ * Copyright (C) 2005 Hewlett-Packard Co.
   31.14 -+ *
   31.15 -  * This is the core of the buffer management. Each
   31.16 -  * CPU buffer is processed and entered into the
   31.17 -  * global event buffer. Such processing is necessary
   31.18 -@@ -38,6 +42,7 @@ static cpumask_t marked_cpus = CPU_MASK_
   31.19 - static DEFINE_SPINLOCK(task_mortuary);
   31.20 - static void process_task_mortuary(void);
   31.21 - 
   31.22 -+static int cpu_current_domain[NR_CPUS];
   31.23 - 
   31.24 - /* Take ownership of the task struct and place it on the
   31.25 -  * list for processing. Only after two full buffer syncs
   31.26 -@@ -146,6 +151,11 @@ static void end_sync(void)
   31.27 - int sync_start(void)
   31.28 - {
   31.29 - 	int err;
   31.30 -+	int i;
   31.31 -+
   31.32 -+	for (i = 0; i < NR_CPUS; i++) {
   31.33 -+		cpu_current_domain[i] = COORDINATOR_DOMAIN;
   31.34 -+	}
   31.35 - 
   31.36 - 	start_cpu_work();
   31.37 - 
   31.38 -@@ -275,15 +285,31 @@ static void add_cpu_switch(int i)
   31.39 - 	last_cookie = INVALID_COOKIE;
   31.40 - }
   31.41 - 
   31.42 --static void add_kernel_ctx_switch(unsigned int in_kernel)
   31.43 -+static void add_cpu_mode_switch(unsigned int cpu_mode)
   31.44 - {
   31.45 - 	add_event_entry(ESCAPE_CODE);
   31.46 --	if (in_kernel)
   31.47 --		add_event_entry(KERNEL_ENTER_SWITCH_CODE); 
   31.48 --	else
   31.49 --		add_event_entry(KERNEL_EXIT_SWITCH_CODE); 
   31.50 -+	switch (cpu_mode) {
   31.51 -+	case CPU_MODE_USER:
   31.52 -+		add_event_entry(USER_ENTER_SWITCH_CODE);
   31.53 -+		break;
   31.54 -+	case CPU_MODE_KERNEL:
   31.55 -+		add_event_entry(KERNEL_ENTER_SWITCH_CODE);
   31.56 -+		break;
   31.57 -+	case CPU_MODE_XEN:
   31.58 -+		add_event_entry(XEN_ENTER_SWITCH_CODE);
   31.59 -+	  	break;
   31.60 -+	default:
   31.61 -+		break;
   31.62 -+	}
   31.63 - }
   31.64 -- 
   31.65 -+
   31.66 -+static void add_domain_switch(unsigned long domain_id)
   31.67 -+{
   31.68 -+	add_event_entry(ESCAPE_CODE);
   31.69 -+	add_event_entry(DOMAIN_SWITCH_CODE);
   31.70 -+	add_event_entry(domain_id);
   31.71 -+}
   31.72 -+
   31.73 - static void
   31.74 - add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
   31.75 - {
   31.76 -@@ -348,9 +374,9 @@ static int add_us_sample(struct mm_struc
   31.77 -  * for later lookup from userspace.
   31.78 -  */
   31.79 - static int
   31.80 --add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
   31.81 -+add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode)
   31.82 - {
   31.83 --	if (in_kernel) {
   31.84 -+	if (cpu_mode >= CPU_MODE_KERNEL) {
   31.85 - 		add_sample_entry(s->eip, s->event);
   31.86 - 		return 1;
   31.87 - 	} else if (mm) {
   31.88 -@@ -496,15 +522,21 @@ void sync_buffer(int cpu)
   31.89 - 	struct mm_struct *mm = NULL;
   31.90 - 	struct task_struct * new;
   31.91 - 	unsigned long cookie = 0;
   31.92 --	int in_kernel = 1;
   31.93 -+	int cpu_mode = 1;
   31.94 - 	unsigned int i;
   31.95 - 	sync_buffer_state state = sb_buffer_start;
   31.96 - 	unsigned long available;
   31.97 -+	int domain_switch = 0;
   31.98 - 
   31.99 - 	down(&buffer_sem);
  31.100 -  
  31.101 - 	add_cpu_switch(cpu);
  31.102 - 
  31.103 -+	/* We need to assign the first samples in this CPU buffer to the
  31.104 -+	   same domain that we were processing at the last sync_buffer */
  31.105 -+	if (cpu_current_domain[cpu] != COORDINATOR_DOMAIN) {
  31.106 -+		add_domain_switch(cpu_current_domain[cpu]);
  31.107 -+	}
  31.108 - 	/* Remember, only we can modify tail_pos */
  31.109 - 
  31.110 - 	available = get_slots(cpu_buf);
  31.111 -@@ -512,16 +544,18 @@ void sync_buffer(int cpu)
  31.112 - 	for (i = 0; i < available; ++i) {
  31.113 - 		struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
  31.114 -  
  31.115 --		if (is_code(s->eip)) {
  31.116 --			if (s->event <= CPU_IS_KERNEL) {
  31.117 --				/* kernel/userspace switch */
  31.118 --				in_kernel = s->event;
  31.119 -+		if (is_code(s->eip) && !domain_switch) {
  31.120 -+			if (s->event <= CPU_MODE_XEN) {
  31.121 -+				/* xen/kernel/userspace switch */
  31.122 -+				cpu_mode = s->event;
  31.123 - 				if (state == sb_buffer_start)
  31.124 - 					state = sb_sample_start;
  31.125 --				add_kernel_ctx_switch(s->event);
  31.126 -+				add_cpu_mode_switch(s->event);
  31.127 - 			} else if (s->event == CPU_TRACE_BEGIN) {
  31.128 - 				state = sb_bt_start;
  31.129 - 				add_trace_begin();
  31.130 -+			} else if (s->event == CPU_DOMAIN_SWITCH) {
  31.131 -+					domain_switch = 1;				
  31.132 - 			} else {
  31.133 - 				struct mm_struct * oldmm = mm;
  31.134 - 
  31.135 -@@ -535,11 +569,21 @@ void sync_buffer(int cpu)
  31.136 - 				add_user_ctx_switch(new, cookie);
  31.137 - 			}
  31.138 - 		} else {
  31.139 --			if (state >= sb_bt_start &&
  31.140 --			    !add_sample(mm, s, in_kernel)) {
  31.141 --				if (state == sb_bt_start) {
  31.142 --					state = sb_bt_ignore;
  31.143 --					atomic_inc(&oprofile_stats.bt_lost_no_mapping);
  31.144 -+			if (domain_switch) {
  31.145 -+				cpu_current_domain[cpu] = s->eip;
  31.146 -+				add_domain_switch(s->eip);
  31.147 -+				domain_switch = 0;
  31.148 -+			} else {
  31.149 -+				if (cpu_current_domain[cpu] !=
  31.150 -+				    COORDINATOR_DOMAIN) {
  31.151 -+					add_sample_entry(s->eip, s->event);
  31.152 -+				}
  31.153 -+				else  if (state >= sb_bt_start &&
  31.154 -+				    !add_sample(mm, s, cpu_mode)) {
  31.155 -+					if (state == sb_bt_start) {
  31.156 -+						state = sb_bt_ignore;
  31.157 -+						atomic_inc(&oprofile_stats.bt_lost_no_mapping);
  31.158 -+					}
  31.159 - 				}
  31.160 - 			}
  31.161 - 		}
  31.162 -@@ -548,6 +592,11 @@ void sync_buffer(int cpu)
  31.163 - 	}
  31.164 - 	release_mm(mm);
  31.165 - 
  31.166 -+	/* We reset domain to COORDINATOR at each CPU switch */
  31.167 -+	if (cpu_current_domain[cpu] != COORDINATOR_DOMAIN) {
  31.168 -+		add_domain_switch(COORDINATOR_DOMAIN);
  31.169 -+	}
  31.170 -+
  31.171 - 	mark_done(cpu);
  31.172 - 
  31.173 - 	up(&buffer_sem);
  31.174 -diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c
  31.175 ---- ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.c	2006-11-06 14:46:52.000000000 -0800
  31.176 -+++ ./drivers/oprofile/cpu_buffer.c	2006-11-06 14:47:55.000000000 -0800
  31.177 -@@ -6,6 +6,10 @@
  31.178 -  *
  31.179 -  * @author John Levon <levon@movementarian.org>
  31.180 -  *
  31.181 -+ * Modified by Aravind Menon for Xen
  31.182 -+ * These modifications are:
  31.183 -+ * Copyright (C) 2005 Hewlett-Packard Co.
  31.184 -+ *
  31.185 -  * Each CPU has a local buffer that stores PC value/event
  31.186 -  * pairs. We also log context switches when we notice them.
  31.187 -  * Eventually each CPU's buffer is processed into the global
  31.188 -@@ -34,6 +38,8 @@ static void wq_sync_buffer(void *);
  31.189 - #define DEFAULT_TIMER_EXPIRE (HZ / 10)
  31.190 - static int work_enabled;
  31.191 - 
  31.192 -+static int32_t current_domain = COORDINATOR_DOMAIN;
  31.193 -+
  31.194 - void free_cpu_buffers(void)
  31.195 - {
  31.196 - 	int i;
  31.197 -@@ -58,7 +64,7 @@ int alloc_cpu_buffers(void)
  31.198 - 			goto fail;
  31.199 -  
  31.200 - 		b->last_task = NULL;
  31.201 --		b->last_is_kernel = -1;
  31.202 -+		b->last_cpu_mode = -1;
  31.203 - 		b->tracing = 0;
  31.204 - 		b->buffer_size = buffer_size;
  31.205 - 		b->tail_pos = 0;
  31.206 -@@ -114,7 +120,7 @@ void cpu_buffer_reset(struct oprofile_cp
  31.207 - 	 * collected will populate the buffer with proper
  31.208 - 	 * values to initialize the buffer
  31.209 - 	 */
  31.210 --	cpu_buf->last_is_kernel = -1;
  31.211 -+	cpu_buf->last_cpu_mode = -1;
  31.212 - 	cpu_buf->last_task = NULL;
  31.213 - }
  31.214 - 
  31.215 -@@ -164,13 +170,13 @@ add_code(struct oprofile_cpu_buffer * bu
  31.216 -  * because of the head/tail separation of the writer and reader
  31.217 -  * of the CPU buffer.
  31.218 -  *
  31.219 -- * is_kernel is needed because on some architectures you cannot
  31.220 -+ * cpu_mode is needed because on some architectures you cannot
  31.221 -  * tell if you are in kernel or user space simply by looking at
  31.222 -- * pc. We tag this in the buffer by generating kernel enter/exit
  31.223 -- * events whenever is_kernel changes
  31.224 -+ * pc. We tag this in the buffer by generating kernel/user (and xen)
  31.225 -+ *  enter events whenever cpu_mode changes
  31.226 -  */
  31.227 - static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
  31.228 --		      int is_kernel, unsigned long event)
  31.229 -+		      int cpu_mode, unsigned long event)
  31.230 - {
  31.231 - 	struct task_struct * task;
  31.232 - 
  31.233 -@@ -181,18 +187,18 @@ static int log_sample(struct oprofile_cp
  31.234 - 		return 0;
  31.235 - 	}
  31.236 - 
  31.237 --	is_kernel = !!is_kernel;
  31.238 --
  31.239 - 	task = current;
  31.240 - 
  31.241 - 	/* notice a switch from user->kernel or vice versa */
  31.242 --	if (cpu_buf->last_is_kernel != is_kernel) {
  31.243 --		cpu_buf->last_is_kernel = is_kernel;
  31.244 --		add_code(cpu_buf, is_kernel);
  31.245 -+	if (cpu_buf->last_cpu_mode != cpu_mode) {
  31.246 -+		cpu_buf->last_cpu_mode = cpu_mode;
  31.247 -+		add_code(cpu_buf, cpu_mode);
  31.248 - 	}
  31.249 --
  31.250 -+	
  31.251 - 	/* notice a task switch */
  31.252 --	if (cpu_buf->last_task != task) {
  31.253 -+	/* if not processing other domain samples */
  31.254 -+	if ((cpu_buf->last_task != task) &&
  31.255 -+	    (current_domain == COORDINATOR_DOMAIN)) {
  31.256 - 		cpu_buf->last_task = task;
  31.257 - 		add_code(cpu_buf, (unsigned long)task);
  31.258 - 	}
  31.259 -@@ -269,6 +275,25 @@ void oprofile_add_trace(unsigned long pc
  31.260 - 	add_sample(cpu_buf, pc, 0);
  31.261 - }
  31.262 - 
  31.263 -+int oprofile_add_domain_switch(int32_t domain_id)
  31.264 -+{
  31.265 -+	struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[smp_processor_id()];
  31.266 -+
  31.267 -+	/* should have space for switching into and out of domain 
  31.268 -+	   (2 slots each) plus one sample and one cpu mode switch */
  31.269 -+	if (((nr_available_slots(cpu_buf) < 6) && 
  31.270 -+	     (domain_id != COORDINATOR_DOMAIN)) ||
  31.271 -+	    (nr_available_slots(cpu_buf) < 2))
  31.272 -+		return 0;
  31.273 -+
  31.274 -+	add_code(cpu_buf, CPU_DOMAIN_SWITCH);
  31.275 -+	add_sample(cpu_buf, domain_id, 0);
  31.276 -+
  31.277 -+	current_domain = domain_id;
  31.278 -+
  31.279 -+	return 1;
  31.280 -+}
  31.281 -+
  31.282 - /*
  31.283 -  * This serves to avoid cpu buffer overflow, and makes sure
  31.284 -  * the task mortuary progresses
  31.285 -diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.h ./drivers/oprofile/cpu_buffer.h
  31.286 ---- ../orig-linux-2.6.16.29/drivers/oprofile/cpu_buffer.h	2006-11-06 14:46:52.000000000 -0800
  31.287 -+++ ./drivers/oprofile/cpu_buffer.h	2006-11-06 14:47:55.000000000 -0800
  31.288 -@@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
  31.289 - 	volatile unsigned long tail_pos;
  31.290 - 	unsigned long buffer_size;
  31.291 - 	struct task_struct * last_task;
  31.292 --	int last_is_kernel;
  31.293 -+	int last_cpu_mode;
  31.294 - 	int tracing;
  31.295 - 	struct op_sample * buffer;
  31.296 - 	unsigned long sample_received;
  31.297 -@@ -51,7 +51,10 @@ extern struct oprofile_cpu_buffer cpu_bu
  31.298 - void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
  31.299 - 
  31.300 - /* transient events for the CPU buffer -> event buffer */
  31.301 --#define CPU_IS_KERNEL 1
  31.302 --#define CPU_TRACE_BEGIN 2
  31.303 -+#define CPU_MODE_USER           0
  31.304 -+#define CPU_MODE_KERNEL         1
  31.305 -+#define CPU_MODE_XEN            2
  31.306 -+#define CPU_TRACE_BEGIN         3
  31.307 -+#define CPU_DOMAIN_SWITCH       4
  31.308 - 
  31.309 - #endif /* OPROFILE_CPU_BUFFER_H */
  31.310 -diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/event_buffer.h ./drivers/oprofile/event_buffer.h
  31.311 ---- ../orig-linux-2.6.16.29/drivers/oprofile/event_buffer.h	2006-11-06 14:46:52.000000000 -0800
  31.312 -+++ ./drivers/oprofile/event_buffer.h	2006-11-06 14:47:55.000000000 -0800
  31.313 -@@ -29,15 +29,20 @@ void wake_up_buffer_waiter(void);
  31.314 - #define CPU_SWITCH_CODE 		2
  31.315 - #define COOKIE_SWITCH_CODE 		3
  31.316 - #define KERNEL_ENTER_SWITCH_CODE	4
  31.317 --#define KERNEL_EXIT_SWITCH_CODE		5
  31.318 -+#define USER_ENTER_SWITCH_CODE		5
  31.319 - #define MODULE_LOADED_CODE		6
  31.320 - #define CTX_TGID_CODE			7
  31.321 - #define TRACE_BEGIN_CODE		8
  31.322 - #define TRACE_END_CODE			9
  31.323 -+#define XEN_ENTER_SWITCH_CODE		10
  31.324 -+#define DOMAIN_SWITCH_CODE		11
  31.325 -  
  31.326 - #define INVALID_COOKIE ~0UL
  31.327 - #define NO_COOKIE 0UL
  31.328 - 
  31.329 -+/* Constant used to refer to coordinator domain (Xen) */
  31.330 -+#define COORDINATOR_DOMAIN -1
  31.331 -+
  31.332 - /* add data to the event buffer */
  31.333 - void add_event_entry(unsigned long data);
  31.334 -  
  31.335 -diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/oprof.c ./drivers/oprofile/oprof.c
  31.336 ---- ../orig-linux-2.6.16.29/drivers/oprofile/oprof.c	2006-11-06 14:46:52.000000000 -0800
  31.337 -+++ ./drivers/oprofile/oprof.c	2006-11-06 14:47:55.000000000 -0800
  31.338 -@@ -5,6 +5,10 @@
  31.339 -  * @remark Read the file COPYING
  31.340 -  *
  31.341 -  * @author John Levon <levon@movementarian.org>
  31.342 -+ *
  31.343 -+ * Modified by Aravind Menon for Xen
  31.344 -+ * These modifications are:
  31.345 -+ * Copyright (C) 2005 Hewlett-Packard Co.
  31.346 -  */
  31.347 - 
  31.348 - #include <linux/kernel.h>
  31.349 -@@ -19,7 +23,7 @@
  31.350 - #include "cpu_buffer.h"
  31.351 - #include "buffer_sync.h"
  31.352 - #include "oprofile_stats.h"
  31.353 -- 
  31.354 -+
  31.355 - struct oprofile_operations oprofile_ops;
  31.356 - 
  31.357 - unsigned long oprofile_started;
  31.358 -@@ -33,6 +37,32 @@ static DECLARE_MUTEX(start_sem);
  31.359 -  */
  31.360 - static int timer = 0;
  31.361 - 
  31.362 -+int oprofile_set_active(int active_domains[], unsigned int adomains)
  31.363 -+{
  31.364 -+	int err;
  31.365 -+
  31.366 -+	if (!oprofile_ops.set_active)
  31.367 -+		return -EINVAL;
  31.368 -+
  31.369 -+	down(&start_sem);
  31.370 -+	err = oprofile_ops.set_active(active_domains, adomains);
  31.371 -+	up(&start_sem);
  31.372 -+	return err;
  31.373 -+}
  31.374 -+
  31.375 -+int oprofile_set_passive(int passive_domains[], unsigned int pdomains)
  31.376 -+{
  31.377 -+	int err;
  31.378 -+
  31.379 -+	if (!oprofile_ops.set_passive)
  31.380 -+		return -EINVAL;
  31.381 -+
  31.382 -+	down(&start_sem);
  31.383 -+	err = oprofile_ops.set_passive(passive_domains, pdomains);
  31.384 -+	up(&start_sem);
  31.385 -+	return err;
  31.386 -+}
  31.387 -+
  31.388 - int oprofile_setup(void)
  31.389 - {
  31.390 - 	int err;
  31.391 -diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/oprof.h ./drivers/oprofile/oprof.h
  31.392 ---- ../orig-linux-2.6.16.29/drivers/oprofile/oprof.h	2006-11-06 14:46:52.000000000 -0800
  31.393 -+++ ./drivers/oprofile/oprof.h	2006-11-06 14:47:55.000000000 -0800
  31.394 -@@ -35,5 +35,8 @@ void oprofile_create_files(struct super_
  31.395 - void oprofile_timer_init(struct oprofile_operations * ops);
  31.396 - 
  31.397 - int oprofile_set_backtrace(unsigned long depth);
  31.398 -+
  31.399 -+int oprofile_set_active(int active_domains[], unsigned int adomains);
  31.400 -+int oprofile_set_passive(int passive_domains[], unsigned int pdomains);
  31.401 -  
  31.402 - #endif /* OPROF_H */
  31.403 -diff -pruN ../orig-linux-2.6.16.29/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c
  31.404 ---- ../orig-linux-2.6.16.29/drivers/oprofile/oprofile_files.c	2006-11-06 14:46:52.000000000 -0800
  31.405 -+++ ./drivers/oprofile/oprofile_files.c	2006-11-06 14:47:55.000000000 -0800
  31.406 -@@ -5,15 +5,21 @@
  31.407 -  * @remark Read the file COPYING
  31.408 -  *
  31.409 -  * @author John Levon <levon@movementarian.org>
  31.410 -+ *
  31.411 -+ * Modified by Aravind Menon for Xen
  31.412 -+ * These modifications are:
  31.413 -+ * Copyright (C) 2005 Hewlett-Packard Co.	
  31.414 -  */
  31.415 - 
  31.416 - #include <linux/fs.h>
  31.417 - #include <linux/oprofile.h>
  31.418 -+#include <asm/uaccess.h>
  31.419 -+#include <linux/ctype.h>
  31.420 - 
  31.421 - #include "event_buffer.h"
  31.422 - #include "oprofile_stats.h"
  31.423 - #include "oprof.h"
  31.424 -- 
  31.425 -+
  31.426 - unsigned long fs_buffer_size = 131072;
  31.427 - unsigned long fs_cpu_buffer_size = 8192;
  31.428 - unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
  31.429 -@@ -117,11 +123,202 @@ static ssize_t dump_write(struct file * 
  31.430 - static struct file_operations dump_fops = {
  31.431 - 	.write		= dump_write,
  31.432 - };
  31.433 -- 
  31.434 -+
  31.435 -+#define TMPBUFSIZE 512
  31.436 -+
  31.437 -+static unsigned int adomains = 0;
  31.438 -+static int active_domains[MAX_OPROF_DOMAINS + 1];
  31.439 -+static DEFINE_MUTEX(adom_mutex);
  31.440 -+
  31.441 -+static ssize_t adomain_write(struct file * file, char const __user * buf, 
  31.442 -+			     size_t count, loff_t * offset)
  31.443 -+{
  31.444 -+	char *tmpbuf;
  31.445 -+	char *startp, *endp;
  31.446 -+	int i;
  31.447 -+	unsigned long val;
  31.448 -+	ssize_t retval = count;
  31.449 -+	
  31.450 -+	if (*offset)
  31.451 -+		return -EINVAL;	
  31.452 -+	if (count > TMPBUFSIZE - 1)
  31.453 -+		return -EINVAL;
  31.454 -+
  31.455 -+	if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
  31.456 -+		return -ENOMEM;
  31.457 -+
  31.458 -+	if (copy_from_user(tmpbuf, buf, count)) {
  31.459 -+		kfree(tmpbuf);
  31.460 -+		return -EFAULT;
  31.461 -+	}
  31.462 -+	tmpbuf[count] = 0;
  31.463 -+
  31.464 -+	mutex_lock(&adom_mutex);
  31.465 -+
  31.466 -+	startp = tmpbuf;
  31.467 -+	/* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
  31.468 -+	for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
  31.469 -+		val = simple_strtoul(startp, &endp, 0);
  31.470 -+		if (endp == startp)
  31.471 -+			break;
  31.472 -+		while (ispunct(*endp) || isspace(*endp))
  31.473 -+			endp++;
  31.474 -+		active_domains[i] = val;
  31.475 -+		if (active_domains[i] != val)
  31.476 -+			/* Overflow, force error below */
  31.477 -+			i = MAX_OPROF_DOMAINS + 1;
  31.478 -+		startp = endp;
  31.479 -+	}
  31.480 -+	/* Force error on trailing junk */
  31.481 -+	adomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
  31.482 -+
  31.483 -+	kfree(tmpbuf);
  31.484 -+
  31.485 -+	if (adomains > MAX_OPROF_DOMAINS
  31.486 -+	    || oprofile_set_active(active_domains, adomains)) {
  31.487 -+		adomains = 0;
  31.488 -+		retval = -EINVAL;
  31.489 -+	}
  31.490 -+
  31.491 -+	mutex_unlock(&adom_mutex);
  31.492 -+	return retval;
  31.493 -+}
  31.494 -+
  31.495 -+static ssize_t adomain_read(struct file * file, char __user * buf, 
  31.496 -+			    size_t count, loff_t * offset)
  31.497 -+{
  31.498 -+	char * tmpbuf;
  31.499 -+	size_t len;
  31.500 -+	int i;
  31.501 -+	ssize_t retval;
  31.502 -+
  31.503 -+	if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
  31.504 -+		return -ENOMEM;
  31.505 -+
  31.506 -+	mutex_lock(&adom_mutex);
  31.507 -+
  31.508 -+	len = 0;
  31.509 -+	for (i = 0; i < adomains; i++)
  31.510 -+		len += snprintf(tmpbuf + len,
  31.511 -+				len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
  31.512 -+				"%u ", active_domains[i]);
  31.513 -+	WARN_ON(len > TMPBUFSIZE);
  31.514 -+	if (len != 0 && len <= TMPBUFSIZE)
  31.515 -+		tmpbuf[len-1] = '\n';
  31.516 -+
  31.517 -+	mutex_unlock(&adom_mutex);
  31.518 -+
  31.519 -+	retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
  31.520 -+
  31.521 -+	kfree(tmpbuf);
  31.522 -+	return retval;
  31.523 -+}
  31.524 -+
  31.525 -+
  31.526 -+static struct file_operations active_domain_ops = {
  31.527 -+	.read		= adomain_read,
  31.528 -+	.write		= adomain_write,
  31.529 -+};
  31.530 -+
  31.531 -+static unsigned int pdomains = 0;
  31.532 -+static int passive_domains[MAX_OPROF_DOMAINS];
  31.533 -+static DEFINE_MUTEX(pdom_mutex);
  31.534 -+
  31.535 -+static ssize_t pdomain_write(struct file * file, char const __user * buf, 
  31.536 -+			     size_t count, loff_t * offset)
  31.537 -+{
  31.538 -+	char *tmpbuf;
  31.539 -+	char *startp, *endp;
  31.540 -+	int i;
  31.541 -+	unsigned long val;
  31.542 -+	ssize_t retval = count;
  31.543 -+	
  31.544 -+	if (*offset)
  31.545 -+		return -EINVAL;	
  31.546 -+	if (count > TMPBUFSIZE - 1)
  31.547 -+		return -EINVAL;
  31.548 -+
  31.549 -+	if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
  31.550 -+		return -ENOMEM;
  31.551 -+
  31.552 -+	if (copy_from_user(tmpbuf, buf, count)) {
  31.553 -+		kfree(tmpbuf);
  31.554 -+		return -EFAULT;
  31.555 -+	}
  31.556 -+	tmpbuf[count] = 0;
  31.557 -+
  31.558 -+	mutex_lock(&pdom_mutex);
  31.559 -+
  31.560 -+	startp = tmpbuf;
  31.561 -+	/* Parse one more than MAX_OPROF_DOMAINS, for easy error checking */
  31.562 -+	for (i = 0; i <= MAX_OPROF_DOMAINS; i++) {
  31.563 -+		val = simple_strtoul(startp, &endp, 0);
  31.564 -+		if (endp == startp)
  31.565 -+			break;
  31.566 -+		while (ispunct(*endp) || isspace(*endp))
  31.567 -+			endp++;
  31.568 -+		passive_domains[i] = val;
  31.569 -+		if (passive_domains[i] != val)
  31.570 -+			/* Overflow, force error below */
  31.571 -+			i = MAX_OPROF_DOMAINS + 1;
  31.572 -+		startp = endp;
  31.573 -+	}
  31.574 -+	/* Force error on trailing junk */
  31.575 -+	pdomains = *startp ? MAX_OPROF_DOMAINS + 1 : i;
  31.576 -+
  31.577 -+	kfree(tmpbuf);
  31.578 -+
  31.579 -+	if (pdomains > MAX_OPROF_DOMAINS
  31.580 -+	    || oprofile_set_passive(passive_domains, pdomains)) {
  31.581 -+		pdomains = 0;
  31.582 -+		retval = -EINVAL;
  31.583 -+	}
  31.584 -+
  31.585 -+	mutex_unlock(&pdom_mutex);
  31.586 -+	return retval;
  31.587 -+}
  31.588 -+
  31.589 -+static ssize_t pdomain_read(struct file * file, char __user * buf, 
  31.590 -+			    size_t count, loff_t * offset)
  31.591 -+{
  31.592 -+	char * tmpbuf;
  31.593 -+	size_t len;
  31.594 -+	int i;
  31.595 -+	ssize_t retval;
  31.596 -+
  31.597 -+	if (!(tmpbuf = kmalloc(TMPBUFSIZE, GFP_KERNEL)))
  31.598 -+		return -ENOMEM;
  31.599 -+
  31.600 -+	mutex_lock(&pdom_mutex);
  31.601 -+
  31.602 -+	len = 0;
  31.603 -+	for (i = 0; i < pdomains; i++)
  31.604 -+		len += snprintf(tmpbuf + len,
  31.605 -+				len < TMPBUFSIZE ? TMPBUFSIZE - len : 0,
  31.606 -+				"%u ", passive_domains[i]);
  31.607 -+	WARN_ON(len > TMPBUFSIZE);
  31.608 -+	if (len != 0 && len <= TMPBUFSIZE)
  31.609 -+		tmpbuf[len-1] = '\n';
  31.610 -+
  31.611 -+	mutex_unlock(&pdom_mutex);
  31.612 -+
  31.613 -+	retval = simple_read_from_buffer(buf, count, offset, tmpbuf, len);
  31.614 -+
  31.615 -+	kfree(tmpbuf);
  31.616 -+	return retval;
  31.617 -+}
  31.618 -+
  31.619 -+static struct file_operations passive_domain_ops = {
  31.620 -+	.read		= pdomain_read,
  31.621 -+	.write		= pdomain_write,
  31.622 -+};
  31.623 -+
  31.624 - void oprofile_create_files(struct super_block * sb, struct dentry * root)
  31.625 - {
  31.626 - 	oprofilefs_create_file(sb, root, "enable", &enable_fops);
  31.627 - 	oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
  31.628 -+	oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
  31.629 -+	oprofilefs_create_file(sb, root, "passive_domains", &passive_domain_ops);
  31.630 - 	oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
  31.631 - 	oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
  31.632 - 	oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
  31.633 -diff -pruN ../orig-linux-2.6.16.29/include/linux/oprofile.h ./include/linux/oprofile.h
  31.634 ---- ../orig-linux-2.6.16.29/include/linux/oprofile.h	2006-11-06 14:46:42.000000000 -0800
  31.635 -+++ ./include/linux/oprofile.h	2006-11-06 14:47:55.000000000 -0800
  31.636 -@@ -16,6 +16,8 @@
  31.637 - #include <linux/types.h>
  31.638 - #include <linux/spinlock.h>
  31.639 - #include <asm/atomic.h>
  31.640 -+
  31.641 -+#include <xen/interface/xenoprof.h>
  31.642 -  
  31.643 - struct super_block;
  31.644 - struct dentry;
  31.645 -@@ -27,6 +29,11 @@ struct oprofile_operations {
  31.646 - 	/* create any necessary configuration files in the oprofile fs.
  31.647 - 	 * Optional. */
  31.648 - 	int (*create_files)(struct super_block * sb, struct dentry * root);
  31.649 -+	/* setup active domains with Xen */
  31.650 -+	int (*set_active)(int *active_domains, unsigned int adomains);
  31.651 -+        /* setup passive domains with Xen */
  31.652 -+        int (*set_passive)(int *passive_domains, unsigned int pdomains);
  31.653 -+	
  31.654 - 	/* Do any necessary interrupt setup. Optional. */
  31.655 - 	int (*setup)(void);
  31.656 - 	/* Do any necessary interrupt shutdown. Optional. */
  31.657 -@@ -68,6 +75,8 @@ void oprofile_add_pc(unsigned long pc, i
  31.658 - /* add a backtrace entry, to be called from the ->backtrace callback */
  31.659 - void oprofile_add_trace(unsigned long eip);
  31.660 - 
  31.661 -+/* add a domain switch entry */
  31.662 -+int oprofile_add_domain_switch(int32_t domain_id);
  31.663 - 
  31.664 - /**
  31.665 -  * Create a file of the given name as a child of the given root, with
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/patches/linux-2.6.16.32/blktap-aio-16_03_06.patch	Mon Nov 27 13:50:02 2006 +0000
    32.3 @@ -0,0 +1,294 @@
    32.4 +diff -pruN ../orig-linux-2.6.16.29/fs/aio.c ./fs/aio.c
    32.5 +--- ../orig-linux-2.6.16.29/fs/aio.c	2006-09-12 19:02:10.000000000 +0100
    32.6 ++++ ./fs/aio.c	2006-09-19 13:58:49.000000000 +0100
    32.7 +@@ -34,6 +34,11 @@
    32.8 + #include <asm/uaccess.h>
    32.9 + #include <asm/mmu_context.h>
   32.10 + 
   32.11 ++#ifdef CONFIG_EPOLL
   32.12 ++#include <linux/poll.h>
   32.13 ++#include <linux/eventpoll.h>
   32.14 ++#endif
   32.15 ++
   32.16 + #if DEBUG > 1
   32.17 + #define dprintk		printk
   32.18 + #else
   32.19 +@@ -1016,6 +1021,10 @@ put_rq:
   32.20 + 	if (waitqueue_active(&ctx->wait))
   32.21 + 		wake_up(&ctx->wait);
   32.22 + 
   32.23 ++#ifdef CONFIG_EPOLL
   32.24 ++	if (ctx->file && waitqueue_active(&ctx->poll_wait))
   32.25 ++		wake_up(&ctx->poll_wait);
   32.26 ++#endif
   32.27 + 	if (ret)
   32.28 + 		put_ioctx(ctx);
   32.29 + 
   32.30 +@@ -1025,6 +1034,8 @@ put_rq:
   32.31 + /* aio_read_evt
   32.32 +  *	Pull an event off of the ioctx's event ring.  Returns the number of 
   32.33 +  *	events fetched (0 or 1 ;-)
   32.34 ++ *	If ent parameter is 0, just returns the number of events that would
   32.35 ++ *	be fetched.
   32.36 +  *	FIXME: make this use cmpxchg.
   32.37 +  *	TODO: make the ringbuffer user mmap()able (requires FIXME).
   32.38 +  */
   32.39 +@@ -1047,13 +1058,18 @@ static int aio_read_evt(struct kioctx *i
   32.40 + 
   32.41 + 	head = ring->head % info->nr;
   32.42 + 	if (head != ring->tail) {
   32.43 +-		struct io_event *evp = aio_ring_event(info, head, KM_USER1);
   32.44 +-		*ent = *evp;
   32.45 +-		head = (head + 1) % info->nr;
   32.46 +-		smp_mb(); /* finish reading the event before updatng the head */
   32.47 +-		ring->head = head;
   32.48 +-		ret = 1;
   32.49 +-		put_aio_ring_event(evp, KM_USER1);
   32.50 ++		if (ent) { /* event requested */
   32.51 ++			struct io_event *evp =
   32.52 ++				aio_ring_event(info, head, KM_USER1);
   32.53 ++			*ent = *evp;
   32.54 ++			head = (head + 1) % info->nr;
   32.55 ++			/* finish reading the event before updatng the head */
   32.56 ++			smp_mb();
   32.57 ++			ring->head = head;
   32.58 ++			ret = 1;
   32.59 ++			put_aio_ring_event(evp, KM_USER1);
   32.60 ++		} else /* only need to know availability */
   32.61 ++			ret = 1;
   32.62 + 	}
   32.63 + 	spin_unlock(&info->ring_lock);
   32.64 + 
   32.65 +@@ -1236,9 +1252,78 @@ static void io_destroy(struct kioctx *io
   32.66 + 
   32.67 + 	aio_cancel_all(ioctx);
   32.68 + 	wait_for_all_aios(ioctx);
   32.69 ++#ifdef CONFIG_EPOLL
   32.70 ++	/* forget the poll file, but it's up to the user to close it */
   32.71 ++	if (ioctx->file) {
   32.72 ++		ioctx->file->private_data = 0;
   32.73 ++		ioctx->file = 0;
   32.74 ++	}
   32.75 ++#endif
   32.76 + 	put_ioctx(ioctx);	/* once for the lookup */
   32.77 + }
   32.78 + 
   32.79 ++#ifdef CONFIG_EPOLL
   32.80 ++
   32.81 ++static int aio_queue_fd_close(struct inode *inode, struct file *file)
   32.82 ++{
   32.83 ++	struct kioctx *ioctx = file->private_data;
   32.84 ++	if (ioctx) {
   32.85 ++		file->private_data = 0;
   32.86 ++		spin_lock_irq(&ioctx->ctx_lock);
   32.87 ++		ioctx->file = 0;
   32.88 ++		spin_unlock_irq(&ioctx->ctx_lock);
   32.89 ++	}
   32.90 ++	return 0;
   32.91 ++}
   32.92 ++
   32.93 ++static unsigned int aio_queue_fd_poll(struct file *file, poll_table *wait)
   32.94 ++{	unsigned int pollflags = 0;
   32.95 ++	struct kioctx *ioctx = file->private_data;
   32.96 ++
   32.97 ++	if (ioctx) {
   32.98 ++
   32.99 ++		spin_lock_irq(&ioctx->ctx_lock);
  32.100 ++		/* Insert inside our poll wait queue */
  32.101 ++		poll_wait(file, &ioctx->poll_wait, wait);
  32.102 ++
  32.103 ++		/* Check our condition */
  32.104 ++		if (aio_read_evt(ioctx, 0))
  32.105 ++			pollflags = POLLIN | POLLRDNORM;
  32.106 ++		spin_unlock_irq(&ioctx->ctx_lock);
  32.107 ++	}
  32.108 ++
  32.109 ++	return pollflags;
  32.110 ++}
  32.111 ++
  32.112 ++static struct file_operations aioq_fops = {
  32.113 ++	.release	= aio_queue_fd_close,
  32.114 ++	.poll		= aio_queue_fd_poll
  32.115 ++};
  32.116 ++
  32.117 ++/* make_aio_fd:
  32.118 ++ *  Create a file descriptor that can be used to poll the event queue.
  32.119 ++ *  Based and piggybacked on the excellent epoll code.
  32.120 ++ */
  32.121 ++
  32.122 ++static int make_aio_fd(struct kioctx *ioctx)
  32.123 ++{
  32.124 ++	int error, fd;
  32.125 ++	struct inode *inode;
  32.126 ++	struct file *file;
  32.127 ++
  32.128 ++	error = ep_getfd(&fd, &inode, &file, NULL, &aioq_fops);
  32.129 ++	if (error)
  32.130 ++		return error;
  32.131 ++
  32.132 ++	/* associate the file with the IO context */
  32.133 ++	file->private_data = ioctx;
  32.134 ++	ioctx->file = file;
  32.135 ++	init_waitqueue_head(&ioctx->poll_wait);
  32.136 ++	return fd;
  32.137 ++}
  32.138 ++#endif
  32.139 ++
  32.140 ++
  32.141 + /* sys_io_setup:
  32.142 +  *	Create an aio_context capable of receiving at least nr_events.
  32.143 +  *	ctxp must not point to an aio_context that already exists, and
  32.144 +@@ -1251,18 +1336,30 @@ static void io_destroy(struct kioctx *io
  32.145 +  *	resources are available.  May fail with -EFAULT if an invalid
  32.146 +  *	pointer is passed for ctxp.  Will fail with -ENOSYS if not
  32.147 +  *	implemented.
  32.148 ++ *
  32.149 ++ *	To request a selectable fd, the user context has to be initialized
  32.150 ++ *	to 1, instead of 0, and the return value is the fd.
  32.151 ++ *	This keeps the system call compatible, since a non-zero value
  32.152 ++ *	was not allowed so far.
  32.153 +  */
  32.154 + asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp)
  32.155 + {
  32.156 + 	struct kioctx *ioctx = NULL;
  32.157 + 	unsigned long ctx;
  32.158 + 	long ret;
  32.159 ++	int make_fd = 0;
  32.160 + 
  32.161 + 	ret = get_user(ctx, ctxp);
  32.162 + 	if (unlikely(ret))
  32.163 + 		goto out;
  32.164 + 
  32.165 + 	ret = -EINVAL;
  32.166 ++#ifdef CONFIG_EPOLL
  32.167 ++	if (ctx == 1) {
  32.168 ++		make_fd = 1;
  32.169 ++		ctx = 0;
  32.170 ++	}
  32.171 ++#endif
  32.172 + 	if (unlikely(ctx || nr_events == 0)) {
  32.173 + 		pr_debug("EINVAL: io_setup: ctx %lu nr_events %u\n",
  32.174 + 		         ctx, nr_events);
  32.175 +@@ -1273,8 +1370,12 @@ asmlinkage long sys_io_setup(unsigned nr
  32.176 + 	ret = PTR_ERR(ioctx);
  32.177 + 	if (!IS_ERR(ioctx)) {
  32.178 + 		ret = put_user(ioctx->user_id, ctxp);
  32.179 +-		if (!ret)
  32.180 +-			return 0;
  32.181 ++#ifdef CONFIG_EPOLL
  32.182 ++		if (make_fd && ret >= 0)
  32.183 ++			ret = make_aio_fd(ioctx);
  32.184 ++#endif
  32.185 ++		if (ret >= 0)
  32.186 ++			return ret;
  32.187 + 
  32.188 + 		get_ioctx(ioctx); /* io_destroy() expects us to hold a ref */
  32.189 + 		io_destroy(ioctx);
  32.190 +diff -pruN ../orig-linux-2.6.16.29/fs/eventpoll.c ./fs/eventpoll.c
  32.191 +--- ../orig-linux-2.6.16.29/fs/eventpoll.c	2006-09-12 19:02:10.000000000 +0100
  32.192 ++++ ./fs/eventpoll.c	2006-09-19 13:58:49.000000000 +0100
  32.193 +@@ -235,8 +235,6 @@ struct ep_pqueue {
  32.194 + 
  32.195 + static void ep_poll_safewake_init(struct poll_safewake *psw);
  32.196 + static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
  32.197 +-static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
  32.198 +-		    struct eventpoll *ep);
  32.199 + static int ep_alloc(struct eventpoll **pep);
  32.200 + static void ep_free(struct eventpoll *ep);
  32.201 + static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
  32.202 +@@ -266,7 +264,7 @@ static int ep_events_transfer(struct eve
  32.203 + static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
  32.204 + 		   int maxevents, long timeout);
  32.205 + static int eventpollfs_delete_dentry(struct dentry *dentry);
  32.206 +-static struct inode *ep_eventpoll_inode(void);
  32.207 ++static struct inode *ep_eventpoll_inode(struct file_operations *fops);
  32.208 + static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
  32.209 + 					      int flags, const char *dev_name,
  32.210 + 					      void *data);
  32.211 +@@ -525,7 +523,7 @@ asmlinkage long sys_epoll_create(int siz
  32.212 + 	 * Creates all the items needed to setup an eventpoll file. That is,
  32.213 + 	 * a file structure, and inode and a free file descriptor.
  32.214 + 	 */
  32.215 +-	error = ep_getfd(&fd, &inode, &file, ep);
  32.216 ++	error = ep_getfd(&fd, &inode, &file, ep, &eventpoll_fops);
  32.217 + 	if (error)
  32.218 + 		goto eexit_2;
  32.219 + 
  32.220 +@@ -710,8 +708,8 @@ eexit_1:
  32.221 + /*
  32.222 +  * Creates the file descriptor to be used by the epoll interface.
  32.223 +  */
  32.224 +-static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
  32.225 +-		    struct eventpoll *ep)
  32.226 ++int ep_getfd(int *efd, struct inode **einode, struct file **efile,
  32.227 ++		    struct eventpoll *ep, struct file_operations *fops)
  32.228 + {
  32.229 + 	struct qstr this;
  32.230 + 	char name[32];
  32.231 +@@ -727,7 +725,7 @@ static int ep_getfd(int *efd, struct ino
  32.232 + 		goto eexit_1;
  32.233 + 
  32.234 + 	/* Allocates an inode from the eventpoll file system */
  32.235 +-	inode = ep_eventpoll_inode();
  32.236 ++	inode = ep_eventpoll_inode(fops);
  32.237 + 	error = PTR_ERR(inode);
  32.238 + 	if (IS_ERR(inode))
  32.239 + 		goto eexit_2;
  32.240 +@@ -758,7 +756,7 @@ static int ep_getfd(int *efd, struct ino
  32.241 + 
  32.242 + 	file->f_pos = 0;
  32.243 + 	file->f_flags = O_RDONLY;
  32.244 +-	file->f_op = &eventpoll_fops;
  32.245 ++	file->f_op = fops;
  32.246 + 	file->f_mode = FMODE_READ;
  32.247 + 	file->f_version = 0;
  32.248 + 	file->private_data = ep;
  32.249 +@@ -1574,7 +1572,7 @@ static int eventpollfs_delete_dentry(str
  32.250 + }
  32.251 + 
  32.252 + 
  32.253 +-static struct inode *ep_eventpoll_inode(void)
  32.254 ++static struct inode *ep_eventpoll_inode(struct file_operations *fops)
  32.255 + {
  32.256 + 	int error = -ENOMEM;
  32.257 + 	struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
  32.258 +@@ -1582,7 +1580,7 @@ static struct inode *ep_eventpoll_inode(
  32.259 + 	if (!inode)
  32.260 + 		goto eexit_1;
  32.261 + 
  32.262 +-	inode->i_fop = &eventpoll_fops;
  32.263 ++	inode->i_fop = fops;
  32.264 + 
  32.265 + 	/*
  32.266 + 	 * Mark the inode dirty from the very beginning,
  32.267 +diff -pruN ../orig-linux-2.6.16.29/include/linux/aio.h ./include/linux/aio.h
  32.268 +--- ../orig-linux-2.6.16.29/include/linux/aio.h	2006-09-12 19:02:10.000000000 +0100
  32.269 ++++ ./include/linux/aio.h	2006-09-19 13:58:49.000000000 +0100
  32.270 +@@ -191,6 +191,11 @@ struct kioctx {
  32.271 + 	struct aio_ring_info	ring_info;
  32.272 + 
  32.273 + 	struct work_struct	wq;
  32.274 ++#ifdef CONFIG_EPOLL
  32.275 ++	// poll integration
  32.276 ++	wait_queue_head_t       poll_wait;
  32.277 ++	struct file		*file;
  32.278 ++#endif
  32.279 + };
  32.280 + 
  32.281 + /* prototypes */
  32.282 +diff -pruN ../orig-linux-2.6.16.29/include/linux/eventpoll.h ./include/linux/eventpoll.h
  32.283 +--- ../orig-linux-2.6.16.29/include/linux/eventpoll.h	2006-09-12 19:02:10.000000000 +0100
  32.284 ++++ ./include/linux/eventpoll.h	2006-09-19 13:58:49.000000000 +0100
  32.285 +@@ -86,6 +86,12 @@ static inline void eventpoll_release(str
  32.286 + }
  32.287 + 
  32.288 + 
  32.289 ++/*
  32.290 ++ * called by aio code to create fd that can poll the  aio event queueQ
  32.291 ++ */
  32.292 ++struct eventpoll;
  32.293 ++int ep_getfd(int *efd, struct inode **einode, struct file **efile,
  32.294 ++             struct eventpoll *ep, struct file_operations *fops);
  32.295 + #else
  32.296 + 
  32.297 + static inline void eventpoll_init_file(struct file *file) {}
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/patches/linux-2.6.16.32/device_bind.patch	Mon Nov 27 13:50:02 2006 +0000
    33.3 @@ -0,0 +1,15 @@
    33.4 +diff -pruN ../orig-linux-2.6.16.29/drivers/base/bus.c ./drivers/base/bus.c
    33.5 +--- ../orig-linux-2.6.16.29/drivers/base/bus.c	2006-09-12 19:02:10.000000000 +0100
    33.6 ++++ ./drivers/base/bus.c	2006-09-19 13:58:54.000000000 +0100
    33.7 +@@ -188,6 +188,11 @@ static ssize_t driver_bind(struct device
    33.8 + 		up(&dev->sem);
    33.9 + 		if (dev->parent)
   33.10 + 			up(&dev->parent->sem);
   33.11 ++
   33.12 ++		if (err > 0) 		/* success */
   33.13 ++			err = count;
   33.14 ++		else if (err == 0)	/* driver didn't accept device */
   33.15 ++			err = -ENODEV;
   33.16 + 	}
   33.17 + 	put_device(dev);
   33.18 + 	put_bus(bus);
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/patches/linux-2.6.16.32/fix-hz-suspend.patch	Mon Nov 27 13:50:02 2006 +0000
    34.3 @@ -0,0 +1,26 @@
    34.4 +diff -pruN ../orig-linux-2.6.16.29/kernel/timer.c ./kernel/timer.c
    34.5 +--- ../orig-linux-2.6.16.29/kernel/timer.c	2006-09-12 19:02:10.000000000 +0100
    34.6 ++++ ./kernel/timer.c	2006-09-19 13:58:58.000000000 +0100
    34.7 +@@ -555,6 +555,22 @@ found:
    34.8 + 	}
    34.9 + 	spin_unlock(&base->t_base.lock);
   34.10 + 
   34.11 ++	/*
   34.12 ++	 * It can happen that other CPUs service timer IRQs and increment
   34.13 ++	 * jiffies, but we have not yet got a local timer tick to process
   34.14 ++	 * the timer wheels.  In that case, the expiry time can be before
   34.15 ++	 * jiffies, but since the high-resolution timer here is relative to
   34.16 ++	 * jiffies, the default expression when high-resolution timers are
   34.17 ++	 * not active,
   34.18 ++	 *
   34.19 ++	 *   time_before(MAX_JIFFY_OFFSET + jiffies, expires)
   34.20 ++	 *
   34.21 ++	 * would falsely evaluate to true.  If that is the case, just
   34.22 ++	 * return jiffies so that we can immediately fire the local timer
   34.23 ++	 */
   34.24 ++	if (time_before(expires, jiffies))
   34.25 ++		return jiffies;
   34.26 ++
   34.27 + 	if (time_before(hr_expires, expires))
   34.28 + 		return hr_expires;
   34.29 + 
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/patches/linux-2.6.16.32/fix-ide-cd-pio-mode.patch	Mon Nov 27 13:50:02 2006 +0000
    35.3 @@ -0,0 +1,18 @@
    35.4 +diff -pruN ../orig-linux-2.6.16.29/drivers/ide/ide-lib.c ./drivers/ide/ide-lib.c
    35.5 +--- ../orig-linux-2.6.16.29/drivers/ide/ide-lib.c	2006-09-12 19:02:10.000000000 +0100
    35.6 ++++ ./drivers/ide/ide-lib.c	2006-09-19 13:59:03.000000000 +0100
    35.7 +@@ -410,10 +410,10 @@ void ide_toggle_bounce(ide_drive_t *driv
    35.8 + {
    35.9 + 	u64 addr = BLK_BOUNCE_HIGH;	/* dma64_addr_t */
   35.10 + 
   35.11 +-	if (!PCI_DMA_BUS_IS_PHYS) {
   35.12 +-		addr = BLK_BOUNCE_ANY;
   35.13 +-	} else if (on && drive->media == ide_disk) {
   35.14 +-		if (HWIF(drive)->pci_dev)
   35.15 ++	if (on && drive->media == ide_disk) {
   35.16 ++		if (!PCI_DMA_BUS_IS_PHYS)
   35.17 ++			addr = BLK_BOUNCE_ANY;
   35.18 ++		else if (HWIF(drive)->pci_dev)
   35.19 + 			addr = HWIF(drive)->pci_dev->dma_mask;
   35.20 + 	}
   35.21 + 
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/patches/linux-2.6.16.32/i386-mach-io-check-nmi.patch	Mon Nov 27 13:50:02 2006 +0000
    36.3 @@ -0,0 +1,45 @@
    36.4 +diff -pruN ../orig-linux-2.6.16.29/arch/i386/kernel/traps.c ./arch/i386/kernel/traps.c
    36.5 +--- ../orig-linux-2.6.16.29/arch/i386/kernel/traps.c	2006-09-12 19:02:10.000000000 +0100
    36.6 ++++ ./arch/i386/kernel/traps.c	2006-09-19 13:59:06.000000000 +0100
    36.7 +@@ -567,18 +567,11 @@ static void mem_parity_error(unsigned ch
    36.8 + 
    36.9 + static void io_check_error(unsigned char reason, struct pt_regs * regs)
   36.10 + {
   36.11 +-	unsigned long i;
   36.12 +-
   36.13 + 	printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n");
   36.14 + 	show_registers(regs);
   36.15 + 
   36.16 + 	/* Re-enable the IOCK line, wait for a few seconds */
   36.17 +-	reason = (reason & 0xf) | 8;
   36.18 +-	outb(reason, 0x61);
   36.19 +-	i = 2000;
   36.20 +-	while (--i) udelay(1000);
   36.21 +-	reason &= ~8;
   36.22 +-	outb(reason, 0x61);
   36.23 ++	clear_io_check_error(reason);
   36.24 + }
   36.25 + 
   36.26 + static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
   36.27 +diff -pruN ../orig-linux-2.6.16.29/include/asm-i386/mach-default/mach_traps.h ./include/asm-i386/mach-default/mach_traps.h
   36.28 +--- ../orig-linux-2.6.16.29/include/asm-i386/mach-default/mach_traps.h	2006-09-12 19:02:10.000000000 +0100
   36.29 ++++ ./include/asm-i386/mach-default/mach_traps.h	2006-09-19 13:59:06.000000000 +0100
   36.30 +@@ -15,6 +15,18 @@ static inline void clear_mem_error(unsig
   36.31 + 	outb(reason, 0x61);
   36.32 + }
   36.33 + 
   36.34 ++static inline void clear_io_check_error(unsigned char reason)
   36.35 ++{
   36.36 ++	unsigned long i;
   36.37 ++
   36.38 ++	reason = (reason & 0xf) | 8;
   36.39 ++	outb(reason, 0x61);
   36.40 ++	i = 2000;
   36.41 ++	while (--i) udelay(1000);
   36.42 ++	reason &= ~8;
   36.43 ++	outb(reason, 0x61);
   36.44 ++}
   36.45 ++
   36.46 + static inline unsigned char get_nmi_reason(void)
   36.47 + {
   36.48 + 	return inb(0x61);
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/patches/linux-2.6.16.32/ipv6-no-autoconf.patch	Mon Nov 27 13:50:02 2006 +0000
    37.3 @@ -0,0 +1,19 @@
    37.4 +diff -pruN ../orig-linux-2.6.16.29/net/ipv6/addrconf.c ./net/ipv6/addrconf.c
    37.5 +--- ../orig-linux-2.6.16.29/net/ipv6/addrconf.c	2006-09-12 19:02:10.000000000 +0100
    37.6 ++++ ./net/ipv6/addrconf.c	2006-09-19 13:59:11.000000000 +0100
    37.7 +@@ -2471,6 +2471,7 @@ static void addrconf_dad_start(struct in
    37.8 + 	spin_lock_bh(&ifp->lock);
    37.9 + 
   37.10 + 	if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
   37.11 ++	    !(dev->flags&IFF_MULTICAST) ||
   37.12 + 	    !(ifp->flags&IFA_F_TENTATIVE)) {
   37.13 + 		ifp->flags &= ~IFA_F_TENTATIVE;
   37.14 + 		spin_unlock_bh(&ifp->lock);
   37.15 +@@ -2555,6 +2556,7 @@ static void addrconf_dad_completed(struc
   37.16 + 	if (ifp->idev->cnf.forwarding == 0 &&
   37.17 + 	    ifp->idev->cnf.rtr_solicits > 0 &&
   37.18 + 	    (dev->flags&IFF_LOOPBACK) == 0 &&
   37.19 ++	    (dev->flags & IFF_MULTICAST) &&
   37.20 + 	    (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
   37.21 + 		struct in6_addr all_routers;
   37.22 + 
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/patches/linux-2.6.16.32/net-csum.patch	Mon Nov 27 13:50:02 2006 +0000
    38.3 @@ -0,0 +1,63 @@
    38.4 +diff -pruN ../orig-linux-2.6.16.29/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c
    38.5 +--- ../orig-linux-2.6.16.29/net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-09-12 19:02:10.000000000 +0100
    38.6 ++++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c	2006-09-19 13:59:15.000000000 +0100
    38.7 +@@ -129,7 +129,12 @@ tcp_manip_pkt(struct sk_buff **pskb,
    38.8 + 	if (hdrsize < sizeof(*hdr))
    38.9 + 		return 1;
   38.10 + 
   38.11 +-	hdr->check = ip_nat_cheat_check(~oldip, newip,
   38.12 ++#ifdef CONFIG_XEN
   38.13 ++	if ((*pskb)->proto_csum_blank)
   38.14 ++		hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
   38.15 ++	else
   38.16 ++#endif
   38.17 ++		hdr->check = ip_nat_cheat_check(~oldip, newip,
   38.18 + 					ip_nat_cheat_check(oldport ^ 0xFFFF,
   38.19 + 							   newport,
   38.20 + 							   hdr->check));
   38.21 +diff -pruN ../orig-linux-2.6.16.29/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c
   38.22 +--- ../orig-linux-2.6.16.29/net/ipv4/netfilter/ip_nat_proto_udp.c	2006-09-12 19:02:10.000000000 +0100
   38.23 ++++ ./net/ipv4/netfilter/ip_nat_proto_udp.c	2006-09-19 13:59:15.000000000 +0100
   38.24 +@@ -113,11 +113,17 @@ udp_manip_pkt(struct sk_buff **pskb,
   38.25 + 		newport = tuple->dst.u.udp.port;
   38.26 + 		portptr = &hdr->dest;
   38.27 + 	}
   38.28 +-	if (hdr->check) /* 0 is a special case meaning no checksum */
   38.29 +-		hdr->check = ip_nat_cheat_check(~oldip, newip,
   38.30 ++	if (hdr->check) { /* 0 is a special case meaning no checksum */
   38.31 ++#ifdef CONFIG_XEN
   38.32 ++		if ((*pskb)->proto_csum_blank)
   38.33 ++			hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check);
   38.34 ++		else
   38.35 ++#endif
   38.36 ++			hdr->check = ip_nat_cheat_check(~oldip, newip,
   38.37 + 					ip_nat_cheat_check(*portptr ^ 0xFFFF,
   38.38 + 							   newport,
   38.39 + 							   hdr->check));
   38.40 ++	}
   38.41 + 	*portptr = newport;
   38.42 + 	return 1;
   38.43 + }
   38.44 +diff -pruN ../orig-linux-2.6.16.29/net/ipv4/xfrm4_output.c ./net/ipv4/xfrm4_output.c
   38.45 +--- ../orig-linux-2.6.16.29/net/ipv4/xfrm4_output.c	2006-09-12 19:02:10.000000000 +0100
   38.46 ++++ ./net/ipv4/xfrm4_output.c	2006-09-19 13:59:15.000000000 +0100
   38.47 +@@ -17,6 +17,8 @@
   38.48 + #include <net/xfrm.h>
   38.49 + #include <net/icmp.h>
   38.50 + 
   38.51 ++extern int skb_checksum_setup(struct sk_buff *skb);
   38.52 ++
   38.53 + /* Add encapsulation header.
   38.54 +  *
   38.55 +  * In transport mode, the IP header will be moved forward to make space
   38.56 +@@ -103,6 +105,10 @@ static int xfrm4_output_one(struct sk_bu
   38.57 + 	struct xfrm_state *x = dst->xfrm;
   38.58 + 	int err;
   38.59 + 	
   38.60 ++	err = skb_checksum_setup(skb);
   38.61 ++	if (err)
   38.62 ++		goto error_nolock;
   38.63 ++
   38.64 + 	if (skb->ip_summed == CHECKSUM_HW) {
   38.65 + 		err = skb_checksum_help(skb, 0);
   38.66 + 		if (err)
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/patches/linux-2.6.16.32/net-gso-0-base.patch	Mon Nov 27 13:50:02 2006 +0000
    39.3 @@ -0,0 +1,2898 @@
    39.4 +Index: tmp-xxx/Documentation/networking/netdevices.txt
    39.5 +===================================================================
    39.6 +--- tmp-xxx.orig/Documentation/networking/netdevices.txt	2006-11-15 10:38:39.000000000 +0000
    39.7 ++++ tmp-xxx/Documentation/networking/netdevices.txt	2006-11-27 10:52:42.000000000 +0000
    39.8 +@@ -42,9 +42,9 @@
    39.9 + 	Context: nominally process, but don't sleep inside an rwlock
   39.10 + 
   39.11 + dev->hard_start_xmit:
   39.12 +-	Synchronization: dev->xmit_lock spinlock.
   39.13 ++	Synchronization: netif_tx_lock spinlock.
   39.14 + 	When the driver sets NETIF_F_LLTX in dev->features this will be
   39.15 +-	called without holding xmit_lock. In this case the driver 
   39.16 ++	called without holding netif_tx_lock. In this case the driver
   39.17 + 	has to lock by itself when needed. It is recommended to use a try lock
   39.18 + 	for this and return -1 when the spin lock fails. 
   39.19 + 	The locking there should also properly protect against 
   39.20 +@@ -62,12 +62,12 @@
   39.21 + 	  Only valid when NETIF_F_LLTX is set.
   39.22 + 
   39.23 + dev->tx_timeout:
   39.24 +-	Synchronization: dev->xmit_lock spinlock.
   39.25 ++	Synchronization: netif_tx_lock spinlock.
   39.26 + 	Context: BHs disabled
   39.27 + 	Notes: netif_queue_stopped() is guaranteed true
   39.28 + 
   39.29 + dev->set_multicast_list:
   39.30 +-	Synchronization: dev->xmit_lock spinlock.
   39.31 ++	Synchronization: netif_tx_lock spinlock.
   39.32 + 	Context: BHs disabled
   39.33 + 
   39.34 + dev->poll:
   39.35 +Index: tmp-xxx/drivers/block/aoe/aoenet.c
   39.36 +===================================================================
   39.37 +--- tmp-xxx.orig/drivers/block/aoe/aoenet.c	2006-11-15 10:38:39.000000000 +0000
   39.38 ++++ tmp-xxx/drivers/block/aoe/aoenet.c	2006-11-27 10:52:42.000000000 +0000
   39.39 +@@ -95,9 +95,8 @@
   39.40 + static struct sk_buff *
   39.41 + skb_check(struct sk_buff *skb)
   39.42 + {
   39.43 +-	if (skb_is_nonlinear(skb))
   39.44 + 	if ((skb = skb_share_check(skb, GFP_ATOMIC)))
   39.45 +-	if (skb_linearize(skb, GFP_ATOMIC) < 0) {
   39.46 ++	if (skb_linearize(skb)) {
   39.47 + 		dev_kfree_skb(skb);
   39.48 + 		return NULL;
   39.49 + 	}
   39.50 +Index: tmp-xxx/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
   39.51 +===================================================================
   39.52 +--- tmp-xxx.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2006-11-15 10:38:39.000000000 +0000
   39.53 ++++ tmp-xxx/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2006-11-27 10:52:42.000000000 +0000
   39.54 +@@ -821,7 +821,8 @@
   39.55 + 
   39.56 + 	ipoib_mcast_stop_thread(dev, 0);
   39.57 + 
   39.58 +-	spin_lock_irqsave(&dev->xmit_lock, flags);
   39.59 ++	local_irq_save(flags);
   39.60 ++	netif_tx_lock(dev);
   39.61 + 	spin_lock(&priv->lock);
   39.62 + 
   39.63 + 	/*
   39.64 +@@ -896,7 +897,8 @@
   39.65 + 	}
   39.66 + 
   39.67 + 	spin_unlock(&priv->lock);
   39.68 +-	spin_unlock_irqrestore(&dev->xmit_lock, flags);
   39.69 ++	netif_tx_unlock(dev);
   39.70 ++	local_irq_restore(flags);
   39.71 + 
   39.72 + 	/* We have to cancel outside of the spinlock */
   39.73 + 	list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
   39.74 +Index: tmp-xxx/drivers/media/dvb/dvb-core/dvb_net.c
   39.75 +===================================================================
   39.76 +--- tmp-xxx.orig/drivers/media/dvb/dvb-core/dvb_net.c	2006-11-15 10:38:39.000000000 +0000
   39.77 ++++ tmp-xxx/drivers/media/dvb/dvb-core/dvb_net.c	2006-11-27 10:52:42.000000000 +0000
   39.78 +@@ -1053,7 +1053,7 @@
   39.79 + 
   39.80 + 	dvb_net_feed_stop(dev);
   39.81 + 	priv->rx_mode = RX_MODE_UNI;
   39.82 +-	spin_lock_bh(&dev->xmit_lock);
   39.83 ++	netif_tx_lock_bh(dev);
   39.84 + 
   39.85 + 	if (dev->flags & IFF_PROMISC) {
   39.86 + 		dprintk("%s: promiscuous mode\n", dev->name);
   39.87 +@@ -1078,7 +1078,7 @@
   39.88 + 		}
   39.89 + 	}
   39.90 + 
   39.91 +-	spin_unlock_bh(&dev->xmit_lock);
   39.92 ++	netif_tx_unlock_bh(dev);
   39.93 + 	dvb_net_feed_start(dev);
   39.94 + }
   39.95 + 
   39.96 +Index: tmp-xxx/drivers/net/8139cp.c
   39.97 +===================================================================
   39.98 +--- tmp-xxx.orig/drivers/net/8139cp.c	2006-11-15 10:38:39.000000000 +0000
   39.99 ++++ tmp-xxx/drivers/net/8139cp.c	2006-11-27 10:52:42.000000000 +0000
  39.100 +@@ -794,7 +794,7 @@
  39.101 + 	entry = cp->tx_head;
  39.102 + 	eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
  39.103 + 	if (dev->features & NETIF_F_TSO)
  39.104 +-		mss = skb_shinfo(skb)->tso_size;
  39.105 ++		mss = skb_shinfo(skb)->gso_size;
  39.106 + 
  39.107 + 	if (skb_shinfo(skb)->nr_frags == 0) {
  39.108 + 		struct cp_desc *txd = &cp->tx_ring[entry];
  39.109 +Index: tmp-xxx/drivers/net/bnx2.c
  39.110 +===================================================================
  39.111 +--- tmp-xxx.orig/drivers/net/bnx2.c	2006-11-15 10:38:39.000000000 +0000
  39.112 ++++ tmp-xxx/drivers/net/bnx2.c	2006-11-27 10:52:42.000000000 +0000
  39.113 +@@ -1593,7 +1593,7 @@
  39.114 + 		skb = tx_buf->skb;
  39.115 + #ifdef BCM_TSO 
  39.116 + 		/* partial BD completions possible with TSO packets */
  39.117 +-		if (skb_shinfo(skb)->tso_size) {
  39.118 ++		if (skb_shinfo(skb)->gso_size) {
  39.119 + 			u16 last_idx, last_ring_idx;
  39.120 + 
  39.121 + 			last_idx = sw_cons +
  39.122 +@@ -1948,7 +1948,7 @@
  39.123 + 	return 1;
  39.124 + }
  39.125 + 
  39.126 +-/* Called with rtnl_lock from vlan functions and also dev->xmit_lock
  39.127 ++/* Called with rtnl_lock from vlan functions and also netif_tx_lock
  39.128 +  * from set_multicast.
  39.129 +  */
  39.130 + static void
  39.131 +@@ -4403,7 +4403,7 @@
  39.132 + }
  39.133 + #endif
  39.134 + 
  39.135 +-/* Called with dev->xmit_lock.
  39.136 ++/* Called with netif_tx_lock.
  39.137 +  * hard_start_xmit is pseudo-lockless - a lock is only required when
  39.138 +  * the tx queue is full. This way, we get the benefit of lockless
  39.139 +  * operations most of the time without the complexities to handle
  39.140 +@@ -4441,7 +4441,7 @@
  39.141 + 			(TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
  39.142 + 	}
  39.143 + #ifdef BCM_TSO 
  39.144 +-	if ((mss = skb_shinfo(skb)->tso_size) &&
  39.145 ++	if ((mss = skb_shinfo(skb)->gso_size) &&
  39.146 + 		(skb->len > (bp->dev->mtu + ETH_HLEN))) {
  39.147 + 		u32 tcp_opt_len, ip_tcp_len;
  39.148 + 
  39.149 +Index: tmp-xxx/drivers/net/bonding/bond_main.c
  39.150 +===================================================================
  39.151 +--- tmp-xxx.orig/drivers/net/bonding/bond_main.c	2006-11-15 10:38:39.000000000 +0000
  39.152 ++++ tmp-xxx/drivers/net/bonding/bond_main.c	2006-11-27 10:52:42.000000000 +0000
  39.153 +@@ -1145,8 +1145,7 @@
  39.154 + }
  39.155 + 
  39.156 + #define BOND_INTERSECT_FEATURES \
  39.157 +-	(NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\
  39.158 +-	NETIF_F_TSO|NETIF_F_UFO)
  39.159 ++	(NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO)
  39.160 + 
  39.161 + /* 
  39.162 +  * Compute the common dev->feature set available to all slaves.  Some
  39.163 +@@ -1164,9 +1163,7 @@
  39.164 + 		features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
  39.165 + 
  39.166 + 	if ((features & NETIF_F_SG) && 
  39.167 +-	    !(features & (NETIF_F_IP_CSUM |
  39.168 +-			  NETIF_F_NO_CSUM |
  39.169 +-			  NETIF_F_HW_CSUM)))
  39.170 ++	    !(features & NETIF_F_ALL_CSUM))
  39.171 + 		features &= ~NETIF_F_SG;
  39.172 + 
  39.173 + 	/* 
  39.174 +@@ -4147,7 +4144,7 @@
  39.175 + 	 */
  39.176 + 	bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
  39.177 + 
  39.178 +-	/* don't acquire bond device's xmit_lock when 
  39.179 ++	/* don't acquire bond device's netif_tx_lock when
  39.180 + 	 * transmitting */
  39.181 + 	bond_dev->features |= NETIF_F_LLTX;
  39.182 + 
  39.183 +Index: tmp-xxx/drivers/net/chelsio/sge.c
  39.184 +===================================================================
  39.185 +--- tmp-xxx.orig/drivers/net/chelsio/sge.c	2006-11-15 10:38:39.000000000 +0000
  39.186 ++++ tmp-xxx/drivers/net/chelsio/sge.c	2006-11-27 10:52:42.000000000 +0000
  39.187 +@@ -1419,7 +1419,7 @@
  39.188 + 	struct cpl_tx_pkt *cpl;
  39.189 + 
  39.190 + #ifdef NETIF_F_TSO
  39.191 +-	if (skb_shinfo(skb)->tso_size) {
  39.192 ++	if (skb_shinfo(skb)->gso_size) {
  39.193 + 		int eth_type;
  39.194 + 		struct cpl_tx_pkt_lso *hdr;
  39.195 + 
  39.196 +@@ -1434,7 +1434,7 @@
  39.197 + 		hdr->ip_hdr_words = skb->nh.iph->ihl;
  39.198 + 		hdr->tcp_hdr_words = skb->h.th->doff;
  39.199 + 		hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type,
  39.200 +-						skb_shinfo(skb)->tso_size));
  39.201 ++						skb_shinfo(skb)->gso_size));
  39.202 + 		hdr->len = htonl(skb->len - sizeof(*hdr));
  39.203 + 		cpl = (struct cpl_tx_pkt *)hdr;
  39.204 + 		sge->stats.tx_lso_pkts++;
  39.205 +Index: tmp-xxx/drivers/net/e1000/e1000_main.c
  39.206 +===================================================================
  39.207 +--- tmp-xxx.orig/drivers/net/e1000/e1000_main.c	2006-11-15 10:38:39.000000000 +0000
  39.208 ++++ tmp-xxx/drivers/net/e1000/e1000_main.c	2006-11-27 10:52:42.000000000 +0000
  39.209 +@@ -2526,7 +2526,7 @@
  39.210 + 	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
  39.211 + 	int err;
  39.212 + 
  39.213 +-	if (skb_shinfo(skb)->tso_size) {
  39.214 ++	if (skb_shinfo(skb)->gso_size) {
  39.215 + 		if (skb_header_cloned(skb)) {
  39.216 + 			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
  39.217 + 			if (err)
  39.218 +@@ -2534,7 +2534,7 @@
  39.219 + 		}
  39.220 + 
  39.221 + 		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
  39.222 +-		mss = skb_shinfo(skb)->tso_size;
  39.223 ++		mss = skb_shinfo(skb)->gso_size;
  39.224 + 		if (skb->protocol == ntohs(ETH_P_IP)) {
  39.225 + 			skb->nh.iph->tot_len = 0;
  39.226 + 			skb->nh.iph->check = 0;
  39.227 +@@ -2651,7 +2651,7 @@
  39.228 + 		 * tso gets written back prematurely before the data is fully
  39.229 + 		 * DMAd to the controller */
  39.230 + 		if (!skb->data_len && tx_ring->last_tx_tso &&
  39.231 +-				!skb_shinfo(skb)->tso_size) {
  39.232 ++				!skb_shinfo(skb)->gso_size) {
  39.233 + 			tx_ring->last_tx_tso = 0;
  39.234 + 			size -= 4;
  39.235 + 		}
  39.236 +@@ -2893,7 +2893,7 @@
  39.237 + 	}
  39.238 + 
  39.239 + #ifdef NETIF_F_TSO
  39.240 +-	mss = skb_shinfo(skb)->tso_size;
  39.241 ++	mss = skb_shinfo(skb)->gso_size;
  39.242 + 	/* The controller does a simple calculation to 
  39.243 + 	 * make sure there is enough room in the FIFO before
  39.244 + 	 * initiating the DMA for each buffer.  The calc is:
  39.245 +@@ -2935,7 +2935,7 @@
  39.246 + #ifdef NETIF_F_TSO
  39.247 + 	/* Controller Erratum workaround */
  39.248 + 	if (!skb->data_len && tx_ring->last_tx_tso &&
  39.249 +-		!skb_shinfo(skb)->tso_size)
  39.250 ++		!skb_shinfo(skb)->gso_size)
  39.251 + 		count++;
  39.252 + #endif
  39.253 + 
  39.254 +Index: tmp-xxx/drivers/net/forcedeth.c
  39.255 +===================================================================
  39.256 +--- tmp-xxx.orig/drivers/net/forcedeth.c	2006-11-15 10:38:39.000000000 +0000
  39.257 ++++ tmp-xxx/drivers/net/forcedeth.c	2006-11-27 10:52:42.000000000 +0000
  39.258 +@@ -482,9 +482,9 @@
  39.259 +  * critical parts:
  39.260 +  * - rx is (pseudo-) lockless: it relies on the single-threading provided
  39.261 +  *	by the arch code for interrupts.
  39.262 +- * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission
  39.263 ++ * - tx setup is lockless: it relies on netif_tx_lock. Actual submission
  39.264 +  *	needs dev->priv->lock :-(
  39.265 +- * - set_multicast_list: preparation lockless, relies on dev->xmit_lock.
  39.266 ++ * - set_multicast_list: preparation lockless, relies on netif_tx_lock.
  39.267 +  */
  39.268 + 
  39.269 + /* in dev: base, irq */
  39.270 +@@ -1016,7 +1016,7 @@
  39.271 + 
  39.272 + /*
  39.273 +  * nv_start_xmit: dev->hard_start_xmit function
  39.274 +- * Called with dev->xmit_lock held.
  39.275 ++ * Called with netif_tx_lock held.
  39.276 +  */
  39.277 + static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
  39.278 + {
  39.279 +@@ -1105,8 +1105,8 @@
  39.280 + 	np->tx_skbuff[nr] = skb;
  39.281 + 
  39.282 + #ifdef NETIF_F_TSO
  39.283 +-	if (skb_shinfo(skb)->tso_size)
  39.284 +-		tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT);
  39.285 ++	if (skb_shinfo(skb)->gso_size)
  39.286 ++		tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT);
  39.287 + 	else
  39.288 + #endif
  39.289 + 	tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
  39.290 +@@ -1203,7 +1203,7 @@
  39.291 + 
  39.292 + /*
  39.293 +  * nv_tx_timeout: dev->tx_timeout function
  39.294 +- * Called with dev->xmit_lock held.
  39.295 ++ * Called with netif_tx_lock held.
  39.296 +  */
  39.297 + static void nv_tx_timeout(struct net_device *dev)
  39.298 + {
  39.299 +@@ -1524,7 +1524,7 @@
  39.300 + 		 * Changing the MTU is a rare event, it shouldn't matter.
  39.301 + 		 */
  39.302 + 		disable_irq(dev->irq);
  39.303 +-		spin_lock_bh(&dev->xmit_lock);
  39.304 ++		netif_tx_lock_bh(dev);
  39.305 + 		spin_lock(&np->lock);
  39.306 + 		/* stop engines */
  39.307 + 		nv_stop_rx(dev);
  39.308 +@@ -1559,7 +1559,7 @@
  39.309 + 		nv_start_rx(dev);
  39.310 + 		nv_start_tx(dev);
  39.311 + 		spin_unlock(&np->lock);
  39.312 +-		spin_unlock_bh(&dev->xmit_lock);
  39.313 ++		netif_tx_unlock_bh(dev);
  39.314 + 		enable_irq(dev->irq);
  39.315 + 	}
  39.316 + 	return 0;
  39.317 +@@ -1594,7 +1594,7 @@
  39.318 + 	memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN);
  39.319 + 
  39.320 + 	if (netif_running(dev)) {
  39.321 +-		spin_lock_bh(&dev->xmit_lock);
  39.322 ++		netif_tx_lock_bh(dev);
  39.323 + 		spin_lock_irq(&np->lock);
  39.324 + 
  39.325 + 		/* stop rx engine */
  39.326 +@@ -1606,7 +1606,7 @@
  39.327 + 		/* restart rx engine */
  39.328 + 		nv_start_rx(dev);
  39.329 + 		spin_unlock_irq(&np->lock);
  39.330 +-		spin_unlock_bh(&dev->xmit_lock);
  39.331 ++		netif_tx_unlock_bh(dev);
  39.332 + 	} else {
  39.333 + 		nv_copy_mac_to_hw(dev);
  39.334 + 	}
  39.335 +@@ -1615,7 +1615,7 @@
  39.336 + 
  39.337 + /*
  39.338 +  * nv_set_multicast: dev->set_multicast function
  39.339 +- * Called with dev->xmit_lock held.
  39.340 ++ * Called with netif_tx_lock held.
  39.341 +  */
  39.342 + static void nv_set_multicast(struct net_device *dev)
  39.343 + {
  39.344 +Index: tmp-xxx/drivers/net/hamradio/6pack.c
  39.345 +===================================================================
  39.346 +--- tmp-xxx.orig/drivers/net/hamradio/6pack.c	2006-11-15 10:38:39.000000000 +0000
  39.347 ++++ tmp-xxx/drivers/net/hamradio/6pack.c	2006-11-27 10:52:42.000000000 +0000
  39.348 +@@ -308,9 +308,9 @@
  39.349 + {
  39.350 + 	struct sockaddr_ax25 *sa = addr;
  39.351 + 
  39.352 +-	spin_lock_irq(&dev->xmit_lock);
  39.353 ++	netif_tx_lock_bh(dev);
  39.354 + 	memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
  39.355 +-	spin_unlock_irq(&dev->xmit_lock);
  39.356 ++	netif_tx_unlock_bh(dev);
  39.357 + 
  39.358 + 	return 0;
  39.359 + }
  39.360 +@@ -767,9 +767,9 @@
  39.361 + 			break;
  39.362 + 		}
  39.363 + 
  39.364 +-		spin_lock_irq(&dev->xmit_lock);
  39.365 ++		netif_tx_lock_bh(dev);
  39.366 + 		memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
  39.367 +-		spin_unlock_irq(&dev->xmit_lock);
  39.368 ++		netif_tx_unlock_bh(dev);
  39.369 + 
  39.370 + 		err = 0;
  39.371 + 		break;
  39.372 +Index: tmp-xxx/drivers/net/hamradio/mkiss.c
  39.373 +===================================================================
  39.374 +--- tmp-xxx.orig/drivers/net/hamradio/mkiss.c	2006-11-15 10:38:39.000000000 +0000
  39.375 ++++ tmp-xxx/drivers/net/hamradio/mkiss.c	2006-11-27 10:52:42.000000000 +0000
  39.376 +@@ -357,9 +357,9 @@
  39.377 + {
  39.378 + 	struct sockaddr_ax25 *sa = addr;
  39.379 + 
  39.380 +-	spin_lock_irq(&dev->xmit_lock);
  39.381 ++	netif_tx_lock_bh(dev);
  39.382 + 	memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
  39.383 +-	spin_unlock_irq(&dev->xmit_lock);
  39.384 ++	netif_tx_unlock_bh(dev);
  39.385 + 
  39.386 + 	return 0;
  39.387 + }
  39.388 +@@ -886,9 +886,9 @@
  39.389 + 			break;
  39.390 + 		}
  39.391 + 
  39.392 +-		spin_lock_irq(&dev->xmit_lock);
  39.393 ++		netif_tx_lock_bh(dev);
  39.394 + 		memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
  39.395 +-		spin_unlock_irq(&dev->xmit_lock);
  39.396 ++		netif_tx_unlock_bh(dev);
  39.397 + 
  39.398 + 		err = 0;
  39.399 + 		break;
  39.400 +Index: tmp-xxx/drivers/net/ifb.c
  39.401 +===================================================================
  39.402 +--- tmp-xxx.orig/drivers/net/ifb.c	2006-11-15 10:38:39.000000000 +0000
  39.403 ++++ tmp-xxx/drivers/net/ifb.c	2006-11-27 10:52:42.000000000 +0000
  39.404 +@@ -76,13 +76,13 @@
  39.405 + 	dp->st_task_enter++;
  39.406 + 	if ((skb = skb_peek(&dp->tq)) == NULL) {
  39.407 + 		dp->st_txq_refl_try++;
  39.408 +-		if (spin_trylock(&_dev->xmit_lock)) {
  39.409 ++		if (netif_tx_trylock(_dev)) {
  39.410 + 			dp->st_rxq_enter++;
  39.411 + 			while ((skb = skb_dequeue(&dp->rq)) != NULL) {
  39.412 + 				skb_queue_tail(&dp->tq, skb);
  39.413 + 				dp->st_rx2tx_tran++;
  39.414 + 			}
  39.415 +-			spin_unlock(&_dev->xmit_lock);
  39.416 ++			netif_tx_unlock(_dev);
  39.417 + 		} else {
  39.418 + 			/* reschedule */
  39.419 + 			dp->st_rxq_notenter++;
  39.420 +@@ -110,7 +110,7 @@
  39.421 + 		}
  39.422 + 	}
  39.423 + 
  39.424 +-	if (spin_trylock(&_dev->xmit_lock)) {
  39.425 ++	if (netif_tx_trylock(_dev)) {
  39.426 + 		dp->st_rxq_check++;
  39.427 + 		if ((skb = skb_peek(&dp->rq)) == NULL) {
  39.428 + 			dp->tasklet_pending = 0;
  39.429 +@@ -118,10 +118,10 @@
  39.430 + 				netif_wake_queue(_dev);
  39.431 + 		} else {
  39.432 + 			dp->st_rxq_rsch++;
  39.433 +-			spin_unlock(&_dev->xmit_lock);
  39.434 ++			netif_tx_unlock(_dev);
  39.435 + 			goto resched;
  39.436 + 		}
  39.437 +-		spin_unlock(&_dev->xmit_lock);
  39.438 ++		netif_tx_unlock(_dev);
  39.439 + 	} else {
  39.440 + resched:
  39.441 + 		dp->tasklet_pending = 1;
  39.442 +Index: tmp-xxx/drivers/net/irda/vlsi_ir.c
  39.443 +===================================================================
  39.444 +--- tmp-xxx.orig/drivers/net/irda/vlsi_ir.c	2006-11-15 10:38:39.000000000 +0000
  39.445 ++++ tmp-xxx/drivers/net/irda/vlsi_ir.c	2006-11-27 10:52:42.000000000 +0000
  39.446 +@@ -959,7 +959,7 @@
  39.447 + 			    ||  (now.tv_sec==ready.tv_sec && now.tv_usec>=ready.tv_usec))
  39.448 + 			    	break;
  39.449 + 			udelay(100);
  39.450 +-			/* must not sleep here - we are called under xmit_lock! */
  39.451 ++			/* must not sleep here - called under netif_tx_lock! */
  39.452 + 		}
  39.453 + 	}
  39.454 + 
  39.455 +Index: tmp-xxx/drivers/net/ixgb/ixgb_main.c
  39.456 +===================================================================
  39.457 +--- tmp-xxx.orig/drivers/net/ixgb/ixgb_main.c	2006-11-15 10:38:39.000000000 +0000
  39.458 ++++ tmp-xxx/drivers/net/ixgb/ixgb_main.c	2006-11-27 10:52:42.000000000 +0000
  39.459 +@@ -1163,7 +1163,7 @@
  39.460 + 	uint16_t ipcse, tucse, mss;
  39.461 + 	int err;
  39.462 + 
  39.463 +-	if(likely(skb_shinfo(skb)->tso_size)) {
  39.464 ++	if(likely(skb_shinfo(skb)->gso_size)) {
  39.465 + 		if (skb_header_cloned(skb)) {
  39.466 + 			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
  39.467 + 			if (err)
  39.468 +@@ -1171,7 +1171,7 @@
  39.469 + 		}
  39.470 + 
  39.471 + 		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
  39.472 +-		mss = skb_shinfo(skb)->tso_size;
  39.473 ++		mss = skb_shinfo(skb)->gso_size;
  39.474 + 		skb->nh.iph->tot_len = 0;
  39.475 + 		skb->nh.iph->check = 0;
  39.476 + 		skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr,
  39.477 +Index: tmp-xxx/drivers/net/loopback.c
  39.478 +===================================================================
  39.479 +--- tmp-xxx.orig/drivers/net/loopback.c	2006-11-15 10:38:39.000000000 +0000
  39.480 ++++ tmp-xxx/drivers/net/loopback.c	2006-11-27 10:52:42.000000000 +0000
  39.481 +@@ -74,7 +74,7 @@
  39.482 + 	struct iphdr *iph = skb->nh.iph;
  39.483 + 	struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4));
  39.484 + 	unsigned int doffset = (iph->ihl + th->doff) * 4;
  39.485 +-	unsigned int mtu = skb_shinfo(skb)->tso_size + doffset;
  39.486 ++	unsigned int mtu = skb_shinfo(skb)->gso_size + doffset;
  39.487 + 	unsigned int offset = 0;
  39.488 + 	u32 seq = ntohl(th->seq);
  39.489 + 	u16 id  = ntohs(iph->id);
  39.490 +@@ -139,7 +139,7 @@
  39.491 + #endif
  39.492 + 
  39.493 + #ifdef LOOPBACK_TSO
  39.494 +-	if (skb_shinfo(skb)->tso_size) {
  39.495 ++	if (skb_shinfo(skb)->gso_size) {
  39.496 + 		BUG_ON(skb->protocol != htons(ETH_P_IP));
  39.497 + 		BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP);
  39.498 + 
  39.499 +Index: tmp-xxx/drivers/net/mv643xx_eth.c
  39.500 +===================================================================
  39.501 +--- tmp-xxx.orig/drivers/net/mv643xx_eth.c	2006-11-15 10:38:39.000000000 +0000
  39.502 ++++ tmp-xxx/drivers/net/mv643xx_eth.c	2006-11-27 10:52:42.000000000 +0000
  39.503 +@@ -1107,7 +1107,7 @@
  39.504 + 
  39.505 + #ifdef MV643XX_CHECKSUM_OFFLOAD_TX
  39.506 + 	if (has_tiny_unaligned_frags(skb)) {
  39.507 +-		if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {
  39.508 ++		if (__skb_linearize(skb)) {
  39.509 + 			stats->tx_dropped++;
  39.510 + 			printk(KERN_DEBUG "%s: failed to linearize tiny "
  39.511 + 					"unaligned fragment\n", dev->name);
  39.512 +Index: tmp-xxx/drivers/net/natsemi.c
  39.513 +===================================================================
  39.514 +--- tmp-xxx.orig/drivers/net/natsemi.c	2006-11-15 10:38:39.000000000 +0000
  39.515 ++++ tmp-xxx/drivers/net/natsemi.c	2006-11-27 10:52:42.000000000 +0000
  39.516 +@@ -323,12 +323,12 @@
  39.517 + The rx process only runs in the interrupt handler. Access from outside
  39.518 + the interrupt handler is only permitted after disable_irq().
  39.519 + 
  39.520 +-The rx process usually runs under the dev->xmit_lock. If np->intr_tx_reap
  39.521 ++The rx process usually runs under the netif_tx_lock. If np->intr_tx_reap
  39.522 + is set, then access is permitted under spin_lock_irq(&np->lock).
  39.523 + 
  39.524 + Thus configuration functions that want to access everything must call
  39.525 + 	disable_irq(dev->irq);
  39.526 +-	spin_lock_bh(dev->xmit_lock);
  39.527 ++	netif_tx_lock_bh(dev);
  39.528 + 	spin_lock_irq(&np->lock);
  39.529 + 
  39.530 + IV. Notes
  39.531 +Index: tmp-xxx/drivers/net/r8169.c
  39.532 +===================================================================
  39.533 +--- tmp-xxx.orig/drivers/net/r8169.c	2006-11-15 10:38:39.000000000 +0000
  39.534 ++++ tmp-xxx/drivers/net/r8169.c	2006-11-27 10:52:42.000000000 +0000
  39.535 +@@ -2171,7 +2171,7 @@
  39.536 + static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev)
  39.537 + {
  39.538 + 	if (dev->features & NETIF_F_TSO) {
  39.539 +-		u32 mss = skb_shinfo(skb)->tso_size;
  39.540 ++		u32 mss = skb_shinfo(skb)->gso_size;
  39.541 + 
  39.542 + 		if (mss)
  39.543 + 			return LargeSend | ((mss & MSSMask) << MSSShift);
  39.544 +Index: tmp-xxx/drivers/net/s2io.c
  39.545 +===================================================================
  39.546 +--- tmp-xxx.orig/drivers/net/s2io.c	2006-11-15 10:38:39.000000000 +0000
  39.547 ++++ tmp-xxx/drivers/net/s2io.c	2006-11-27 10:52:42.000000000 +0000
  39.548 +@@ -3522,8 +3522,8 @@
  39.549 + 	txdp->Control_1 = 0;
  39.550 + 	txdp->Control_2 = 0;
  39.551 + #ifdef NETIF_F_TSO
  39.552 +-	mss = skb_shinfo(skb)->tso_size;
  39.553 +-	if (mss) {
  39.554 ++	mss = skb_shinfo(skb)->gso_size;
  39.555 ++	if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4) {
  39.556 + 		txdp->Control_1 |= TXD_TCP_LSO_EN;
  39.557 + 		txdp->Control_1 |= TXD_TCP_LSO_MSS(mss);
  39.558 + 	}
  39.559 +@@ -3543,10 +3543,10 @@
  39.560 + 	}
  39.561 + 
  39.562 + 	frg_len = skb->len - skb->data_len;
  39.563 +-	if (skb_shinfo(skb)->ufo_size) {
  39.564 ++	if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) {
  39.565 + 		int ufo_size;
  39.566 + 
  39.567 +-		ufo_size = skb_shinfo(skb)->ufo_size;
  39.568 ++		ufo_size = skb_shinfo(skb)->gso_size;
  39.569 + 		ufo_size &= ~7;
  39.570 + 		txdp->Control_1 |= TXD_UFO_EN;
  39.571 + 		txdp->Control_1 |= TXD_UFO_MSS(ufo_size);
  39.572 +@@ -3572,7 +3572,7 @@
  39.573 + 	txdp->Host_Control = (unsigned long) skb;
  39.574 + 	txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
  39.575 + 
  39.576 +-	if (skb_shinfo(skb)->ufo_size)
  39.577 ++	if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
  39.578 + 		txdp->Control_1 |= TXD_UFO_EN;
  39.579 + 
  39.580 + 	frg_cnt = skb_shinfo(skb)->nr_frags;
  39.581 +@@ -3587,12 +3587,12 @@
  39.582 + 		    (sp->pdev, frag->page, frag->page_offset,
  39.583 + 		     frag->size, PCI_DMA_TODEVICE);
  39.584 + 		txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size);
  39.585 +-		if (skb_shinfo(skb)->ufo_size)
  39.586 ++		if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
  39.587 + 			txdp->Control_1 |= TXD_UFO_EN;
  39.588 + 	}
  39.589 + 	txdp->Control_1 |= TXD_GATHER_CODE_LAST;
  39.590 + 
  39.591 +-	if (skb_shinfo(skb)->ufo_size)
  39.592 ++	if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
  39.593 + 		frg_cnt++; /* as Txd0 was used for inband header */
  39.594 + 
  39.595 + 	tx_fifo = mac_control->tx_FIFO_start[queue];
  39.596 +@@ -3606,7 +3606,7 @@
  39.597 + 	if (mss)
  39.598 + 		val64 |= TX_FIFO_SPECIAL_FUNC;
  39.599 + #endif
  39.600 +-	if (skb_shinfo(skb)->ufo_size)
  39.601 ++	if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4)
  39.602 + 		val64 |= TX_FIFO_SPECIAL_FUNC;
  39.603 + 	writeq(val64, &tx_fifo->List_Control);
  39.604 + 
  39.605 +Index: tmp-xxx/drivers/net/sky2.c
  39.606 +===================================================================
  39.607 +--- tmp-xxx.orig/drivers/net/sky2.c	2006-11-15 10:38:39.000000000 +0000
  39.608 ++++ tmp-xxx/drivers/net/sky2.c	2006-11-27 10:52:42.000000000 +0000
  39.609 +@@ -1141,7 +1141,7 @@
  39.610 + 	count = sizeof(dma_addr_t) / sizeof(u32);
  39.611 + 	count += skb_shinfo(skb)->nr_frags * count;
  39.612 + 
  39.613 +-	if (skb_shinfo(skb)->tso_size)
  39.614 ++	if (skb_shinfo(skb)->gso_size)
  39.615 + 		++count;
  39.616 + 
  39.617 + 	if (skb->ip_summed == CHECKSUM_HW)
  39.618 +@@ -1213,7 +1213,7 @@
  39.619 + 	}
  39.620 + 
  39.621 + 	/* Check for TCP Segmentation Offload */
  39.622 +-	mss = skb_shinfo(skb)->tso_size;
  39.623 ++	mss = skb_shinfo(skb)->gso_size;
  39.624 + 	if (mss != 0) {
  39.625 + 		/* just drop the packet if non-linear expansion fails */
  39.626 + 		if (skb_header_cloned(skb) &&
  39.627 +Index: tmp-xxx/drivers/net/tg3.c
  39.628 +===================================================================
  39.629 +--- tmp-xxx.orig/drivers/net/tg3.c	2006-11-15 10:38:39.000000000 +0000
  39.630 ++++ tmp-xxx/drivers/net/tg3.c	2006-11-27 10:52:42.000000000 +0000
  39.631 +@@ -3664,7 +3664,7 @@
  39.632 + #if TG3_TSO_SUPPORT != 0
  39.633 + 	mss = 0;
  39.634 + 	if (skb->len > (tp->dev->mtu + ETH_HLEN) &&
  39.635 +-	    (mss = skb_shinfo(skb)->tso_size) != 0) {
  39.636 ++	    (mss = skb_shinfo(skb)->gso_size) != 0) {
  39.637 + 		int tcp_opt_len, ip_tcp_len;
  39.638 + 
  39.639 + 		if (skb_header_cloned(skb) &&
  39.640 +Index: tmp-xxx/drivers/net/tulip/winbond-840.c
  39.641 +===================================================================
  39.642 +--- tmp-xxx.orig/drivers/net/tulip/winbond-840.c	2006-11-15 10:38:39.000000000 +0000
  39.643 ++++ tmp-xxx/drivers/net/tulip/winbond-840.c	2006-11-27 10:52:42.000000000 +0000
  39.644 +@@ -1605,11 +1605,11 @@
  39.645 +  * - get_stats:
  39.646 +  * 	spin_lock_irq(np->lock), doesn't touch hw if not present
  39.647 +  * - hard_start_xmit:
  39.648 +- * 	netif_stop_queue + spin_unlock_wait(&dev->xmit_lock);
  39.649 ++ * 	synchronize_irq + netif_tx_disable;
  39.650 +  * - tx_timeout:
  39.651 +- * 	netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
  39.652 ++ * 	netif_device_detach + netif_tx_disable;
  39.653 +  * - set_multicast_list
  39.654 +- * 	netif_device_detach + spin_unlock_wait(&dev->xmit_lock);
  39.655 ++ * 	netif_device_detach + netif_tx_disable;
  39.656 +  * - interrupt handler
  39.657 +  * 	doesn't touch hw if not present, synchronize_irq waits for
  39.658 +  * 	running instances of the interrupt handler.
  39.659 +@@ -1635,11 +1635,10 @@
  39.660 + 		netif_device_detach(dev);
  39.661 + 		update_csr6(dev, 0);
  39.662 + 		iowrite32(0, ioaddr + IntrEnable);
  39.663 +-		netif_stop_queue(dev);
  39.664 + 		spin_unlock_irq(&np->lock);
  39.665 + 
  39.666 +-		spin_unlock_wait(&dev->xmit_lock);
  39.667 + 		synchronize_irq(dev->irq);
  39.668 ++		netif_tx_disable(dev);
  39.669 + 	
  39.670 + 		np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff;
  39.671 + 
  39.672 +Index: tmp-xxx/drivers/net/typhoon.c
  39.673 +===================================================================
  39.674 +--- tmp-xxx.orig/drivers/net/typhoon.c	2006-11-15 10:38:39.000000000 +0000
  39.675 ++++ tmp-xxx/drivers/net/typhoon.c	2006-11-27 10:52:42.000000000 +0000
  39.676 +@@ -340,7 +340,7 @@
  39.677 + #endif
  39.678 + 
  39.679 + #if defined(NETIF_F_TSO)
  39.680 +-#define skb_tso_size(x)		(skb_shinfo(x)->tso_size)
  39.681 ++#define skb_tso_size(x)		(skb_shinfo(x)->gso_size)
  39.682 + #define TSO_NUM_DESCRIPTORS	2
  39.683 + #define TSO_OFFLOAD_ON		TYPHOON_OFFLOAD_TCP_SEGMENT
  39.684 + #else
  39.685 +Index: tmp-xxx/drivers/net/via-velocity.c
  39.686 +===================================================================
  39.687 +--- tmp-xxx.orig/drivers/net/via-velocity.c	2006-11-15 10:38:39.000000000 +0000
  39.688 ++++ tmp-xxx/drivers/net/via-velocity.c	2006-11-27 10:52:42.000000000 +0000
  39.689 +@@ -1905,6 +1905,13 @@
  39.690 + 
  39.691 + 	int pktlen = skb->len;
  39.692 + 
  39.693 ++#ifdef VELOCITY_ZERO_COPY_SUPPORT
  39.694 ++	if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
  39.695 ++		kfree_skb(skb);
  39.696 ++		return 0;
  39.697 ++	}
  39.698 ++#endif
  39.699 ++
  39.700 + 	spin_lock_irqsave(&vptr->lock, flags);
  39.701 + 
  39.702 + 	index = vptr->td_curr[qnum];
  39.703 +@@ -1920,8 +1927,6 @@
  39.704 + 	 */
  39.705 + 	if (pktlen < ETH_ZLEN) {
  39.706 + 		/* Cannot occur until ZC support */
  39.707 +-		if(skb_linearize(skb, GFP_ATOMIC))
  39.708 +-			return 0; 
  39.709 + 		pktlen = ETH_ZLEN;
  39.710 + 		memcpy(tdinfo->buf, skb->data, skb->len);
  39.711 + 		memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
  39.712 +@@ -1939,7 +1944,6 @@
  39.713 + 		int nfrags = skb_shinfo(skb)->nr_frags;
  39.714 + 		tdinfo->skb = skb;
  39.715 + 		if (nfrags > 6) {
  39.716 +-			skb_linearize(skb, GFP_ATOMIC);
  39.717 + 			memcpy(tdinfo->buf, skb->data, skb->len);
  39.718 + 			tdinfo->skb_dma[0] = tdinfo->buf_dma;
  39.719 + 			td_ptr->tdesc0.pktsize = 
  39.720 +Index: tmp-xxx/drivers/net/wireless/orinoco.c
  39.721 +===================================================================
  39.722 +--- tmp-xxx.orig/drivers/net/wireless/orinoco.c	2006-11-15 10:38:39.000000000 +0000
  39.723 ++++ tmp-xxx/drivers/net/wireless/orinoco.c	2006-11-27 10:52:42.000000000 +0000
  39.724 +@@ -1835,7 +1835,9 @@
  39.725 + 	/* Set promiscuity / multicast*/
  39.726 + 	priv->promiscuous = 0;
  39.727 + 	priv->mc_count = 0;
  39.728 +-	__orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */
  39.729 ++
  39.730 ++	/* FIXME: what about netif_tx_lock */
  39.731 ++	__orinoco_set_multicast_list(dev);
  39.732 + 
  39.733 + 	return 0;
  39.734 + }
  39.735 +Index: tmp-xxx/drivers/s390/net/qeth_eddp.c
  39.736 +===================================================================
  39.737 +--- tmp-xxx.orig/drivers/s390/net/qeth_eddp.c	2006-11-15 10:38:39.000000000 +0000
  39.738 ++++ tmp-xxx/drivers/s390/net/qeth_eddp.c	2006-11-27 10:52:42.000000000 +0000
  39.739 +@@ -421,7 +421,7 @@
  39.740 +        }
  39.741 + 	tcph = eddp->skb->h.th;
  39.742 + 	while (eddp->skb_offset < eddp->skb->len) {
  39.743 +-		data_len = min((int)skb_shinfo(eddp->skb)->tso_size,
  39.744 ++		data_len = min((int)skb_shinfo(eddp->skb)->gso_size,
  39.745 + 			       (int)(eddp->skb->len - eddp->skb_offset));
  39.746 + 		/* prepare qdio hdr */
  39.747 + 		if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){
  39.748 +@@ -516,20 +516,20 @@
  39.749 + 	
  39.750 + 	QETH_DBF_TEXT(trace, 5, "eddpcanp");
  39.751 + 	/* can we put multiple skbs in one page? */
  39.752 +-	skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len);
  39.753 ++	skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len);
  39.754 + 	if (skbs_per_page > 1){
  39.755 +-		ctx->num_pages = (skb_shinfo(skb)->tso_segs + 1) /
  39.756 ++		ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) /
  39.757 + 				 skbs_per_page + 1;
  39.758 + 		ctx->elements_per_skb = 1;
  39.759 + 	} else {
  39.760 + 		/* no -> how many elements per skb? */
  39.761 +-		ctx->elements_per_skb = (skb_shinfo(skb)->tso_size + hdr_len +
  39.762 ++		ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len +
  39.763 + 				     PAGE_SIZE) >> PAGE_SHIFT;
  39.764 + 		ctx->num_pages = ctx->elements_per_skb *
  39.765 +-				 (skb_shinfo(skb)->tso_segs + 1);
  39.766 ++				 (skb_shinfo(skb)->gso_segs + 1);
  39.767 + 	}
  39.768 + 	ctx->num_elements = ctx->elements_per_skb *
  39.769 +-			    (skb_shinfo(skb)->tso_segs + 1);
  39.770 ++			    (skb_shinfo(skb)->gso_segs + 1);
  39.771 + }
  39.772 + 
  39.773 + static inline struct qeth_eddp_context *
  39.774 +Index: tmp-xxx/drivers/s390/net/qeth_main.c
  39.775 +===================================================================
  39.776 +--- tmp-xxx.orig/drivers/s390/net/qeth_main.c	2006-11-15 10:38:39.000000000 +0000
  39.777 ++++ tmp-xxx/drivers/s390/net/qeth_main.c	2006-11-27 10:52:42.000000000 +0000
  39.778 +@@ -4454,7 +4454,7 @@
  39.779 + 	queue = card->qdio.out_qs
  39.780 + 		[qeth_get_priority_queue(card, skb, ipv, cast_type)];
  39.781 + 
  39.782 +-	if (skb_shinfo(skb)->tso_size)
  39.783 ++	if (skb_shinfo(skb)->gso_size)
  39.784 + 		large_send = card->options.large_send;
  39.785 + 
  39.786 + 	/*are we able to do TSO ? If so ,prepare and send it from here */
  39.787 +@@ -4501,7 +4501,7 @@
  39.788 + 		card->stats.tx_packets++;
  39.789 + 		card->stats.tx_bytes += skb->len;
  39.790 + #ifdef CONFIG_QETH_PERF_STATS
  39.791 +-		if (skb_shinfo(skb)->tso_size &&
  39.792 ++		if (skb_shinfo(skb)->gso_size &&
  39.793 + 		   !(large_send == QETH_LARGE_SEND_NO)) {
  39.794 + 			card->perf_stats.large_send_bytes += skb->len;
  39.795 + 			card->perf_stats.large_send_cnt++;
  39.796 +Index: tmp-xxx/drivers/s390/net/qeth_tso.h
  39.797 +===================================================================
  39.798 +--- tmp-xxx.orig/drivers/s390/net/qeth_tso.h	2006-11-15 10:38:39.000000000 +0000
  39.799 ++++ tmp-xxx/drivers/s390/net/qeth_tso.h	2006-11-27 10:52:42.000000000 +0000
  39.800 +@@ -51,7 +51,7 @@
  39.801 + 	hdr->ext.hdr_version = 1;
  39.802 + 	hdr->ext.hdr_len     = 28;
  39.803 + 	/*insert non-fix values */
  39.804 +-	hdr->ext.mss = skb_shinfo(skb)->tso_size;
  39.805 ++	hdr->ext.mss = skb_shinfo(skb)->gso_size;
  39.806 + 	hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
  39.807 + 	hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
  39.808 + 				       sizeof(struct qeth_hdr_tso));
  39.809 +Index: tmp-xxx/include/linux/ethtool.h
  39.810 +===================================================================
  39.811 +--- tmp-xxx.orig/include/linux/ethtool.h	2006-11-15 10:38:39.000000000 +0000
  39.812 ++++ tmp-xxx/include/linux/ethtool.h	2006-11-27 10:52:42.000000000 +0000
  39.813 +@@ -408,6 +408,8 @@
  39.814 + #define ETHTOOL_GPERMADDR	0x00000020 /* Get permanent hardware address */
  39.815 + #define ETHTOOL_GUFO		0x00000021 /* Get UFO enable (ethtool_value) */
  39.816 + #define ETHTOOL_SUFO		0x00000022 /* Set UFO enable (ethtool_value) */
  39.817 ++#define ETHTOOL_GGSO		0x00000023 /* Get GSO enable (ethtool_value) */
  39.818 ++#define ETHTOOL_SGSO		0x00000024 /* Set GSO enable (ethtool_value) */
  39.819 + 
  39.820 + /* compatibility with older code */
  39.821 + #define SPARC_ETH_GSET		ETHTOOL_GSET
  39.822 +Index: tmp-xxx/include/linux/netdevice.h
  39.823 +===================================================================
  39.824 +--- tmp-xxx.orig/include/linux/netdevice.h	2006-11-15 10:38:39.000000000 +0000
  39.825 ++++ tmp-xxx/include/linux/netdevice.h	2006-11-27 10:52:42.000000000 +0000
  39.826 +@@ -230,7 +230,8 @@
  39.827 + 	__LINK_STATE_SCHED,
  39.828 + 	__LINK_STATE_NOCARRIER,
  39.829 + 	__LINK_STATE_RX_SCHED,
  39.830 +-	__LINK_STATE_LINKWATCH_PENDING
  39.831 ++	__LINK_STATE_LINKWATCH_PENDING,
  39.832 ++	__LINK_STATE_QDISC_RUNNING,
  39.833 + };
  39.834 + 
  39.835 + 
  39.836 +@@ -306,9 +307,17 @@
  39.837 + #define NETIF_F_HW_VLAN_RX	256	/* Receive VLAN hw acceleration */
  39.838 + #define NETIF_F_HW_VLAN_FILTER	512	/* Receive filtering on VLAN */
  39.839 + #define NETIF_F_VLAN_CHALLENGED	1024	/* Device cannot handle VLAN packets */
  39.840 +-#define NETIF_F_TSO		2048	/* Can offload TCP/IP segmentation */
  39.841 ++#define NETIF_F_GSO		2048	/* Enable software GSO. */
  39.842 + #define NETIF_F_LLTX		4096	/* LockLess TX */
  39.843 +-#define NETIF_F_UFO             8192    /* Can offload UDP Large Send*/
  39.844 ++
  39.845 ++	/* Segmentation offload features */
  39.846 ++#define NETIF_F_GSO_SHIFT	16
  39.847 ++#define NETIF_F_TSO		(SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
  39.848 ++#define NETIF_F_UFO		(SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT)
  39.849 ++#define NETIF_F_GSO_ROBUST	(SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
  39.850 ++
  39.851 ++#define NETIF_F_GEN_CSUM	(NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
  39.852 ++#define NETIF_F_ALL_CSUM	(NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM)
  39.853 + 
  39.854 + 	struct net_device	*next_sched;
  39.855 + 
  39.856 +@@ -394,6 +403,9 @@
  39.857 + 	struct list_head	qdisc_list;
  39.858 + 	unsigned long		tx_queue_len;	/* Max frames per queue allowed */
  39.859 + 
  39.860 ++	/* Partially transmitted GSO packet. */
  39.861 ++	struct sk_buff		*gso_skb;
  39.862 ++
  39.863 + 	/* ingress path synchronizer */
  39.864 + 	spinlock_t		ingress_lock;
  39.865 + 	struct Qdisc		*qdisc_ingress;
  39.866 +@@ -402,7 +414,7 @@
  39.867 +  * One part is mostly used on xmit path (device)
  39.868 +  */
  39.869 + 	/* hard_start_xmit synchronizer */
  39.870 +-	spinlock_t		xmit_lock ____cacheline_aligned_in_smp;
  39.871 ++	spinlock_t		_xmit_lock ____cacheline_aligned_in_smp;
  39.872 + 	/* cpu id of processor entered to hard_start_xmit or -1,
  39.873 + 	   if nobody entered there.
  39.874 + 	 */
  39.875 +@@ -527,6 +539,8 @@
  39.876 + 					 struct net_device *,
  39.877 + 					 struct packet_type *,
  39.878 + 					 struct net_device *);
  39.879 ++	struct sk_buff		*(*gso_segment)(struct sk_buff *skb,
  39.880 ++						int features);
  39.881 + 	void			*af_packet_priv;
  39.882 + 	struct list_head	list;
  39.883 + };
  39.884 +@@ -693,7 +707,8 @@
  39.885 + extern int		dev_set_mtu(struct net_device *, int);
  39.886 + extern int		dev_set_mac_address(struct net_device *,
  39.887 + 					    struct sockaddr *);
  39.888 +-extern void		dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev);
  39.889 ++extern int		dev_hard_start_xmit(struct sk_buff *skb,
  39.890 ++					    struct net_device *dev);
  39.891 + 
  39.892 + extern void		dev_init(void);
  39.893 + 
  39.894 +@@ -900,11 +915,43 @@
  39.895 + 	clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
  39.896 + }
  39.897 + 
  39.898 ++static inline void netif_tx_lock(struct net_device *dev)
  39.899 ++{
  39.900 ++	spin_lock(&dev->_xmit_lock);
  39.901 ++	dev->xmit_lock_owner = smp_processor_id();
  39.902 ++}
  39.903 ++
  39.904 ++static inline void netif_tx_lock_bh(struct net_device *dev)
  39.905 ++{
  39.906 ++	spin_lock_bh(&dev->_xmit_lock);
  39.907 ++	dev->xmit_lock_owner = smp_processor_id();
  39.908 ++}
  39.909 ++
  39.910 ++static inline int netif_tx_trylock(struct net_device *dev)
  39.911 ++{
  39.912 ++	int err = spin_trylock(&dev->_xmit_lock);
  39.913 ++	if (!err)
  39.914 ++		dev->xmit_lock_owner = smp_processor_id();
  39.915 ++	return err;
  39.916 ++}
  39.917 ++
  39.918 ++static inline void netif_tx_unlock(struct net_device *dev)
  39.919 ++{
  39.920 ++	dev->xmit_lock_owner = -1;
  39.921 ++	spin_unlock(&dev->_xmit_lock);
  39.922 ++}
  39.923 ++
  39.924 ++static inline void netif_tx_unlock_bh(struct net_device *dev)
  39.925 ++{
  39.926 ++	dev->xmit_lock_owner = -1;
  39.927 ++	spin_unlock_bh(&dev->_xmit_lock);
  39.928 ++}
  39.929 ++
  39.930 + static inline void netif_tx_disable(struct net_device *dev)
  39.931 + {
  39.932 +-	spin_lock_bh(&dev->xmit_lock);
  39.933 ++	netif_tx_lock_bh(dev);
  39.934 + 	netif_stop_queue(dev);
  39.935 +-	spin_unlock_bh(&dev->xmit_lock);
  39.936 ++	netif_tx_unlock_bh(dev);
  39.937 + }
  39.938 + 
  39.939 + /* These functions live elsewhere (drivers/net/net_init.c, but related) */
  39.940 +@@ -932,6 +979,7 @@
  39.941 + extern int		weight_p;
  39.942 + extern int		netdev_set_master(struct net_device *dev, struct net_device *master);
  39.943 + extern int skb_checksum_help(struct sk_buff *skb, int inward);
  39.944 ++extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features);
  39.945 + #ifdef CONFIG_BUG
  39.946 + extern void netdev_rx_csum_fault(struct net_device *dev);
  39.947 + #else
  39.948 +@@ -951,6 +999,18 @@
  39.949 + 
  39.950 + extern void linkwatch_run_queue(void);
  39.951 + 
  39.952 ++static inline int skb_gso_ok(struct sk_buff *skb, int features)
  39.953 ++{
  39.954 ++	int feature = skb_shinfo(skb)->gso_size ?
  39.955 ++		      skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT : 0;
  39.956 ++	return (features & feature) == feature;
  39.957 ++}
  39.958 ++
  39.959 ++static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
  39.960 ++{
  39.961 ++	return !skb_gso_ok(skb, dev->features);
  39.962 ++}
  39.963 ++
  39.964 + #endif /* __KERNEL__ */
  39.965 + 
  39.966 + #endif	/* _LINUX_DEV_H */
  39.967 +Index: tmp-xxx/include/linux/skbuff.h
  39.968 +===================================================================
  39.969 +--- tmp-xxx.orig/include/linux/skbuff.h	2006-11-15 10:38:39.000000000 +0000
  39.970 ++++ tmp-xxx/include/linux/skbuff.h	2006-11-27 10:52:42.000000000 +0000
  39.971 +@@ -134,9 +134,10 @@
  39.972 + struct skb_shared_info {
  39.973 + 	atomic_t	dataref;
  39.974 + 	unsigned short	nr_frags;
  39.975 +-	unsigned short	tso_size;
  39.976 +-	unsigned short	tso_segs;
  39.977 +-	unsigned short  ufo_size;
  39.978 ++	unsigned short	gso_size;
  39.979 ++	/* Warning: this field is not always filled in (UFO)! */
  39.980 ++	unsigned short	gso_segs;
  39.981 ++	unsigned short  gso_type;
  39.982 + 	unsigned int    ip6_frag_id;
  39.983 + 	struct sk_buff	*frag_list;
  39.984 + 	skb_frag_t	frags[MAX_SKB_FRAGS];
  39.985 +@@ -168,6 +169,14 @@
  39.986 + 	SKB_FCLONE_CLONE,
  39.987 + };
  39.988 + 
  39.989 ++enum {
  39.990 ++	SKB_GSO_TCPV4 = 1 << 0,
  39.991 ++	SKB_GSO_UDPV4 = 1 << 1,
  39.992 ++
  39.993 ++	/* This indicates the skb is from an untrusted source. */
  39.994 ++	SKB_GSO_DODGY = 1 << 2,
  39.995 ++};
  39.996 ++
  39.997 + /** 
  39.998 +  *	struct sk_buff - socket buffer
  39.999 +  *	@next: Next buffer in list
 39.1000 +@@ -1148,18 +1157,34 @@
 39.1001 + 	return 0;
 39.1002 + }
 39.1003 + 
 39.1004 ++static inline int __skb_linearize(struct sk_buff *skb)
 39.1005 ++{
 39.1006 ++	return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
 39.1007 ++}
 39.1008 ++
 39.1009 + /**
 39.1010 +  *	skb_linearize - convert paged skb to linear one
 39.1011 +  *	@skb: buffer to linarize
 39.1012 +- *	@gfp: allocation mode
 39.1013 +  *
 39.1014 +  *	If there is no free memory -ENOMEM is returned, otherwise zero
 39.1015 +  *	is returned and the old skb data released.
 39.1016 +  */
 39.1017 +-extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
 39.1018 +-static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
 39.1019 ++static inline int skb_linearize(struct sk_buff *skb)
 39.1020 ++{
 39.1021 ++	return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;
 39.1022 ++}
 39.1023 ++
 39.1024 ++/**
 39.1025 ++ *	skb_linearize_cow - make sure skb is linear and writable
 39.1026 ++ *	@skb: buffer to process
 39.1027 ++ *
 39.1028 ++ *	If there is no free memory -ENOMEM is returned, otherwise zero
 39.1029 ++ *	is returned and the old skb data released.
 39.1030 ++ */
 39.1031 ++static inline int skb_linearize_cow(struct sk_buff *skb)
 39.1032 + {
 39.1033 +-	return __skb_linearize(skb, gfp);
 39.1034 ++	return skb_is_nonlinear(skb) || skb_cloned(skb) ?
 39.1035 ++	       __skb_linearize(skb) : 0;
 39.1036 + }
 39.1037 + 
 39.1038 + /**
 39.1039 +@@ -1254,6 +1279,7 @@
 39.1040 + 				 struct sk_buff *skb1, const u32 len);
 39.1041 + 
 39.1042 + extern void	       skb_release_data(struct sk_buff *skb);
 39.1043 ++extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
 39.1044 + 
 39.1045 + static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
 39.1046 + 				       int len, void *buffer)
 39.1047 +Index: tmp-xxx/include/net/pkt_sched.h
 39.1048 +===================================================================
 39.1049 +--- tmp-xxx.orig/include/net/pkt_sched.h	2006-11-15 10:38:39.000000000 +0000
 39.1050 ++++ tmp-xxx/include/net/pkt_sched.h	2006-11-27 10:52:42.000000000 +0000
 39.1051 +@@ -218,12 +218,13 @@
 39.1052 + 		struct rtattr *tab);
 39.1053 + extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
 39.1054 + 
 39.1055 +-extern int qdisc_restart(struct net_device *dev);
 39.1056 ++extern void __qdisc_run(struct net_device *dev);
 39.1057 + 
 39.1058 + static inline void qdisc_run(struct net_device *dev)
 39.1059 + {
 39.1060 +-	while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0)
 39.1061 +-		/* NOTHING */;
 39.1062 ++	if (!netif_queue_stopped(dev) &&
 39.1063 ++	    !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
 39.1064 ++		__qdisc_run(dev);
 39.1065 + }
 39.1066 + 
 39.1067 + extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
 39.1068 +