[kernel] r7390 - in dists/sid/linux-2.6/debian: . patches patches/series

Frederik Schüler fs at costa.debian.org
Tue Sep 12 11:56:47 UTC 2006


Author: fs
Date: Tue Sep 12 11:56:47 2006
New Revision: 7390

Added:
   dists/sid/linux-2.6/debian/patches/2.6.17.12
   dists/sid/linux-2.6/debian/patches/2.6.17.13
Removed:
   dists/sid/linux-2.6/debian/patches/drivers-ide-pci-via82cxxx-vt8237a-id-2.patch
   dists/sid/linux-2.6/debian/patches/drivers-ide-pci-via82cxxx-vt8237a-id.patch
   dists/sid/linux-2.6/debian/patches/s390-kernel-futex-barrier.patch
Modified:
   dists/sid/linux-2.6/debian/changelog
   dists/sid/linux-2.6/debian/patches/series/7-extra
   dists/sid/linux-2.6/debian/patches/series/9

Log:
Add stable release 2.5.17.12
Add stable release 2.6.17.13
Remove patches merged upstream:
 - s390-kernel-futex-barrier.patch
 - drivers-ide-pci-via82cxxx-vt8237a-id.patch
 - drivers-ide-pci-via82cxxx-vt8237a-id-2.patch
Unpatch ia64-mman.h-fix.patch



Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog	(original)
+++ dists/sid/linux-2.6/debian/changelog	Tue Sep 12 11:56:47 2006
@@ -9,7 +9,54 @@
   * Update vserver patch to 2.0.2.
     - Fix possible priviledge escalation in remount code. (CVE-2006-4243)
 
- -- Bastian Blank <waldi at debian.org>  Mon, 11 Sep 2006 14:44:18 +0200
+  [ Frederik Schüler ]
+  * Add stable release 2.5.17.12:
+    - sky2: version 1.6.1
+    - sky2: fix fiber support
+    - sky2: MSI test timing
+    - sky2: use dev_alloc_skb for receive buffers
+    - sky2: clear status IRQ after empty
+    - sky2: accept flow control
+    - dm: Fix deadlock under high i/o load in raid1 setup.
+    - Remove redundant up() in stop_machine()
+    - Missing PCI id update for VIA IDE
+    - PKTGEN: Fix oops when used with balance-tlb bonding
+    - PKTGEN: Make sure skb->{nh,h} are initialized in fill_packet_ipv6() too.
+    - Silent data corruption caused by XPC
+    - uhci-hcd: fix list access bug
+    - binfmt_elf: fix checks for bad address
+    - [s390] bug in futex unqueue_me
+    - fcntl(F_SETSIG) fix
+    - IPV6 OOPS'er triggerable by any user
+    - SCTP: Fix sctp_primitive_ABORT() call in sctp_close().
+    - SPARC64: Fix X server crashes on sparc64
+    - TG3: Disable TSO by default
+    - dm: mirror sector offset fix
+    - dm: fix block device initialisation
+    - dm: add module ref counting
+    - dm: fix mapped device ref counting
+    - dm: add DMF_FREEING
+    - dm: change minor_lock to spinlock
+    - dm: move idr_pre_get
+    - dm: fix idr minor allocation
+    - dm snapshot: unify chunk_size
+    - Have ext2 reject file handles with bad inode numbers early.
+    - Allow per-route window scale limiting
+    - bridge-netfilter: don't overwrite memory outside of skb
+    - fix compilation error on IA64
+    - Fix output framentation of paged-skbs
+    - spectrum_cs: Fix firmware uploading errors
+    - TEXTSEARCH: Fix Boyer Moore initialization bug
+  * Add stable release 2.6.17.13:
+    - lib: add idr_replace
+    - pci_ids.h: add some VIA IDE identifiers
+  * Remove patches merged upstream:
+    - s390-kernel-futex-barrier.patch 
+    - drivers-ide-pci-via82cxxx-vt8237a-id.patch
+    - drivers-ide-pci-via82cxxx-vt8237a-id-2.patch
+  * Unpatch ia64-mman.h-fix.patch
+
+ -- Frederik Schüler <fs at debian.org>  Tue, 12 Sep 2006 13:49:32 +0200
 
 linux-2.6 (2.6.17-8) unstable; urgency=low
 

Added: dists/sid/linux-2.6/debian/patches/2.6.17.12
==============================================================================
--- (empty file)
+++ dists/sid/linux-2.6/debian/patches/2.6.17.12	Tue Sep 12 11:56:47 2006
@@ -0,0 +1,1751 @@
+diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
+index 8255a9b..7e8a4d1 100644
+--- a/arch/ia64/sn/kernel/xpc_channel.c
++++ b/arch/ia64/sn/kernel/xpc_channel.c
+@@ -279,8 +279,8 @@ xpc_pull_remote_cachelines(struct xpc_pa
+ 		return part->reason;
+ 	}
+ 
+-	bte_ret = xp_bte_copy((u64) src, (u64) ia64_tpa((u64) dst),
+-				(u64) cnt, (BTE_NORMAL | BTE_WACQUIRE), NULL);
++	bte_ret = xp_bte_copy((u64) src, (u64) dst, (u64) cnt,
++					(BTE_NORMAL | BTE_WACQUIRE), NULL);
+ 	if (bte_ret == BTE_SUCCESS) {
+ 		return xpcSuccess;
+ 	}
+diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
+index 99b123a..440039f 100644
+--- a/arch/ia64/sn/kernel/xpc_main.c
++++ b/arch/ia64/sn/kernel/xpc_main.c
+@@ -1052,6 +1052,8 @@ xpc_do_exit(enum xpc_retval reason)
+ 	if (xpc_sysctl) {
+ 		unregister_sysctl_table(xpc_sysctl);
+ 	}
++
++	kfree(xpc_remote_copy_buffer_base);
+ }
+ 
+ 
+@@ -1212,24 +1214,20 @@ xpc_init(void)
+ 	partid_t partid;
+ 	struct xpc_partition *part;
+ 	pid_t pid;
++	size_t buf_size;
+ 
+ 
+ 	if (!ia64_platform_is("sn2")) {
+ 		return -ENODEV;
+ 	}
+ 
+-	/*
+-	 * xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng
+-	 * various portions of a partition's reserved page. Its size is based
+-	 * on the size of the reserved page header and part_nasids mask. So we
+-	 * need to ensure that the other items will fit as well.
+-	 */
+-	if (XPC_RP_VARS_SIZE > XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES) {
+-		dev_err(xpc_part, "xpc_remote_copy_buffer is not big enough\n");
+-		return -EPERM;
+-	}
+-	DBUG_ON((u64) xpc_remote_copy_buffer !=
+-				L1_CACHE_ALIGN((u64) xpc_remote_copy_buffer));
++
++	buf_size = max(XPC_RP_VARS_SIZE,
++				XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES);
++	xpc_remote_copy_buffer = xpc_kmalloc_cacheline_aligned(buf_size,
++				     GFP_KERNEL, &xpc_remote_copy_buffer_base);
++	if (xpc_remote_copy_buffer == NULL)
++		return -ENOMEM;
+ 
+ 	snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part");
+ 	snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan");
+@@ -1293,6 +1291,8 @@ xpc_init(void)
+ 		if (xpc_sysctl) {
+ 			unregister_sysctl_table(xpc_sysctl);
+ 		}
++
++		kfree(xpc_remote_copy_buffer_base);
+ 		return -EBUSY;
+ 	}
+ 
+@@ -1311,6 +1311,8 @@ xpc_init(void)
+ 		if (xpc_sysctl) {
+ 			unregister_sysctl_table(xpc_sysctl);
+ 		}
++
++		kfree(xpc_remote_copy_buffer_base);
+ 		return -EBUSY;
+ 	}
+ 
+@@ -1362,6 +1364,8 @@ xpc_init(void)
+ 		if (xpc_sysctl) {
+ 			unregister_sysctl_table(xpc_sysctl);
+ 		}
++
++		kfree(xpc_remote_copy_buffer_base);
+ 		return -EBUSY;
+ 	}
+ 
+diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c
+index 2a89cfc..57c723f 100644
+--- a/arch/ia64/sn/kernel/xpc_partition.c
++++ b/arch/ia64/sn/kernel/xpc_partition.c
+@@ -71,19 +71,15 @@ struct xpc_partition xpc_partitions[XP_M
+  * Generic buffer used to store a local copy of portions of a remote
+  * partition's reserved page (either its header and part_nasids mask,
+  * or its vars).
+- *
+- * xpc_discovery runs only once and is a seperate thread that is
+- * very likely going to be processing in parallel with receiving
+- * interrupts.
+  */
+-char ____cacheline_aligned xpc_remote_copy_buffer[XPC_RP_HEADER_SIZE +
+-							XP_NASID_MASK_BYTES];
++char *xpc_remote_copy_buffer;
++void *xpc_remote_copy_buffer_base;
+ 
+ 
+ /*
+  * Guarantee that the kmalloc'd memory is cacheline aligned.
+  */
+-static void *
++void *
+ xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
+ {
+ 	/* see if kmalloc will give us cachline aligned memory by default */
+@@ -148,7 +144,7 @@ xpc_get_rsvd_page_pa(int nasid)
+ 			}
+ 		}
+ 
+-		bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_len,
++		bte_res = xp_bte_copy(rp_pa, buf, buf_len,
+ 					(BTE_NOTIFY | BTE_WACQUIRE), NULL);
+ 		if (bte_res != BTE_SUCCESS) {
+ 			dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res);
+@@ -447,7 +443,7 @@ xpc_check_remote_hb(void)
+ 
+ 		/* pull the remote_hb cache line */
+ 		bres = xp_bte_copy(part->remote_vars_pa,
+-					ia64_tpa((u64) remote_vars),
++					(u64) remote_vars,
+ 					XPC_RP_VARS_SIZE,
+ 					(BTE_NOTIFY | BTE_WACQUIRE), NULL);
+ 		if (bres != BTE_SUCCESS) {
+@@ -498,8 +494,7 @@ xpc_get_remote_rp(int nasid, u64 *discov
+ 
+ 
+ 	/* pull over the reserved page header and part_nasids mask */
+-
+-	bres = xp_bte_copy(*remote_rp_pa, ia64_tpa((u64) remote_rp),
++	bres = xp_bte_copy(*remote_rp_pa, (u64) remote_rp,
+ 				XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes,
+ 				(BTE_NOTIFY | BTE_WACQUIRE), NULL);
+ 	if (bres != BTE_SUCCESS) {
+@@ -554,11 +549,8 @@ xpc_get_remote_vars(u64 remote_vars_pa, 
+ 		return xpcVarsNotSet;
+ 	}
+ 
+-
+ 	/* pull over the cross partition variables */
+-
+-	bres = xp_bte_copy(remote_vars_pa, ia64_tpa((u64) remote_vars),
+-				XPC_RP_VARS_SIZE,
++	bres = xp_bte_copy(remote_vars_pa, (u64) remote_vars, XPC_RP_VARS_SIZE,
+ 				(BTE_NOTIFY | BTE_WACQUIRE), NULL);
+ 	if (bres != BTE_SUCCESS) {
+ 		return xpc_map_bte_errors(bres);
+@@ -1239,7 +1231,7 @@ xpc_initiate_partid_to_nasids(partid_t p
+ 
+ 	part_nasid_pa = (u64) XPC_RP_PART_NASIDS(part->remote_rp_pa);
+ 
+-	bte_res = xp_bte_copy(part_nasid_pa, ia64_tpa((u64) nasid_mask),
++	bte_res = xp_bte_copy(part_nasid_pa, (u64) nasid_mask,
+ 			xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
+ 
+ 	return xpc_map_bte_errors(bte_res);
+diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c
+index 8cb0620..af9d81d 100644
+--- a/arch/sparc64/mm/generic.c
++++ b/arch/sparc64/mm/generic.c
+@@ -69,6 +69,8 @@ static inline void io_remap_pte_range(st
+ 		} else
+ 			offset += PAGE_SIZE;
+ 
++		if (pte_write(entry))
++			entry = pte_mkdirty(entry);
+ 		do {
+ 			BUG_ON(!pte_none(*pte));
+ 			set_pte_at(mm, address, pte, entry);
+diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
+index 3e677c4..9914a78 100644
+--- a/drivers/ide/pci/via82cxxx.c
++++ b/drivers/ide/pci/via82cxxx.c
+@@ -6,7 +6,7 @@
+  *
+  *   vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
+  *   vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a,
+- *   vt8235, vt8237
++ *   vt8235, vt8237, vt8237a
+  *
+  * Copyright (c) 2000-2002 Vojtech Pavlik
+  *
+@@ -82,6 +82,7 @@ static struct via_isa_bridge {
+ 	{ "vt6410",	PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+ 	{ "vt8251",	PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+ 	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
++	{ "vt8237a",	PCI_DEVICE_ID_VIA_8237A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+ 	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+ 	{ "vt8233a",	PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+ 	{ "vt8233c",	PCI_DEVICE_ID_VIA_8233C_0,  0x00, 0x2f, VIA_UDMA_100 },
+diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
+index cc07bbe..34a7593 100644
+--- a/drivers/md/dm-exception-store.c
++++ b/drivers/md/dm-exception-store.c
+@@ -91,7 +91,6 @@ struct pstore {
+ 	struct dm_snapshot *snap;	/* up pointer to my snapshot */
+ 	int version;
+ 	int valid;
+-	uint32_t chunk_size;
+ 	uint32_t exceptions_per_area;
+ 
+ 	/*
+@@ -133,7 +132,7 @@ static int alloc_area(struct pstore *ps)
+ 	int r = -ENOMEM;
+ 	size_t len;
+ 
+-	len = ps->chunk_size << SECTOR_SHIFT;
++	len = ps->snap->chunk_size << SECTOR_SHIFT;
+ 
+ 	/*
+ 	 * Allocate the chunk_size block of memory that will hold
+@@ -160,8 +159,8 @@ static int chunk_io(struct pstore *ps, u
+ 	unsigned long bits;
+ 
+ 	where.bdev = ps->snap->cow->bdev;
+-	where.sector = ps->chunk_size * chunk;
+-	where.count = ps->chunk_size;
++	where.sector = ps->snap->chunk_size * chunk;
++	where.count = ps->snap->chunk_size;
+ 
+ 	return dm_io_sync_vm(1, &where, rw, ps->area, &bits);
+ }
+@@ -188,7 +187,7 @@ static int area_io(struct pstore *ps, ui
+ 
+ static int zero_area(struct pstore *ps, uint32_t area)
+ {
+-	memset(ps->area, 0, ps->chunk_size << SECTOR_SHIFT);
++	memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
+ 	return area_io(ps, area, WRITE);
+ }
+ 
+@@ -196,6 +195,7 @@ static int read_header(struct pstore *ps
+ {
+ 	int r;
+ 	struct disk_header *dh;
++	chunk_t chunk_size;
+ 
+ 	r = chunk_io(ps, 0, READ);
+ 	if (r)
+@@ -210,8 +210,29 @@ static int read_header(struct pstore *ps
+ 		*new_snapshot = 0;
+ 		ps->valid = le32_to_cpu(dh->valid);
+ 		ps->version = le32_to_cpu(dh->version);
+-		ps->chunk_size = le32_to_cpu(dh->chunk_size);
+-
++		chunk_size = le32_to_cpu(dh->chunk_size);
++		if (ps->snap->chunk_size != chunk_size) {
++			DMWARN("chunk size %llu in device metadata overrides "
++			       "table chunk size of %llu.",
++			       (unsigned long long)chunk_size,
++			       (unsigned long long)ps->snap->chunk_size);
++
++			/* We had a bogus chunk_size. Fix stuff up. */
++			dm_io_put(sectors_to_pages(ps->snap->chunk_size));
++			free_area(ps);
++
++			ps->snap->chunk_size = chunk_size;
++			ps->snap->chunk_mask = chunk_size - 1;
++			ps->snap->chunk_shift = ffs(chunk_size) - 1;
++
++			r = alloc_area(ps);
++			if (r)
++				return r;
++
++			r = dm_io_get(sectors_to_pages(chunk_size));
++			if (r)
++				return r;
++		}
+ 	} else {
+ 		DMWARN("Invalid/corrupt snapshot");
+ 		r = -ENXIO;
+@@ -224,13 +245,13 @@ static int write_header(struct pstore *p
+ {
+ 	struct disk_header *dh;
+ 
+-	memset(ps->area, 0, ps->chunk_size << SECTOR_SHIFT);
++	memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
+ 
+ 	dh = (struct disk_header *) ps->area;
+ 	dh->magic = cpu_to_le32(SNAP_MAGIC);
+ 	dh->valid = cpu_to_le32(ps->valid);
+ 	dh->version = cpu_to_le32(ps->version);
+-	dh->chunk_size = cpu_to_le32(ps->chunk_size);
++	dh->chunk_size = cpu_to_le32(ps->snap->chunk_size);
+ 
+ 	return chunk_io(ps, 0, WRITE);
+ }
+@@ -365,7 +386,7 @@ static void persistent_destroy(struct ex
+ {
+ 	struct pstore *ps = get_info(store);
+ 
+-	dm_io_put(sectors_to_pages(ps->chunk_size));
++	dm_io_put(sectors_to_pages(ps->snap->chunk_size));
+ 	vfree(ps->callbacks);
+ 	free_area(ps);
+ 	kfree(ps);
+@@ -384,6 +405,16 @@ static int persistent_read_metadata(stru
+ 		return r;
+ 
+ 	/*
++	 * Now we know correct chunk_size, complete the initialisation.
++	 */
++	ps->exceptions_per_area = (ps->snap->chunk_size << SECTOR_SHIFT) /
++				  sizeof(struct disk_exception);
++	ps->callbacks = dm_vcalloc(ps->exceptions_per_area,
++			sizeof(*ps->callbacks));
++	if (!ps->callbacks)
++		return -ENOMEM;
++
++	/*
+ 	 * Do we need to setup a new snapshot ?
+ 	 */
+ 	if (new_snapshot) {
+@@ -533,9 +564,6 @@ int dm_create_persistent(struct exceptio
+ 	ps->snap = store->snap;
+ 	ps->valid = 1;
+ 	ps->version = SNAPSHOT_DISK_VERSION;
+-	ps->chunk_size = chunk_size;
+-	ps->exceptions_per_area = (chunk_size << SECTOR_SHIFT) /
+-	    sizeof(struct disk_exception);
+ 	ps->next_free = 2;	/* skipping the header and first area */
+ 	ps->current_committed = 0;
+ 
+@@ -543,18 +571,9 @@ int dm_create_persistent(struct exceptio
+ 	if (r)
+ 		goto bad;
+ 
+-	/*
+-	 * Allocate space for all the callbacks.
+-	 */
+ 	ps->callback_count = 0;
+ 	atomic_set(&ps->pending_count, 0);
+-	ps->callbacks = dm_vcalloc(ps->exceptions_per_area,
+-				   sizeof(*ps->callbacks));
+-
+-	if (!ps->callbacks) {
+-		r = -ENOMEM;
+-		goto bad;
+-	}
++	ps->callbacks = NULL;
+ 
+ 	store->destroy = persistent_destroy;
+ 	store->read_metadata = persistent_read_metadata;
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index 8edd643..f7e7436 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -102,8 +102,10 @@ static struct hash_cell *__get_name_cell
+ 	unsigned int h = hash_str(str);
+ 
+ 	list_for_each_entry (hc, _name_buckets + h, name_list)
+-		if (!strcmp(hc->name, str))
++		if (!strcmp(hc->name, str)) {
++			dm_get(hc->md);
+ 			return hc;
++		}
+ 
+ 	return NULL;
+ }
+@@ -114,8 +116,10 @@ static struct hash_cell *__get_uuid_cell
+ 	unsigned int h = hash_str(str);
+ 
+ 	list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
+-		if (!strcmp(hc->uuid, str))
++		if (!strcmp(hc->uuid, str)) {
++			dm_get(hc->md);
+ 			return hc;
++		}
+ 
+ 	return NULL;
+ }
+@@ -191,7 +195,7 @@ static int unregister_with_devfs(struct 
+  */
+ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md)
+ {
+-	struct hash_cell *cell;
++	struct hash_cell *cell, *hc;
+ 
+ 	/*
+ 	 * Allocate the new cells.
+@@ -204,14 +208,19 @@ static int dm_hash_insert(const char *na
+ 	 * Insert the cell into both hash tables.
+ 	 */
+ 	down_write(&_hash_lock);
+-	if (__get_name_cell(name))
++	hc = __get_name_cell(name);
++	if (hc) {
++		dm_put(hc->md);
+ 		goto bad;
++	}
+ 
+ 	list_add(&cell->name_list, _name_buckets + hash_str(name));
+ 
+ 	if (uuid) {
+-		if (__get_uuid_cell(uuid)) {
++		hc = __get_uuid_cell(uuid);
++		if (hc) {
+ 			list_del(&cell->name_list);
++			dm_put(hc->md);
+ 			goto bad;
+ 		}
+ 		list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
+@@ -289,6 +298,7 @@ static int dm_hash_rename(const char *ol
+ 	if (hc) {
+ 		DMWARN("asked to rename to an already existing name %s -> %s",
+ 		       old, new);
++		dm_put(hc->md);
+ 		up_write(&_hash_lock);
+ 		kfree(new_name);
+ 		return -EBUSY;
+@@ -328,6 +338,7 @@ static int dm_hash_rename(const char *ol
+ 		dm_table_put(table);
+ 	}
+ 
++	dm_put(hc->md);
+ 	up_write(&_hash_lock);
+ 	kfree(old_name);
+ 	return 0;
+@@ -611,10 +622,8 @@ static struct hash_cell *__find_device_h
+ 		return __get_name_cell(param->name);
+ 
+ 	md = dm_get_md(huge_decode_dev(param->dev));
+-	if (md) {
++	if (md)
+ 		mdptr = dm_get_mdptr(md);
+-		dm_put(md);
+-	}
+ 
+ 	return mdptr;
+ }
+@@ -628,7 +637,6 @@ static struct mapped_device *find_device
+ 	hc = __find_device_hash_cell(param);
+ 	if (hc) {
+ 		md = hc->md;
+-		dm_get(md);
+ 
+ 		/*
+ 		 * Sneakily write in both the name and the uuid
+@@ -653,6 +661,7 @@ static struct mapped_device *find_device
+ static int dev_remove(struct dm_ioctl *param, size_t param_size)
+ {
+ 	struct hash_cell *hc;
++	struct mapped_device *md;
+ 
+ 	down_write(&_hash_lock);
+ 	hc = __find_device_hash_cell(param);
+@@ -663,8 +672,11 @@ static int dev_remove(struct dm_ioctl *p
+ 		return -ENXIO;
+ 	}
+ 
++	md = hc->md;
++
+ 	__hash_remove(hc);
+ 	up_write(&_hash_lock);
++	dm_put(md);
+ 	param->data_size = 0;
+ 	return 0;
+ }
+@@ -790,7 +802,6 @@ static int do_resume(struct dm_ioctl *pa
+ 	}
+ 
+ 	md = hc->md;
+-	dm_get(md);
+ 
+ 	new_map = hc->new_map;
+ 	hc->new_map = NULL;
+@@ -1078,6 +1089,7 @@ static int table_clear(struct dm_ioctl *
+ {
+ 	int r;
+ 	struct hash_cell *hc;
++	struct mapped_device *md;
+ 
+ 	down_write(&_hash_lock);
+ 
+@@ -1096,7 +1108,9 @@ static int table_clear(struct dm_ioctl *
+ 	param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
+ 
+ 	r = __dev_status(hc->md, param);
++	md = hc->md;
+ 	up_write(&_hash_lock);
++	dm_put(md);
+ 	return r;
+ }
+ 
+diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
+index d12cf3e..2cab46e 100644
+--- a/drivers/md/dm-raid1.c
++++ b/drivers/md/dm-raid1.c
+@@ -106,12 +106,42 @@ struct region {
+ 	struct bio_list delayed_bios;
+ };
+ 
++
++/*-----------------------------------------------------------------
++ * Mirror set structures.
++ *---------------------------------------------------------------*/
++struct mirror {
++	atomic_t error_count;
++	struct dm_dev *dev;
++	sector_t offset;
++};
++
++struct mirror_set {
++	struct dm_target *ti;
++	struct list_head list;
++	struct region_hash rh;
++	struct kcopyd_client *kcopyd_client;
++
++	spinlock_t lock;	/* protects the next two lists */
++	struct bio_list reads;
++	struct bio_list writes;
++
++	/* recovery */
++	region_t nr_regions;
++	int in_sync;
++
++	struct mirror *default_mirror;	/* Default mirror */
++
++	unsigned int nr_mirrors;
++	struct mirror mirror[0];
++};
++
+ /*
+  * Conversion fns
+  */
+ static inline region_t bio_to_region(struct region_hash *rh, struct bio *bio)
+ {
+-	return bio->bi_sector >> rh->region_shift;
++	return (bio->bi_sector - rh->ms->ti->begin) >> rh->region_shift;
+ }
+ 
+ static inline sector_t region_to_sector(struct region_hash *rh, region_t region)
+@@ -223,7 +253,9 @@ static struct region *__rh_alloc(struct 
+ 	struct region *reg, *nreg;
+ 
+ 	read_unlock(&rh->hash_lock);
+-	nreg = mempool_alloc(rh->region_pool, GFP_NOIO);
++	nreg = mempool_alloc(rh->region_pool, GFP_ATOMIC);
++	if (unlikely(!nreg))
++		nreg = kmalloc(sizeof(struct region), GFP_NOIO);
+ 	nreg->state = rh->log->type->in_sync(rh->log, region, 1) ?
+ 		RH_CLEAN : RH_NOSYNC;
+ 	nreg->rh = rh;
+@@ -541,35 +573,6 @@ static void rh_start_recovery(struct reg
+ 	wake();
+ }
+ 
+-/*-----------------------------------------------------------------
+- * Mirror set structures.
+- *---------------------------------------------------------------*/
+-struct mirror {
+-	atomic_t error_count;
+-	struct dm_dev *dev;
+-	sector_t offset;
+-};
+-
+-struct mirror_set {
+-	struct dm_target *ti;
+-	struct list_head list;
+-	struct region_hash rh;
+-	struct kcopyd_client *kcopyd_client;
+-
+-	spinlock_t lock;	/* protects the next two lists */
+-	struct bio_list reads;
+-	struct bio_list writes;
+-
+-	/* recovery */
+-	region_t nr_regions;
+-	int in_sync;
+-
+-	struct mirror *default_mirror;	/* Default mirror */
+-
+-	unsigned int nr_mirrors;
+-	struct mirror mirror[0];
+-};
+-
+ /*
+  * Every mirror should look like this one.
+  */
+@@ -1115,7 +1118,7 @@ static int mirror_map(struct dm_target *
+ 	struct mirror *m;
+ 	struct mirror_set *ms = ti->private;
+ 
+-	map_context->ll = bio->bi_sector >> ms->rh.region_shift;
++	map_context->ll = bio_to_region(&ms->rh, bio);
+ 
+ 	if (rw == WRITE) {
+ 		queue_bio(ms, bio, rw);
+diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
+index 08312b4..b84bc1a 100644
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -530,7 +530,7 @@ static int snapshot_ctr(struct dm_target
+ 	}
+ 
+ 	ti->private = s;
+-	ti->split_io = chunk_size;
++	ti->split_io = s->chunk_size;
+ 
+ 	return 0;
+ 
+@@ -1204,7 +1204,7 @@ static int origin_status(struct dm_targe
+ 
+ static struct target_type origin_target = {
+ 	.name    = "snapshot-origin",
+-	.version = {1, 1, 0},
++	.version = {1, 4, 0},
+ 	.module  = THIS_MODULE,
+ 	.ctr     = origin_ctr,
+ 	.dtr     = origin_dtr,
+@@ -1215,7 +1215,7 @@ static struct target_type origin_target 
+ 
+ static struct target_type snapshot_target = {
+ 	.name    = "snapshot",
+-	.version = {1, 1, 0},
++	.version = {1, 4, 0},
+ 	.module  = THIS_MODULE,
+ 	.ctr     = snapshot_ctr,
+ 	.dtr     = snapshot_dtr,
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 4d710b7..dfd0378 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -26,6 +26,7 @@ static const char *_name = DM_NAME;
+ static unsigned int major = 0;
+ static unsigned int _major = 0;
+ 
++static DEFINE_SPINLOCK(_minor_lock);
+ /*
+  * One of these is allocated per bio.
+  */
+@@ -54,12 +55,15 @@ union map_info *dm_get_mapinfo(struct bi
+         return NULL;
+ }
+ 
++#define MINOR_ALLOCED ((void *)-1)
++
+ /*
+  * Bits for the md->flags field.
+  */
+ #define DMF_BLOCK_IO 0
+ #define DMF_SUSPENDED 1
+ #define DMF_FROZEN 2
++#define DMF_FREEING 3
+ 
+ struct mapped_device {
+ 	struct rw_semaphore io_lock;
+@@ -218,9 +222,23 @@ static int dm_blk_open(struct inode *ino
+ {
+ 	struct mapped_device *md;
+ 
++	spin_lock(&_minor_lock);
++
+ 	md = inode->i_bdev->bd_disk->private_data;
++	if (!md)
++		goto out;
++
++	if (test_bit(DMF_FREEING, &md->flags)) {
++		md = NULL;
++		goto out;
++	}
++
+ 	dm_get(md);
+-	return 0;
++
++out:
++	spin_unlock(&_minor_lock);
++
++	return md ? 0 : -ENXIO;
+ }
+ 
+ static int dm_blk_close(struct inode *inode, struct file *file)
+@@ -744,14 +762,13 @@ static int dm_any_congested(void *conges
+ /*-----------------------------------------------------------------
+  * An IDR is used to keep track of allocated minor numbers.
+  *---------------------------------------------------------------*/
+-static DEFINE_MUTEX(_minor_lock);
+ static DEFINE_IDR(_minor_idr);
+ 
+ static void free_minor(unsigned int minor)
+ {
+-	mutex_lock(&_minor_lock);
++	spin_lock(&_minor_lock);
+ 	idr_remove(&_minor_idr, minor);
+-	mutex_unlock(&_minor_lock);
++	spin_unlock(&_minor_lock);
+ }
+ 
+ /*
+@@ -764,23 +781,20 @@ static int specific_minor(struct mapped_
+ 	if (minor >= (1 << MINORBITS))
+ 		return -EINVAL;
+ 
+-	mutex_lock(&_minor_lock);
++	r = idr_pre_get(&_minor_idr, GFP_KERNEL);
++	if (!r)
++		return -ENOMEM;
++
++	spin_lock(&_minor_lock);
+ 
+ 	if (idr_find(&_minor_idr, minor)) {
+ 		r = -EBUSY;
+ 		goto out;
+ 	}
+ 
+-	r = idr_pre_get(&_minor_idr, GFP_KERNEL);
+-	if (!r) {
+-		r = -ENOMEM;
+-		goto out;
+-	}
+-
+-	r = idr_get_new_above(&_minor_idr, md, minor, &m);
+-	if (r) {
++	r = idr_get_new_above(&_minor_idr, MINOR_ALLOCED, minor, &m);
++	if (r)
+ 		goto out;
+-	}
+ 
+ 	if (m != minor) {
+ 		idr_remove(&_minor_idr, m);
+@@ -789,7 +803,7 @@ static int specific_minor(struct mapped_
+ 	}
+ 
+ out:
+-	mutex_unlock(&_minor_lock);
++	spin_unlock(&_minor_lock);
+ 	return r;
+ }
+ 
+@@ -798,15 +812,13 @@ static int next_free_minor(struct mapped
+ 	int r;
+ 	unsigned int m;
+ 
+-	mutex_lock(&_minor_lock);
+-
+ 	r = idr_pre_get(&_minor_idr, GFP_KERNEL);
+-	if (!r) {
+-		r = -ENOMEM;
+-		goto out;
+-	}
++	if (!r)
++		return -ENOMEM;
+ 
+-	r = idr_get_new(&_minor_idr, md, &m);
++	spin_lock(&_minor_lock);
++
++	r = idr_get_new(&_minor_idr, MINOR_ALLOCED, &m);
+ 	if (r) {
+ 		goto out;
+ 	}
+@@ -820,7 +832,7 @@ static int next_free_minor(struct mapped
+ 	*minor = m;
+ 
+ out:
+-	mutex_unlock(&_minor_lock);
++	spin_unlock(&_minor_lock);
+ 	return r;
+ }
+ 
+@@ -833,12 +845,16 @@ static struct mapped_device *alloc_dev(u
+ {
+ 	int r;
+ 	struct mapped_device *md = kmalloc(sizeof(*md), GFP_KERNEL);
++	void *old_md;
+ 
+ 	if (!md) {
+ 		DMWARN("unable to allocate device, out of memory.");
+ 		return NULL;
+ 	}
+ 
++	if (!try_module_get(THIS_MODULE))
++		goto bad0;
++
+ 	/* get a minor number for the dev */
+ 	r = persistent ? specific_minor(md, minor) : next_free_minor(md, &minor);
+ 	if (r < 0)
+@@ -875,6 +891,10 @@ static struct mapped_device *alloc_dev(u
+ 	if (!md->disk)
+ 		goto bad4;
+ 
++	atomic_set(&md->pending, 0);
++	init_waitqueue_head(&md->wait);
++	init_waitqueue_head(&md->eventq);
++
+ 	md->disk->major = _major;
+ 	md->disk->first_minor = minor;
+ 	md->disk->fops = &dm_blk_dops;
+@@ -884,9 +904,12 @@ static struct mapped_device *alloc_dev(u
+ 	add_disk(md->disk);
+ 	format_dev_t(md->name, MKDEV(_major, minor));
+ 
+-	atomic_set(&md->pending, 0);
+-	init_waitqueue_head(&md->wait);
+-	init_waitqueue_head(&md->eventq);
++	/* Populate the mapping, nobody knows we exist yet */
++	spin_lock(&_minor_lock);
++	old_md = idr_replace(&_minor_idr, md, minor);
++	spin_unlock(&_minor_lock);
++
++	BUG_ON(old_md != MINOR_ALLOCED);
+ 
+ 	return md;
+ 
+@@ -898,6 +921,8 @@ static struct mapped_device *alloc_dev(u
+ 	blk_cleanup_queue(md->queue);
+ 	free_minor(minor);
+  bad1:
++	module_put(THIS_MODULE);
++ bad0:
+ 	kfree(md);
+ 	return NULL;
+ }
+@@ -914,8 +939,14 @@ static void free_dev(struct mapped_devic
+ 	mempool_destroy(md->io_pool);
+ 	del_gendisk(md->disk);
+ 	free_minor(minor);
++
++	spin_lock(&_minor_lock);
++	md->disk->private_data = NULL;
++	spin_unlock(&_minor_lock);
++
+ 	put_disk(md->disk);
+ 	blk_cleanup_queue(md->queue);
++	module_put(THIS_MODULE);
+ 	kfree(md);
+ }
+ 
+@@ -1015,13 +1046,18 @@ static struct mapped_device *dm_find_md(
+ 	if (MAJOR(dev) != _major || minor >= (1 << MINORBITS))
+ 		return NULL;
+ 
+-	mutex_lock(&_minor_lock);
++	spin_lock(&_minor_lock);
+ 
+ 	md = idr_find(&_minor_idr, minor);
+-	if (!md || (dm_disk(md)->first_minor != minor))
++	if (md && (md == MINOR_ALLOCED ||
++		   (dm_disk(md)->first_minor != minor) ||
++	           test_bit(DMF_FREEING, &md->flags))) {
+ 		md = NULL;
++		goto out;
++	}
+ 
+-	mutex_unlock(&_minor_lock);
++out:
++	spin_unlock(&_minor_lock);
+ 
+ 	return md;
+ }
+@@ -1055,8 +1091,13 @@ void dm_put(struct mapped_device *md)
+ {
+ 	struct dm_table *map;
+ 
+-	if (atomic_dec_and_test(&md->holders)) {
++	BUG_ON(test_bit(DMF_FREEING, &md->flags));
++
++	if (atomic_dec_and_lock(&md->holders, &_minor_lock)) {
+ 		map = dm_get_table(md);
++		idr_replace(&_minor_idr, MINOR_ALLOCED, dm_disk(md)->first_minor);
++		set_bit(DMF_FREEING, &md->flags);
++		spin_unlock(&_minor_lock);
+ 		if (!dm_suspended(md)) {
+ 			dm_table_presuspend_targets(map);
+ 			dm_table_postsuspend_targets(map);
+diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
+index 72ca553..cc66193 100644
+--- a/drivers/net/sky2.c
++++ b/drivers/net/sky2.c
+@@ -51,7 +51,7 @@ #endif
+ #include "sky2.h"
+ 
+ #define DRV_NAME		"sky2"
+-#define DRV_VERSION		"1.4"
++#define DRV_VERSION		"1.6.1"
+ #define PFX			DRV_NAME " "
+ 
+ /*
+@@ -321,7 +321,7 @@ static void sky2_phy_init(struct sky2_hw
+ 	}
+ 
+ 	ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+-	if (hw->copper) {
++	if (sky2_is_copper(hw)) {
+ 		if (hw->chip_id == CHIP_ID_YUKON_FE) {
+ 			/* enable automatic crossover */
+ 			ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1;
+@@ -338,25 +338,37 @@ static void sky2_phy_init(struct sky2_hw
+ 				ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
+ 			}
+ 		}
+-		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+ 	} else {
+ 		/* workaround for deviation #4.88 (CRC errors) */
+ 		/* disable Automatic Crossover */
+ 
+ 		ctrl &= ~PHY_M_PC_MDIX_MSK;
+-		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
++	}
+ 
+-		if (hw->chip_id == CHIP_ID_YUKON_XL) {
+-			/* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */
+-			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
+-			ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+-			ctrl &= ~PHY_M_MAC_MD_MSK;
+-			ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
+-			gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
++	gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
++
++	/* special setup for PHY 88E1112 Fiber */
++	if (hw->chip_id == CHIP_ID_YUKON_XL && !sky2_is_copper(hw)) {
++		pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
++
++		/* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */
++		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
++		ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
++		ctrl &= ~PHY_M_MAC_MD_MSK;
++		ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
++		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+ 
++		if (hw->pmd_type  == 'P') {
+ 			/* select page 1 to access Fiber registers */
+ 			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 1);
++
++			/* for SFP-module set SIGDET polarity to low */
++			ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
++			ctrl |= PHY_M_FIB_SIGD_POL;
++			gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+ 		}
++
++		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+ 	}
+ 
+ 	ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
+@@ -373,7 +385,7 @@ static void sky2_phy_init(struct sky2_hw
+ 	adv = PHY_AN_CSMA;
+ 
+ 	if (sky2->autoneg == AUTONEG_ENABLE) {
+-		if (hw->copper) {
++		if (sky2_is_copper(hw)) {
+ 			if (sky2->advertising & ADVERTISED_1000baseT_Full)
+ 				ct1000 |= PHY_M_1000C_AFD;
+ 			if (sky2->advertising & ADVERTISED_1000baseT_Half)
+@@ -386,8 +398,12 @@ static void sky2_phy_init(struct sky2_hw
+ 				adv |= PHY_M_AN_10_FD;
+ 			if (sky2->advertising & ADVERTISED_10baseT_Half)
+ 				adv |= PHY_M_AN_10_HD;
+-		} else		/* special defines for FIBER (88E1011S only) */
+-			adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
++		} else {	/* special defines for FIBER (88E1040S only) */
++			if (sky2->advertising & ADVERTISED_1000baseT_Full)
++				adv |= PHY_M_AN_1000X_AFD;
++			if (sky2->advertising & ADVERTISED_1000baseT_Half)
++				adv |= PHY_M_AN_1000X_AHD;
++		}
+ 
+ 		/* Set Flow-control capabilities */
+ 		if (sky2->tx_pause && sky2->rx_pause)
+@@ -949,14 +965,14 @@ #endif
+ /*
+  * It appears the hardware has a bug in the FIFO logic that
+  * cause it to hang if the FIFO gets overrun and the receive buffer
+- * is not aligned. ALso alloc_skb() won't align properly if slab
++ * is not aligned. Also dev_alloc_skb() won't align properly if slab
+  * debugging is enabled.
+  */
+ static inline struct sk_buff *sky2_alloc_skb(unsigned int size, gfp_t gfp_mask)
+ {
+ 	struct sk_buff *skb;
+ 
+-	skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask);
++	skb = __dev_alloc_skb(size + RX_SKB_ALIGN, gfp_mask);
+ 	if (likely(skb)) {
+ 		unsigned long p	= (unsigned long) skb->data;
+ 		skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
+@@ -1497,7 +1513,7 @@ static int sky2_down(struct net_device *
+ 
+ static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux)
+ {
+-	if (!hw->copper)
++	if (!sky2_is_copper(hw))
+ 		return SPEED_1000;
+ 
+ 	if (hw->chip_id == CHIP_ID_YUKON_FE)
+@@ -1855,7 +1871,7 @@ static struct sk_buff *sky2_receive(stru
+ 		goto oversize;
+ 
+ 	if (length < copybreak) {
+-		skb = alloc_skb(length + 2, GFP_ATOMIC);
++		skb = dev_alloc_skb(length + 2);
+ 		if (!skb)
+ 			goto resubmit;
+ 
+@@ -2016,6 +2032,9 @@ #endif
+ 		}
+ 	}
+ 
++	/* Fully processed status ring so clear irq */
++	sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
++
+ exit_loop:
+ 	return work_done;
+ }
+@@ -2218,9 +2237,6 @@ static int sky2_poll(struct net_device *
+ 	*budget -= work_done;
+ 	dev0->quota -= work_done;
+ 
+-	if (status & Y2_IS_STAT_BMU)
+-		sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
+-
+ 	if (sky2_more_work(hw))
+ 		return 1;
+ 
+@@ -2287,7 +2303,7 @@ static inline u32 sky2_clk2us(const stru
+ static int __devinit sky2_reset(struct sky2_hw *hw)
+ {
+ 	u16 status;
+-	u8 t8, pmd_type;
++	u8 t8;
+ 	int i;
+ 
+ 	sky2_write8(hw, B0_CTST, CS_RST_CLR);
+@@ -2333,9 +2349,7 @@ static int __devinit sky2_reset(struct s
+ 		sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL);
+ 
+ 
+-	pmd_type = sky2_read8(hw, B2_PMD_TYP);
+-	hw->copper = !(pmd_type == 'L' || pmd_type == 'S');
+-
++	hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
+ 	hw->ports = 1;
+ 	t8 = sky2_read8(hw, B2_Y2_HW_RES);
+ 	if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
+@@ -2432,21 +2446,22 @@ static int __devinit sky2_reset(struct s
+ 
+ static u32 sky2_supported_modes(const struct sky2_hw *hw)
+ {
+-	u32 modes;
+-	if (hw->copper) {
+-		modes = SUPPORTED_10baseT_Half
+-		    | SUPPORTED_10baseT_Full
+-		    | SUPPORTED_100baseT_Half
+-		    | SUPPORTED_100baseT_Full
+-		    | SUPPORTED_Autoneg | SUPPORTED_TP;
++	if (sky2_is_copper(hw)) {
++		u32 modes = SUPPORTED_10baseT_Half
++			| SUPPORTED_10baseT_Full
++			| SUPPORTED_100baseT_Half
++			| SUPPORTED_100baseT_Full
++			| SUPPORTED_Autoneg | SUPPORTED_TP;
+ 
+ 		if (hw->chip_id != CHIP_ID_YUKON_FE)
+ 			modes |= SUPPORTED_1000baseT_Half
+-			    | SUPPORTED_1000baseT_Full;
++				| SUPPORTED_1000baseT_Full;
++		return modes;
+ 	} else
+-		modes = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE
+-		    | SUPPORTED_Autoneg;
+-	return modes;
++		return  SUPPORTED_1000baseT_Half
++			| SUPPORTED_1000baseT_Full
++			| SUPPORTED_Autoneg
++			| SUPPORTED_FIBRE;
+ }
+ 
+ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+@@ -2457,7 +2472,7 @@ static int sky2_get_settings(struct net_
+ 	ecmd->transceiver = XCVR_INTERNAL;
+ 	ecmd->supported = sky2_supported_modes(hw);
+ 	ecmd->phy_address = PHY_ADDR_MARV;
+-	if (hw->copper) {
++	if (sky2_is_copper(hw)) {
+ 		ecmd->supported = SUPPORTED_10baseT_Half
+ 		    | SUPPORTED_10baseT_Full
+ 		    | SUPPORTED_100baseT_Half
+@@ -2466,12 +2481,14 @@ static int sky2_get_settings(struct net_
+ 		    | SUPPORTED_1000baseT_Full
+ 		    | SUPPORTED_Autoneg | SUPPORTED_TP;
+ 		ecmd->port = PORT_TP;
+-	} else
++		ecmd->speed = sky2->speed;
++	} else {
++		ecmd->speed = SPEED_1000;
+ 		ecmd->port = PORT_FIBRE;
++	}
+ 
+ 	ecmd->advertising = sky2->advertising;
+ 	ecmd->autoneg = sky2->autoneg;
+-	ecmd->speed = sky2->speed;
+ 	ecmd->duplex = sky2->duplex;
+ 	return 0;
+ }
+@@ -3184,6 +3201,8 @@ static int __devinit sky2_test_msi(struc
+ 	struct pci_dev *pdev = hw->pdev;
+ 	int err;
+ 
++	init_waitqueue_head (&hw->msi_wait);
++
+ 	sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
+ 
+ 	err = request_irq(pdev->irq, sky2_test_intr, SA_SHIRQ, DRV_NAME, hw);
+@@ -3193,10 +3212,8 @@ static int __devinit sky2_test_msi(struc
+ 		return err;
+ 	}
+ 
+-	init_waitqueue_head (&hw->msi_wait);
+-
+ 	sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
+-	wmb();
++	sky2_read8(hw, B0_CTST);
+ 
+ 	wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10);
+ 
+diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
+index 8a0bc55..9516c1f 100644
+--- a/drivers/net/sky2.h
++++ b/drivers/net/sky2.h
+@@ -1318,6 +1318,14 @@ enum {
+ };
+ 
+ /* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
++/*****  PHY_MARV_PHY_CTRL (page 1)		16 bit r/w	Fiber Specific Ctrl *****/
++enum {
++	PHY_M_FIB_FORCE_LNK	= 1<<10,/* Force Link Good */
++	PHY_M_FIB_SIGD_POL	= 1<<9,	/* SIGDET Polarity */
++	PHY_M_FIB_TX_DIS	= 1<<3,	/* Transmitter Disable */
++};
++
++/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
+ /*****  PHY_MARV_PHY_CTRL (page 2)		16 bit r/w	MAC Specific Ctrl *****/
+ enum {
+ 	PHY_M_MAC_MD_MSK	= 7<<7, /* Bit  9.. 7: Mode Select Mask */
+@@ -1566,7 +1574,7 @@ enum {
+ 
+ 	GMR_FS_ANY_ERR	= GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR |
+ 			  GMR_FS_FRAGMENT | GMR_FS_LONG_ERR |
+-		  	  GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
++		  	  GMR_FS_MII_ERR | GMR_FS_BAD_FC |
+ 			  GMR_FS_UN_SIZE | GMR_FS_JABBER,
+ };
+ 
+@@ -1879,7 +1887,7 @@ struct sky2_hw {
+ 	int		     pm_cap;
+ 	u8	     	     chip_id;
+ 	u8		     chip_rev;
+-	u8		     copper;
++	u8		     pmd_type;
+ 	u8		     ports;
+ 
+ 	struct sky2_status_le *st_le;
+@@ -1891,6 +1899,11 @@ struct sky2_hw {
+ 	wait_queue_head_t    msi_wait;
+ };
+ 
++static inline int sky2_is_copper(const struct sky2_hw *hw)
++{
++	return !(hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P');
++}
++
+ /* Register accessor for memory mapped device */
+ static inline u32 sky2_read32(const struct sky2_hw *hw, unsigned reg)
+ {
+diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
+index 862c226..38b605d 100644
+--- a/drivers/net/tg3.c
++++ b/drivers/net/tg3.c
+@@ -69,8 +69,8 @@ #include "tg3.h"
+ 
+ #define DRV_MODULE_NAME		"tg3"
+ #define PFX DRV_MODULE_NAME	": "
+-#define DRV_MODULE_VERSION	"3.59"
+-#define DRV_MODULE_RELDATE	"June 8, 2006"
++#define DRV_MODULE_VERSION	"3.59.1"
++#define DRV_MODULE_RELDATE	"August 25, 2006"
+ 
+ #define TG3_DEF_MAC_MODE	0
+ #define TG3_DEF_RX_MODE		0
+@@ -11381,11 +11381,15 @@ #if TG3_TSO_SUPPORT != 0
+ 		tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
+ 	}
+ 
+-	/* TSO is on by default on chips that support hardware TSO.
++	/* TSO is on by default on chips that support HW_TSO_2.
++	 * Some HW_TSO_1 capable chips have bugs that can lead to
++	 * tx timeouts in some cases when TSO is enabled.
+ 	 * Firmware TSO on older chips gives lower performance, so it
+ 	 * is off by default, but can be enabled using ethtool.
+ 	 */
+-	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
++	if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) ||
++	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 &&
++	     tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2))
+ 		dev->features |= NETIF_F_TSO;
+ 
+ #endif
+diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
+index ff0faab..cd68f46 100644
+--- a/drivers/net/tg3.h
++++ b/drivers/net/tg3.h
+@@ -125,6 +125,7 @@ #define  CHIPREV_ID_5705_A3		 0x3003
+ #define  CHIPREV_ID_5750_A0		 0x4000
+ #define  CHIPREV_ID_5750_A1		 0x4001
+ #define  CHIPREV_ID_5750_A3		 0x4003
++#define  CHIPREV_ID_5750_C2		 0x4202
+ #define  CHIPREV_ID_5752_A0_HW		 0x5000
+ #define  CHIPREV_ID_5752_A0		 0x6000
+ #define  CHIPREV_ID_5752_A1		 0x6001
+diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
+index f7b77ce..54fe4e4 100644
+--- a/drivers/net/wireless/spectrum_cs.c
++++ b/drivers/net/wireless/spectrum_cs.c
+@@ -245,7 +245,7 @@ spectrum_reset(struct pcmcia_device *lin
+ 	u_int save_cor;
+ 
+ 	/* Doing it if hardware is gone is guaranteed crash */
+-	if (pcmcia_dev_present(link))
++	if (!pcmcia_dev_present(link))
+ 		return -ENODEV;
+ 
+ 	/* Save original COR value */
+diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
+index 27909bc..5f44354 100644
+--- a/drivers/usb/host/uhci-q.c
++++ b/drivers/usb/host/uhci-q.c
+@@ -264,7 +264,7 @@ static void uhci_fixup_toggles(struct uh
+ 		 * need to change any toggles in this URB */
+ 		td = list_entry(urbp->td_list.next, struct uhci_td, list);
+ 		if (toggle > 1 || uhci_toggle(td_token(td)) == toggle) {
+-			td = list_entry(urbp->td_list.next, struct uhci_td,
++			td = list_entry(urbp->td_list.prev, struct uhci_td,
+ 					list);
+ 			toggle = uhci_toggle(td_token(td)) ^ 1;
+ 
+diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
+index 537893a..997a202 100644
+--- a/fs/binfmt_elf.c
++++ b/fs/binfmt_elf.c
+@@ -86,7 +86,7 @@ static struct linux_binfmt elf_format = 
+ 		.min_coredump	= ELF_EXEC_PAGESIZE
+ };
+ 
+-#define BAD_ADDR(x)	((unsigned long)(x) > TASK_SIZE)
++#define BAD_ADDR(x)	((unsigned long)(x) >= TASK_SIZE)
+ 
+ static int set_brk(unsigned long start, unsigned long end)
+ {
+@@ -389,7 +389,7 @@ static unsigned long load_elf_interp(str
+ 	     * <= p_memsize so it is only necessary to check p_memsz.
+ 	     */
+ 	    k = load_addr + eppnt->p_vaddr;
+-	    if (k > TASK_SIZE || eppnt->p_filesz > eppnt->p_memsz ||
++	    if (BAD_ADDR(k) || eppnt->p_filesz > eppnt->p_memsz ||
+ 		eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) {
+ 	        error = -ENOMEM;
+ 		goto out_close;
+@@ -876,7 +876,7 @@ static int load_elf_binary(struct linux_
+ 		 * allowed task size. Note that p_filesz must always be
+ 		 * <= p_memsz so it is only necessary to check p_memsz.
+ 		 */
+-		if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
++		if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
+ 		    elf_ppnt->p_memsz > TASK_SIZE ||
+ 		    TASK_SIZE - elf_ppnt->p_memsz < k) {
+ 			/* set_brk can never work.  Avoid overflows.  */
+@@ -930,10 +930,9 @@ static int load_elf_binary(struct linux_
+ 						    interpreter,
+ 						    &interp_load_addr);
+ 		if (BAD_ADDR(elf_entry)) {
+-			printk(KERN_ERR "Unable to load interpreter %.128s\n",
+-				elf_interpreter);
+ 			force_sig(SIGSEGV, current);
+-			retval = -ENOEXEC; /* Nobody gets to see this, but.. */
++			retval = IS_ERR((void *)elf_entry) ?
++					(int)elf_entry : -EINVAL;
+ 			goto out_free_dentry;
+ 		}
+ 		reloc_func_desc = interp_load_addr;
+@@ -944,8 +943,8 @@ static int load_elf_binary(struct linux_
+ 	} else {
+ 		elf_entry = loc->elf_ex.e_entry;
+ 		if (BAD_ADDR(elf_entry)) {
+-			send_sig(SIGSEGV, current, 0);
+-			retval = -ENOEXEC; /* Nobody gets to see this, but.. */
++			force_sig(SIGSEGV, current);
++			retval = -EINVAL;
+ 			goto out_free_dentry;
+ 		}
+ 	}
+diff --git a/fs/ext2/super.c b/fs/ext2/super.c
+index 7e30bae..e51d1a8 100644
+--- a/fs/ext2/super.c
++++ b/fs/ext2/super.c
+@@ -252,6 +252,46 @@ #ifdef CONFIG_QUOTA
+ #endif
+ };
+ 
++static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp)
++{
++	__u32 *objp = vobjp;
++	unsigned long ino = objp[0];
++	__u32 generation = objp[1];
++	struct inode *inode;
++	struct dentry *result;
++
++	if (ino != EXT2_ROOT_INO && ino < EXT2_FIRST_INO(sb))
++		return ERR_PTR(-ESTALE);
++	if (ino > le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count))
++		return ERR_PTR(-ESTALE);
++
++	/* iget isn't really right if the inode is currently unallocated!!
++	 * ext2_read_inode currently does appropriate checks, but
++	 * it might be "neater" to call ext2_get_inode first and check
++	 * if the inode is valid.....
++	 */
++	inode = iget(sb, ino);
++	if (inode == NULL)
++		return ERR_PTR(-ENOMEM);
++	if (is_bad_inode(inode)
++	    || (generation && inode->i_generation != generation)
++		) {
++		/* we didn't find the right inode.. */
++		iput(inode);
++		return ERR_PTR(-ESTALE);
++	}
++	/* now to find a dentry.
++	 * If possible, get a well-connected one
++	 */
++	result = d_alloc_anon(inode);
++	if (!result) {
++		iput(inode);
++		return ERR_PTR(-ENOMEM);
++	}
++	return result;
++}
++
++
+ /* Yes, most of these are left as NULL!!
+  * A NULL value implies the default, which works with ext2-like file
+  * systems, but can be improved upon.
+@@ -259,6 +299,7 @@ #endif
+  */
+ static struct export_operations ext2_export_ops = {
+ 	.get_parent = ext2_get_parent,
++	.get_dentry = ext2_get_dentry,
+ };
+ 
+ static unsigned long get_sb_block(void **data)
+diff --git a/fs/locks.c b/fs/locks.c
+index ab61a8b..529a0ed 100644
+--- a/fs/locks.c
++++ b/fs/locks.c
+@@ -1389,8 +1389,9 @@ static int __setlease(struct file *filp,
+ 	if (!leases_enable)
+ 		goto out;
+ 
+-	error = lease_alloc(filp, arg, &fl);
+-	if (error)
++	error = -ENOMEM;
++	fl = locks_alloc_lock();
++	if (fl == NULL)
+ 		goto out;
+ 
+ 	locks_copy_lock(fl, lease);
+@@ -1398,6 +1399,7 @@ static int __setlease(struct file *filp,
+ 	locks_insert_lock(before, fl);
+ 
+ 	*flp = fl;
++	error = 0;
+ out:
+ 	return error;
+ }
+diff --git a/include/asm-ia64/mman.h b/include/asm-ia64/mman.h
+index df1b20e..b242f95 100644
+--- a/include/asm-ia64/mman.h
++++ b/include/asm-ia64/mman.h
+@@ -9,10 +9,12 @@ #define _ASM_IA64_MMAN_H
+  */
+ 
+ #ifdef __KERNEL__
++#ifndef __ASSEMBLY__
+ #define arch_mmap_check	ia64_map_check_rgn
+ int ia64_map_check_rgn(unsigned long addr, unsigned long len,
+ 		unsigned long flags);
+ #endif
++#endif
+ 
+ #include <asm-generic/mman.h>
+ 
+diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h
+index 9bd2f9b..6f807e0 100644
+--- a/include/asm-ia64/sn/xp.h
++++ b/include/asm-ia64/sn/xp.h
+@@ -60,23 +60,37 @@ #define XP_NASID_MASK_WORDS	((XP_MAX_PHY
+  * the bte_copy() once in the hope that the failure was due to a temporary
+  * aberration (i.e., the link going down temporarily).
+  *
+- * See bte_copy for definition of the input parameters.
++ * 	src - physical address of the source of the transfer.
++ *	vdst - virtual address of the destination of the transfer.
++ *	len - number of bytes to transfer from source to destination.
++ *	mode - see bte_copy() for definition.
++ *	notification - see bte_copy() for definition.
+  *
+  * Note: xp_bte_copy() should never be called while holding a spinlock.
+  */
+ static inline bte_result_t
+-xp_bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
++xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification)
+ {
+ 	bte_result_t ret;
++	u64 pdst = ia64_tpa(vdst);
+ 
+ 
+-	ret = bte_copy(src, dest, len, mode, notification);
++	/*
++	 * Ensure that the physically mapped memory is contiguous.
++	 *
++	 * We do this by ensuring that the memory is from region 7 only.
++	 * If the need should arise to use memory from one of the other
++	 * regions, then modify the BUG_ON() statement to ensure that the
++	 * memory from that region is always physically contiguous.
++	 */
++	BUG_ON(REGION_NUMBER(vdst) != RGN_KERNEL);
+ 
++	ret = bte_copy(src, pdst, len, mode, notification);
+ 	if (ret != BTE_SUCCESS) {
+ 		if (!in_interrupt()) {
+ 			cond_resched();
+ 		}
+-		ret = bte_copy(src, dest, len, mode, notification);
++		ret = bte_copy(src, pdst, len, mode, notification);
+ 	}
+ 
+ 	return ret;
+diff --git a/include/asm-ia64/sn/xpc.h b/include/asm-ia64/sn/xpc.h
+index aa3b8ac..b454ad4 100644
+--- a/include/asm-ia64/sn/xpc.h
++++ b/include/asm-ia64/sn/xpc.h
+@@ -684,7 +684,9 @@ extern struct xpc_vars *xpc_vars;
+ extern struct xpc_rsvd_page *xpc_rsvd_page;
+ extern struct xpc_vars_part *xpc_vars_part;
+ extern struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
+-extern char xpc_remote_copy_buffer[];
++extern char *xpc_remote_copy_buffer;
++extern void *xpc_remote_copy_buffer_base;
++extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
+ extern struct xpc_rsvd_page *xpc_rsvd_page_init(void);
+ extern void xpc_allow_IPI_ops(void);
+ extern void xpc_restrict_IPI_ops(void);
+diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
+index a75b84b..178a97e 100644
+--- a/include/linux/netfilter_bridge.h
++++ b/include/linux/netfilter_bridge.h
+@@ -47,18 +47,26 @@ #define BRNF_DONT_TAKE_PARENT		0x04
+ #define BRNF_BRIDGED			0x08
+ #define BRNF_NF_BRIDGE_PREROUTING	0x10
+ 
+-
+ /* Only used in br_forward.c */
+-static inline
+-void nf_bridge_maybe_copy_header(struct sk_buff *skb)
++static inline int nf_bridge_maybe_copy_header(struct sk_buff *skb)
+ {
++	int err;
++
+ 	if (skb->nf_bridge) {
+ 		if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
++			err = skb_cow(skb, 18);
++			if (err)
++				return err;
+ 			memcpy(skb->data - 18, skb->nf_bridge->data, 18);
+ 			skb_push(skb, 4);
+-		} else
++		} else {
++			err = skb_cow(skb, 16);
++			if (err)
++				return err;
+ 			memcpy(skb->data - 16, skb->nf_bridge->data, 16);
++		}
+ 	}
++	return 0;
+ }
+ 
+ /* This is called by the IP fragmenting code and it ensures there is
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 2c31bb0..a1ce843 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -1009,6 +1009,21 @@ static inline int pskb_trim(struct sk_bu
+ }
+ 
+ /**
++ *	pskb_trim_unique - remove end from a paged unique (not cloned) buffer
++ *	@skb: buffer to alter
++ *	@len: new length
++ *
++ *	This is identical to pskb_trim except that the caller knows that
++ *	the skb is not cloned so we should never get an error due to out-
++ *	of-memory.
++ */
++static inline void pskb_trim_unique(struct sk_buff *skb, unsigned int len)
++{
++	int err = pskb_trim(skb, len);
++	BUG_ON(err);
++}
++
++/**
+  *	skb_orphan - orphan a buffer
+  *	@skb: buffer to orphan
+  *
+diff --git a/kernel/futex.c b/kernel/futex.c
+index 5699c51..225af28 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -593,6 +593,7 @@ static int unqueue_me(struct futex_q *q)
+ 	/* In the common case we don't take the spinlock, which is nice. */
+  retry:
+ 	lock_ptr = q->lock_ptr;
++	barrier();
+ 	if (lock_ptr != 0) {
+ 		spin_lock(lock_ptr);
+ 		/*
+diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
+index dcfb5d7..51cacd1 100644
+--- a/kernel/stop_machine.c
++++ b/kernel/stop_machine.c
+@@ -111,7 +111,6 @@ static int stop_machine(void)
+ 	/* If some failed, kill them all. */
+ 	if (ret < 0) {
+ 		stopmachine_set_state(STOPMACHINE_EXIT);
+-		up(&stopmachine_mutex);
+ 		return ret;
+ 	}
+ 
+diff --git a/lib/ts_bm.c b/lib/ts_bm.c
+index c4c1ac5..7917265 100644
+--- a/lib/ts_bm.c
++++ b/lib/ts_bm.c
+@@ -112,15 +112,14 @@ static int subpattern(u8 *pattern, int i
+ 	return ret;
+ }
+ 
+-static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern,
+-			       unsigned int len)
++static void compute_prefix_tbl(struct ts_bm *bm)
+ {
+ 	int i, j, g;
+ 
+ 	for (i = 0; i < ASIZE; i++)
+-		bm->bad_shift[i] = len;
+-	for (i = 0; i < len - 1; i++)
+-		bm->bad_shift[pattern[i]] = len - 1 - i;
++		bm->bad_shift[i] = bm->patlen;
++	for (i = 0; i < bm->patlen - 1; i++)
++		bm->bad_shift[bm->pattern[i]] = bm->patlen - 1 - i;
+ 
+ 	/* Compute the good shift array, used to match reocurrences 
+ 	 * of a subpattern */
+@@ -151,8 +150,8 @@ static struct ts_config *bm_init(const v
+ 	bm = ts_config_priv(conf);
+ 	bm->patlen = len;
+ 	bm->pattern = (u8 *) bm->good_shift + prefix_tbl_len;
+-	compute_prefix_tbl(bm, pattern, len);
+ 	memcpy(bm->pattern, pattern, len);
++	compute_prefix_tbl(bm);
+ 
+ 	return conf;
+ }
+diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
+index 56f3aa4..ddb7e1c 100644
+--- a/net/bridge/br_forward.c
++++ b/net/bridge/br_forward.c
+@@ -43,11 +43,15 @@ int br_dev_queue_push_xmit(struct sk_buf
+ 	else {
+ #ifdef CONFIG_BRIDGE_NETFILTER
+ 		/* ip_refrag calls ip_fragment, doesn't copy the MAC header. */
+-		nf_bridge_maybe_copy_header(skb);
++		if (nf_bridge_maybe_copy_header(skb))
++			kfree_skb(skb);
++		else
+ #endif
+-		skb_push(skb, ETH_HLEN);
++		{
++			skb_push(skb, ETH_HLEN);
+ 
+-		dev_queue_xmit(skb);
++			dev_queue_xmit(skb);
++		}
+ 	}
+ 
+ 	return 0;
+diff --git a/net/core/pktgen.c b/net/core/pktgen.c
+index c23e9c0..b916b7f 100644
+--- a/net/core/pktgen.c
++++ b/net/core/pktgen.c
+@@ -2149,6 +2149,8 @@ static struct sk_buff *fill_packet_ipv4(
+ 	skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32);
+ 	skb->dev = odev;
+ 	skb->pkt_type = PACKET_HOST;
++	skb->nh.iph = iph;
++	skb->h.uh = udph;
+ 
+ 	if (pkt_dev->nfrags <= 0)
+ 		pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
+@@ -2460,6 +2462,8 @@ static struct sk_buff *fill_packet_ipv6(
+ 	skb->protocol = protocol;
+ 	skb->dev = odev;
+ 	skb->pkt_type = PACKET_HOST;
++	skb->nh.ipv6h = iph;
++	skb->h.uh = udph;
+ 
+ 	if (pkt_dev->nfrags <= 0)
+ 		pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index cff9c3a..d987a27 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -946,7 +946,7 @@ alloc_new_skb:
+ 				skb_prev->csum = csum_sub(skb_prev->csum,
+ 							  skb->csum);
+ 				data += fraggap;
+-				skb_trim(skb_prev, maxfraglen);
++				pskb_trim_unique(skb_prev, maxfraglen);
+ 			}
+ 
+ 			copy = datalen - transhdrlen - fraggap;
+@@ -1139,7 +1139,7 @@ ssize_t	ip_append_page(struct sock *sk, 
+ 					data, fraggap, 0);
+ 				skb_prev->csum = csum_sub(skb_prev->csum,
+ 							  skb->csum);
+-				skb_trim(skb_prev, maxfraglen);
++				pskb_trim_unique(skb_prev, maxfraglen);
+ 			}
+ 
+ 			/*
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index f33c9dd..e0657b9 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -197,6 +197,7 @@ void tcp_select_initial_window(int __spa
+ 		 * See RFC1323 for an explanation of the limit to 14 
+ 		 */
+ 		space = max_t(u32, sysctl_tcp_rmem[2], sysctl_rmem_max);
++		space = min_t(u32, space, *window_clamp);
+ 		while (space > 65535 && (*rcv_wscale) < 14) {
+ 			space >>= 1;
+ 			(*rcv_wscale)++;
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index a18d425..9ca783d 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -635,14 +635,17 @@ ipv6_renew_options(struct sock *sk, stru
+ 	struct ipv6_txoptions *opt2;
+ 	int err;
+ 
+-	if (newtype != IPV6_HOPOPTS && opt->hopopt)
+-		tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
+-	if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
+-		tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
+-	if (newtype != IPV6_RTHDR && opt->srcrt)
+-		tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
+-	if (newtype != IPV6_DSTOPTS && opt->dst1opt)
+-		tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
++	if (opt) {
++		if (newtype != IPV6_HOPOPTS && opt->hopopt)
++			tot_len += CMSG_ALIGN(ipv6_optlen(opt->hopopt));
++		if (newtype != IPV6_RTHDRDSTOPTS && opt->dst0opt)
++			tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst0opt));
++		if (newtype != IPV6_RTHDR && opt->srcrt)
++			tot_len += CMSG_ALIGN(ipv6_optlen(opt->srcrt));
++		if (newtype != IPV6_DSTOPTS && opt->dst1opt)
++			tot_len += CMSG_ALIGN(ipv6_optlen(opt->dst1opt));
++	}
++
+ 	if (newopt && newoptlen)
+ 		tot_len += CMSG_ALIGN(newoptlen);
+ 
+@@ -659,25 +662,25 @@ ipv6_renew_options(struct sock *sk, stru
+ 	opt2->tot_len = tot_len;
+ 	p = (char *)(opt2 + 1);
+ 
+-	err = ipv6_renew_option(opt->hopopt, newopt, newoptlen,
++	err = ipv6_renew_option(opt ? opt->hopopt : NULL, newopt, newoptlen,
+ 				newtype != IPV6_HOPOPTS,
+ 				&opt2->hopopt, &p);
+ 	if (err)
+ 		goto out;
+ 
+-	err = ipv6_renew_option(opt->dst0opt, newopt, newoptlen,
++	err = ipv6_renew_option(opt ? opt->dst0opt : NULL, newopt, newoptlen,
+ 				newtype != IPV6_RTHDRDSTOPTS,
+ 				&opt2->dst0opt, &p);
+ 	if (err)
+ 		goto out;
+ 
+-	err = ipv6_renew_option(opt->srcrt, newopt, newoptlen,
++	err = ipv6_renew_option(opt ? opt->srcrt : NULL, newopt, newoptlen,
+ 				newtype != IPV6_RTHDR,
+-				(struct ipv6_opt_hdr **)opt2->srcrt, &p);
++				(struct ipv6_opt_hdr **)&opt2->srcrt, &p);
+ 	if (err)
+ 		goto out;
+ 
+-	err = ipv6_renew_option(opt->dst1opt, newopt, newoptlen,
++	err = ipv6_renew_option(opt ? opt->dst1opt : NULL, newopt, newoptlen,
+ 				newtype != IPV6_DSTOPTS,
+ 				&opt2->dst1opt, &p);
+ 	if (err)
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index e460489..56eddb3 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1047,7 +1047,7 @@ alloc_new_skb:
+ 				skb_prev->csum = csum_sub(skb_prev->csum,
+ 							  skb->csum);
+ 				data += fraggap;
+-				skb_trim(skb_prev, maxfraglen);
++				pskb_trim_unique(skb_prev, maxfraglen);
+ 			}
+ 			copy = datalen - transhdrlen - fraggap;
+ 			if (copy < 0) {
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 600eb59..5b1c837 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -1246,9 +1246,13 @@ SCTP_STATIC void sctp_close(struct sock 
+ 			}
+ 		}
+ 
+-		if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime)
+-			sctp_primitive_ABORT(asoc, NULL);
+-		else
++		if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
++			struct sctp_chunk *chunk;
++
++			chunk = sctp_make_abort_user(asoc, NULL, 0);
++			if (chunk)
++				sctp_primitive_ABORT(asoc, chunk);
++		} else
+ 			sctp_primitive_SHUTDOWN(asoc, NULL);
+ 	}
+ 

Added: dists/sid/linux-2.6/debian/patches/2.6.17.13
==============================================================================
--- (empty file)
+++ dists/sid/linux-2.6/debian/patches/2.6.17.13	Tue Sep 12 11:56:47 2006
@@ -0,0 +1,106 @@
+diff --git a/include/linux/idr.h b/include/linux/idr.h
+index d37c8d8..f559a71 100644
+--- a/include/linux/idr.h
++++ b/include/linux/idr.h
+@@ -78,6 +78,7 @@ void *idr_find(struct idr *idp, int id);
+ int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
+ int idr_get_new(struct idr *idp, void *ptr, int *id);
+ int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
++void *idr_replace(struct idr *idp, void *ptr, int id);
+ void idr_remove(struct idr *idp, int id);
+ void idr_destroy(struct idr *idp);
+ void idr_init(struct idr *idp);
+diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
+index 590dc6d..10d6759 100644
+--- a/include/linux/pci_ids.h
++++ b/include/linux/pci_ids.h
+@@ -1235,6 +1235,7 @@ #define PCI_DEVICE_ID_VIA_PT880ULTRA	0x0
+ #define PCI_DEVICE_ID_VIA_PX8X0_0	0x0259
+ #define PCI_DEVICE_ID_VIA_3269_0	0x0269
+ #define PCI_DEVICE_ID_VIA_K8T800PRO_0	0x0282
++#define PCI_DEVICE_ID_VIA_3296_0	0x0296
+ #define PCI_DEVICE_ID_VIA_8363_0	0x0305
+ #define PCI_DEVICE_ID_VIA_P4M800CE	0x0314
+ #define PCI_DEVICE_ID_VIA_8371_0	0x0391
+@@ -1242,6 +1243,7 @@ #define PCI_DEVICE_ID_VIA_8501_0	0x0501
+ #define PCI_DEVICE_ID_VIA_82C561	0x0561
+ #define PCI_DEVICE_ID_VIA_82C586_1	0x0571
+ #define PCI_DEVICE_ID_VIA_82C576	0x0576
++#define PCI_DEVICE_ID_VIA_SATA_EIDE	0x0581
+ #define PCI_DEVICE_ID_VIA_82C586_0	0x0586
+ #define PCI_DEVICE_ID_VIA_82C596	0x0596
+ #define PCI_DEVICE_ID_VIA_82C597_0	0x0597
+@@ -1282,10 +1284,11 @@ #define PCI_DEVICE_ID_VIA_8378_0	0x3205
+ #define PCI_DEVICE_ID_VIA_8783_0	0x3208
+ #define PCI_DEVICE_ID_VIA_8237		0x3227
+ #define PCI_DEVICE_ID_VIA_8251		0x3287
+-#define PCI_DEVICE_ID_VIA_3296_0	0x0296
++#define PCI_DEVICE_ID_VIA_8237A		0x3337
+ #define PCI_DEVICE_ID_VIA_8231		0x8231
+ #define PCI_DEVICE_ID_VIA_8231_4	0x8235
+ #define PCI_DEVICE_ID_VIA_8365_1	0x8305
++#define PCI_DEVICE_ID_VIA_CX700		0x8324
+ #define PCI_DEVICE_ID_VIA_8371_1	0x8391
+ #define PCI_DEVICE_ID_VIA_82C598_1	0x8598
+ #define PCI_DEVICE_ID_VIA_838X_1	0xB188
+diff --git a/lib/idr.c b/lib/idr.c
+index de19030..4d09681 100644
+--- a/lib/idr.c
++++ b/lib/idr.c
+@@ -29,6 +29,7 @@ #include <linux/slab.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #endif
++#include <linux/err.h>
+ #include <linux/string.h>
+ #include <linux/idr.h>
+ 
+@@ -398,6 +399,48 @@ void *idr_find(struct idr *idp, int id)
+ }
+ EXPORT_SYMBOL(idr_find);
+ 
++/**
++ * idr_replace - replace pointer for given id
++ * @idp: idr handle
++ * @ptr: pointer you want associated with the id
++ * @id: lookup key
++ *
++ * Replace the pointer registered with an id and return the old value.
++ * A -ENOENT return indicates that @id was not found.
++ * A -EINVAL return indicates that @id was not within valid constraints.
++ *
++ * The caller must serialize vs idr_find(), idr_get_new(), and idr_remove().
++ */
++void *idr_replace(struct idr *idp, void *ptr, int id)
++{
++	int n;
++	struct idr_layer *p, *old_p;
++
++	n = idp->layers * IDR_BITS;
++	p = idp->top;
++
++	id &= MAX_ID_MASK;
++
++	if (id >= (1 << n))
++		return ERR_PTR(-EINVAL);
++
++	n -= IDR_BITS;
++	while ((n > 0) && p) {
++		p = p->ary[(id >> n) & IDR_MASK];
++		n -= IDR_BITS;
++	}
++
++	n = id & IDR_MASK;
++	if (unlikely(p == NULL || !test_bit(n, &p->bitmap)))
++		return ERR_PTR(-ENOENT);
++
++	old_p = p->ary[n];
++	p->ary[n] = ptr;
++
++	return old_p;
++}
++EXPORT_SYMBOL(idr_replace);
++
+ static void idr_cache_ctor(void * idr_layer, kmem_cache_t *idr_layer_cache,
+ 		unsigned long flags)
+ {

Modified: dists/sid/linux-2.6/debian/patches/series/7-extra
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/7-extra	(original)
+++ dists/sid/linux-2.6/debian/patches/series/7-extra	Tue Sep 12 11:56:47 2006
@@ -3,4 +3,3 @@
 + xen-tls.patch *_xen *_xen-vserver
 + mips-tulip-2700.patch mipsel
 + vserver-version.patch *_vserver *_xen-vserver
-+ s390-kernel-futex-barrier.patch s390

Modified: dists/sid/linux-2.6/debian/patches/series/9
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/9	(original)
+++ dists/sid/linux-2.6/debian/patches/series/9	Tue Sep 12 11:56:47 2006
@@ -1,2 +1,5 @@
-+ drivers-ide-pci-via82cxxx-vt8237a-id.patch
-+ drivers-ide-pci-via82cxxx-vt8237a-id-2.patch
+#+ drivers-ide-pci-via82cxxx-vt8237a-id.patch
+#+ drivers-ide-pci-via82cxxx-vt8237a-id-2.patch
+- ia64-mman.h-fix.patch
++ 2.6.17.12
++ 2.6.17.13



More information about the Kernel-svn-changes mailing list