[kernel] r8353 - in dists/trunk/linux-2.6/debian: . patches/bugfix patches/series

maximilian attems maks-guest at alioth.debian.org
Tue Mar 13 23:59:20 CET 2007


Author: maks-guest
Date: Tue Mar 13 22:59:19 2007
New Revision: 8353

Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/2.6.20.3
Modified:
   dists/trunk/linux-2.6/debian/changelog
   dists/trunk/linux-2.6/debian/patches/series/1~experimental.1
Log:
add stable 2.6.20.3
might kill your serial console prompt on sparc


Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog	(original)
+++ dists/trunk/linux-2.6/debian/changelog	Tue Mar 13 22:59:19 2007
@@ -134,6 +134,27 @@
 
   [ maximilian attems ]
   * i386: Enable kvm.
+  * Add stable release 2.6.20.3:
+    - Fix sparc64 device register probing
+    - Fix bug 7994 sleeping function called from invalid context
+    - Fix timewait jiffies
+    - Fix UDP header pointer after pskb_trim_rcsum()
+    - Fix compat_getsockopt
+    - bcm43xx: Fix problem with >1 GB RAM
+    - nfnetlink_log: fix NULL pointer dereference
+    - nfnetlink_log: fix possible NULL pointer dereference
+    - conntrack: fix {nf, ip}_ct_iterate_cleanup endless loops
+    - nf_conntrack/nf_nat: fix incorrect config ifdefs
+    - tcp conntrack: accept SYN|URG as valid
+    - nfnetlink_log: fix reference leak
+    - nfnetlink_log: fix use after free
+    - nf_conntrack: fix incorrect classification of IPv6 fragments as
+      ESTABLISHED
+    - nfnetlink_log: zero-terminate prefix
+    - nfnetlink_log: fix crash on bridged packet
+    - Fix callback bug in connector
+    - fix for bugzilla #7544 (keyspan USB-to-serial converter)
+    - ip6_route_me_harder should take into account mark
 
   [ Gordon Farquharson ]
   * Disable broken config options on ARM.
@@ -141,7 +162,7 @@
   [ Frederik Schüler ]
   * Disable NAPI on forcedeth, it is broken.
 
- -- Frederik Schüler <fs at debian.org>  Fri, 23 Feb 2007 13:43:07 +0100
+ -- maximilian attems <max at sternwelten.at>  Tue, 13 Mar 2007 23:55:34 +0100
 
 linux-2.6 (2.6.18.dfsg.1-10) unstable; urgency=low
 

Added: dists/trunk/linux-2.6/debian/patches/bugfix/2.6.20.3
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/2.6.20.3	Tue Mar 13 22:59:19 2007
@@ -0,0 +1,837 @@
+diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c
+index dab6169..798b140 100644
+--- a/arch/sparc/kernel/of_device.c
++++ b/arch/sparc/kernel/of_device.c
+@@ -495,7 +495,7 @@ static void __init build_device_resources(struct of_device *op,
+ 		u32 *reg = (preg + (index * ((na + ns) * 4)));
+ 		struct device_node *dp = op->node;
+ 		struct device_node *pp = p_op->node;
+-		struct of_bus *pbus;
++		struct of_bus *pbus, *dbus;
+ 		u64 size, result = OF_BAD_ADDR;
+ 		unsigned long flags;
+ 		int dna, dns;
+@@ -516,6 +516,7 @@ static void __init build_device_resources(struct of_device *op,
+ 
+ 		dna = na;
+ 		dns = ns;
++		dbus = bus;
+ 
+ 		while (1) {
+ 			dp = pp;
+@@ -528,13 +529,13 @@ static void __init build_device_resources(struct of_device *op,
+ 			pbus = of_match_bus(pp);
+ 			pbus->count_cells(dp, &pna, &pns);
+ 
+-			if (build_one_resource(dp, bus, pbus, addr,
++			if (build_one_resource(dp, dbus, pbus, addr,
+ 					       dna, dns, pna))
+ 				break;
+ 
+ 			dna = pna;
+ 			dns = pns;
+-			bus = pbus;
++			dbus = pbus;
+ 		}
+ 
+ 	build_res:
+diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
+index ad74e5e..1f45985 100644
+--- a/arch/sparc64/kernel/of_device.c
++++ b/arch/sparc64/kernel/of_device.c
+@@ -581,7 +581,7 @@ static void __init build_device_resources(struct of_device *op,
+ 		u32 *reg = (preg + (index * ((na + ns) * 4)));
+ 		struct device_node *dp = op->node;
+ 		struct device_node *pp = p_op->node;
+-		struct of_bus *pbus;
++		struct of_bus *pbus, *dbus;
+ 		u64 size, result = OF_BAD_ADDR;
+ 		unsigned long flags;
+ 		int dna, dns;
+@@ -599,6 +599,7 @@ static void __init build_device_resources(struct of_device *op,
+ 
+ 		dna = na;
+ 		dns = ns;
++		dbus = bus;
+ 
+ 		while (1) {
+ 			dp = pp;
+@@ -611,13 +612,13 @@ static void __init build_device_resources(struct of_device *op,
+ 			pbus = of_match_bus(pp);
+ 			pbus->count_cells(dp, &pna, &pns);
+ 
+-			if (build_one_resource(dp, bus, pbus, addr,
++			if (build_one_resource(dp, dbus, pbus, addr,
+ 					       dna, dns, pna))
+ 				break;
+ 
+ 			dna = pna;
+ 			dns = pns;
+-			bus = pbus;
++			dbus = pbus;
+ 		}
+ 
+ 	build_res:
+diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
+index a44db75..a905f78 100644
+--- a/drivers/connector/connector.c
++++ b/drivers/connector/connector.c
+@@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(cn_netlink_send);
+  */
+ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data)
+ {
+-	struct cn_callback_entry *__cbq;
++	struct cn_callback_entry *__cbq, *__new_cbq;
+ 	struct cn_dev *dev = &cdev;
+ 	int err = -ENODEV;
+ 
+@@ -148,27 +148,27 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
+ 			} else {
+ 				struct cn_callback_data *d;
+ 				
+-				__cbq = kzalloc(sizeof(*__cbq), GFP_ATOMIC);
+-				if (__cbq) {
+-					d = &__cbq->data;
++				err = -ENOMEM;
++				__new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
++				if (__new_cbq) {
++					d = &__new_cbq->data;
+ 					d->callback_priv = msg;
+ 					d->callback = __cbq->data.callback;
+ 					d->ddata = data;
+ 					d->destruct_data = destruct_data;
+-					d->free = __cbq;
++					d->free = __new_cbq;
+ 
+-					INIT_WORK(&__cbq->work,
++					INIT_WORK(&__new_cbq->work,
+ 							&cn_queue_wrapper);
+-					
++
+ 					if (queue_work(dev->cbdev->cn_queue,
+-						    &__cbq->work))
++						    &__new_cbq->work))
+ 						err = 0;
+ 					else {
+-						kfree(__cbq);
++						kfree(__new_cbq);
+ 						err = -EINVAL;
+ 					}
+-				} else
+-					err = -ENOMEM;
++				}
+ 			}
+ 			break;
+ 		}
+diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
+index 02ad9b1..38ea6b9 100644
+--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
++++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
+@@ -766,6 +766,7 @@ struct bcm43xx_private {
+ 	 * This is currently always BCM43xx_BUSTYPE_PCI
+ 	 */
+ 	u8 bustype;
++	u64 dma_mask;
+ 
+ 	u16 board_vendor;
+ 	u16 board_type;
+diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
+index 978ed09..6e0dc76 100644
+--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
++++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
+@@ -145,16 +145,14 @@ dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,
+ 			  int tx)
+ {
+ 	dma_addr_t dmaaddr;
++	int direction = PCI_DMA_FROMDEVICE;
+ 
+-	if (tx) {
+-		dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
+-					 buf, len,
+-					 DMA_TO_DEVICE);
+-	} else {
+-		dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
++	if (tx)
++		direction = PCI_DMA_TODEVICE;
++
++	dmaaddr = pci_map_single(ring->bcm->pci_dev,
+ 					 buf, len,
+-					 DMA_FROM_DEVICE);
+-	}
++					 direction);
+ 
+ 	return dmaaddr;
+ }
+@@ -166,13 +164,13 @@ void unmap_descbuffer(struct bcm43xx_dmaring *ring,
+ 		      int tx)
+ {
+ 	if (tx) {
+-		dma_unmap_single(&ring->bcm->pci_dev->dev,
++		pci_unmap_single(ring->bcm->pci_dev,
+ 				 addr, len,
+-				 DMA_TO_DEVICE);
++				 PCI_DMA_TODEVICE);
+ 	} else {
+-		dma_unmap_single(&ring->bcm->pci_dev->dev,
++		pci_unmap_single(ring->bcm->pci_dev,
+ 				 addr, len,
+-				 DMA_FROM_DEVICE);
++				 PCI_DMA_FROMDEVICE);
+ 	}
+ }
+ 
+@@ -183,8 +181,8 @@ void sync_descbuffer_for_cpu(struct bcm43xx_dmaring *ring,
+ {
+ 	assert(!ring->tx);
+ 
+-	dma_sync_single_for_cpu(&ring->bcm->pci_dev->dev,
+-				addr, len, DMA_FROM_DEVICE);
++	pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,
++				    addr, len, PCI_DMA_FROMDEVICE);
+ }
+ 
+ static inline
+@@ -194,8 +192,8 @@ void sync_descbuffer_for_device(struct bcm43xx_dmaring *ring,
+ {
+ 	assert(!ring->tx);
+ 
+-	dma_sync_single_for_device(&ring->bcm->pci_dev->dev,
+-				   addr, len, DMA_FROM_DEVICE);
++	pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,
++				    addr, len, PCI_DMA_TODEVICE);
+ }
+ 
+ /* Unmap and free a descriptor buffer. */
+@@ -214,17 +212,53 @@ void free_descriptor_buffer(struct bcm43xx_dmaring *ring,
+ 
+ static int alloc_ringmemory(struct bcm43xx_dmaring *ring)
+ {
+-	struct device *dev = &(ring->bcm->pci_dev->dev);
+-
+-	ring->descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
+-					    &(ring->dmabase), GFP_KERNEL);
++	ring->descbase = pci_alloc_consistent(ring->bcm->pci_dev, BCM43xx_DMA_RINGMEMSIZE,
++					    &(ring->dmabase));
+ 	if (!ring->descbase) {
+-		printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
+-		return -ENOMEM;
++		/* Allocation may have failed due to pci_alloc_consistent
++		   insisting on use of GFP_DMA, which is more restrictive
++		   than necessary...  */
++		struct dma_desc *rx_ring;
++		dma_addr_t rx_ring_dma;
++
++		rx_ring = kzalloc(BCM43xx_DMA_RINGMEMSIZE, GFP_KERNEL);
++		if (!rx_ring)
++			goto out_err;
++
++		rx_ring_dma = pci_map_single(ring->bcm->pci_dev, rx_ring,
++					     BCM43xx_DMA_RINGMEMSIZE,
++					     PCI_DMA_BIDIRECTIONAL);
++
++		if (pci_dma_mapping_error(rx_ring_dma) ||
++		    rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > ring->bcm->dma_mask) {
++			/* Sigh... */
++			if (!pci_dma_mapping_error(rx_ring_dma))
++				pci_unmap_single(ring->bcm->pci_dev,
++						 rx_ring_dma, BCM43xx_DMA_RINGMEMSIZE,
++						 PCI_DMA_BIDIRECTIONAL);
++			rx_ring_dma = pci_map_single(ring->bcm->pci_dev,
++						 rx_ring, BCM43xx_DMA_RINGMEMSIZE,
++						 PCI_DMA_BIDIRECTIONAL);
++			if (pci_dma_mapping_error(rx_ring_dma) ||
++			    rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > ring->bcm->dma_mask) {
++				assert(0);
++				if (!pci_dma_mapping_error(rx_ring_dma))
++					pci_unmap_single(ring->bcm->pci_dev,
++							 rx_ring_dma, BCM43xx_DMA_RINGMEMSIZE,
++							 PCI_DMA_BIDIRECTIONAL);
++				goto out_err;
++			}
++                }
++
++                ring->descbase = rx_ring;
++                ring->dmabase = rx_ring_dma;
+ 	}
+ 	memset(ring->descbase, 0, BCM43xx_DMA_RINGMEMSIZE);
+ 
+ 	return 0;
++out_err:
++	printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
++	return -ENOMEM;
+ }
+ 
+ static void free_ringmemory(struct bcm43xx_dmaring *ring)
+@@ -407,6 +441,29 @@ static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
+ 	if (unlikely(!skb))
+ 		return -ENOMEM;
+ 	dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
++	/* This hardware bug work-around adapted from the b44 driver.
++	   The chip may be unable to do PCI DMA to/from anything above 1GB */
++	if (pci_dma_mapping_error(dmaaddr) ||
++	    dmaaddr + ring->rx_buffersize > ring->bcm->dma_mask) {
++		/* This one has 30-bit addressing... */
++		if (!pci_dma_mapping_error(dmaaddr))
++			pci_unmap_single(ring->bcm->pci_dev,
++					 dmaaddr, ring->rx_buffersize,
++					 PCI_DMA_FROMDEVICE);
++		dev_kfree_skb_any(skb);
++		skb = __dev_alloc_skb(ring->rx_buffersize,GFP_DMA);
++		if (skb == NULL)
++			return -ENOMEM;
++		dmaaddr = pci_map_single(ring->bcm->pci_dev,
++					 skb->data, ring->rx_buffersize,
++					 PCI_DMA_FROMDEVICE);
++		if (pci_dma_mapping_error(dmaaddr) ||
++		    dmaaddr + ring->rx_buffersize > ring->bcm->dma_mask) {
++			assert(0);
++			dev_kfree_skb_any(skb);
++			return -ENOMEM;
++		}
++	}
+ 	meta->skb = skb;
+ 	meta->dmaaddr = dmaaddr;
+ 	skb->dev = ring->bcm->net_dev;
+@@ -636,8 +693,10 @@ struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm,
+ 	err = dmacontroller_setup(ring);
+ 	if (err)
+ 		goto err_free_ringmemory;
++	return ring;
+ 
+ out:
++	printk(KERN_ERR PFX "Error in bcm43xx_setup_dmaring\n");
+ 	return ring;
+ 
+ err_free_ringmemory:
+@@ -705,30 +764,16 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
+ 	struct bcm43xx_dmaring *ring;
+ 	int err = -ENOMEM;
+ 	int dma64 = 0;
+-	u64 mask = bcm43xx_get_supported_dma_mask(bcm);
+-	int nobits;
+ 
+-	if (mask == DMA_64BIT_MASK) {
++	bcm->dma_mask = bcm43xx_get_supported_dma_mask(bcm);
++	if (bcm->dma_mask == DMA_64BIT_MASK)
+ 		dma64 = 1;
+-		nobits = 64;
+-	} else if (mask == DMA_32BIT_MASK)
+-		nobits = 32;
+-	else
+-		nobits = 30;
+-	err = pci_set_dma_mask(bcm->pci_dev, mask);
+-	err |= pci_set_consistent_dma_mask(bcm->pci_dev, mask);
+-	if (err) {
+-#ifdef CONFIG_BCM43XX_PIO
+-		printk(KERN_WARNING PFX "DMA not supported on this device."
+-					" Falling back to PIO.\n");
+-		bcm->__using_pio = 1;
+-		return -ENOSYS;
+-#else
+-		printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
+-				    "Please recompile the driver with PIO support.\n");
+-		return -ENODEV;
+-#endif /* CONFIG_BCM43XX_PIO */
+-	}
++	err = pci_set_dma_mask(bcm->pci_dev, bcm->dma_mask);
++	if (err)
++		goto no_dma;
++	err = pci_set_consistent_dma_mask(bcm->pci_dev, bcm->dma_mask);
++	if (err)
++		goto no_dma;
+ 
+ 	/* setup TX DMA channels. */
+ 	ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
+@@ -774,7 +819,9 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
+ 		dma->rx_ring3 = ring;
+ 	}
+ 
+-	dprintk(KERN_INFO PFX "%d-bit DMA initialized\n", nobits);
++	dprintk(KERN_INFO PFX "%d-bit DMA initialized\n",
++		(bcm->dma_mask == DMA_64BIT_MASK) ? 64 :
++		(bcm->dma_mask == DMA_32BIT_MASK) ? 32 : 30);
+ 	err = 0;
+ out:
+ 	return err;
+@@ -800,7 +847,17 @@ err_destroy_tx1:
+ err_destroy_tx0:
+ 	bcm43xx_destroy_dmaring(dma->tx_ring0);
+ 	dma->tx_ring0 = NULL;
+-	goto out;
++no_dma:
++#ifdef CONFIG_BCM43XX_PIO
++	printk(KERN_WARNING PFX "DMA not supported on this device."
++				" Falling back to PIO.\n");
++	bcm->__using_pio = 1;
++	return -ENOSYS;
++#else
++	printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
++			    "Please recompile the driver with PIO support.\n");
++	return -ENODEV;
++#endif /* CONFIG_BCM43XX_PIO */
+ }
+ 
+ /* Generate a cookie for the TX header. */
+@@ -905,6 +962,7 @@ static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
+ 	struct bcm43xx_dmadesc_generic *desc;
+ 	struct bcm43xx_dmadesc_meta *meta;
+ 	dma_addr_t dmaaddr;
++	struct sk_buff *bounce_skb;
+ 
+ 	assert(skb_shinfo(skb)->nr_frags == 0);
+ 
+@@ -924,9 +982,28 @@ static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
+ 			       skb->len - sizeof(struct bcm43xx_txhdr),
+ 			       (cur_frag == 0),
+ 			       generate_cookie(ring, slot));
++	dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
++	if (dma_mapping_error(dmaaddr) || dmaaddr + skb->len > ring->bcm->dma_mask) {
++		/* chip cannot handle DMA to/from > 1GB, use bounce buffer (copied from b44 driver) */
++		if (!dma_mapping_error(dmaaddr))
++			unmap_descbuffer(ring, dmaaddr, skb->len, 1);
++		bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC|GFP_DMA);
++		if (!bounce_skb)
++			return;
++		dmaaddr = map_descbuffer(ring, bounce_skb->data, bounce_skb->len, 1);
++		if (dma_mapping_error(dmaaddr) || dmaaddr + skb->len > ring->bcm->dma_mask) {
++			if (!dma_mapping_error(dmaaddr))
++				unmap_descbuffer(ring, dmaaddr, skb->len, 1);
++			dev_kfree_skb_any(bounce_skb);
++			assert(0);
++			return;
++		}
++		memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len);
++		dev_kfree_skb_any(skb);
++		skb = bounce_skb;
++	}
+ 
+ 	meta->skb = skb;
+-	dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
+ 	meta->dmaaddr = dmaaddr;
+ 
+ 	fill_descriptor(ring, desc, dmaaddr,
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index 30ee3d7..614c2c9 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -954,7 +954,9 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target,
+ 	int alloc_len, n, ret;
+ 
+ 	alloc_len = (cmd[3] << 8) + cmd[4];
+-	arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_KERNEL);
++	arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_ATOMIC);
++	if (! arr)
++		return DID_REQUEUE << 16;
+ 	if (devip->wlun)
+ 		pq_pdt = 0x1e;	/* present, wlun */
+ 	else if (scsi_debug_no_lun_0 && (0 == devip->lun))
+@@ -1217,7 +1219,9 @@ static int resp_report_tgtpgs(struct scsi_cmnd * scp,
+ 	alen = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8)
+ 		+ cmd[9]);
+ 
+-	arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_KERNEL);
++	arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_ATOMIC);
++	if (! arr)
++		return DID_REQUEUE << 16;
+ 	/*
+ 	 * EVPD page 0x88 states we have two ports, one
+ 	 * real and a fake port with no device connected.
+@@ -1996,6 +2000,8 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp)
+ 	if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
+ 		sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
+ 	devip = devInfoReg(sdp);
++	if (NULL == devip)
++		return 1;       /* no resources, will be marked offline */
+ 	sdp->hostdata = devip;
+ 	if (sdp->host->cmd_per_lun)
+ 		scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING,
+@@ -2044,7 +2050,7 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
+ 		}
+ 	}
+ 	if (NULL == open_devip) { /* try and make a new one */
+-		open_devip = kzalloc(sizeof(*open_devip),GFP_KERNEL);
++		open_devip = kzalloc(sizeof(*open_devip),GFP_ATOMIC);
+ 		if (NULL == open_devip) {
+ 			printk(KERN_ERR "%s: out of memory at line %d\n",
+ 				__FUNCTION__, __LINE__);
+diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
+index 9d2fdfd..e6966f1 100644
+--- a/drivers/usb/serial/keyspan.c
++++ b/drivers/usb/serial/keyspan.c
+@@ -1275,11 +1275,31 @@ static int keyspan_fake_startup (struct usb_serial *serial)
+ }
+ 
+ /* Helper functions used by keyspan_setup_urbs */
++static struct usb_endpoint_descriptor const *find_ep(struct usb_serial const *serial,
++						     int endpoint)
++{
++	struct usb_host_interface *iface_desc;
++	struct usb_endpoint_descriptor *ep;
++	int i;
++
++	iface_desc = serial->interface->cur_altsetting;
++	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
++		ep = &iface_desc->endpoint[i].desc;
++		if (ep->bEndpointAddress == endpoint)
++			return ep;
++	}
++	dev_warn(&serial->interface->dev, "found no endpoint descriptor for "
++		 "endpoint %x\n", endpoint);
++	return NULL;
++}
++
+ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint,
+ 				      int dir, void *ctx, char *buf, int len,
+ 				      void (*callback)(struct urb *))
+ {
+ 	struct urb *urb;
++	struct usb_endpoint_descriptor const *ep_desc;
++	char const *ep_type_name;
+ 
+ 	if (endpoint == -1)
+ 		return NULL;		/* endpoint not needed */
+@@ -1291,11 +1311,32 @@ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint,
+ 		return NULL;
+ 	}
+ 
+-		/* Fill URB using supplied data. */
+-	usb_fill_bulk_urb(urb, serial->dev,
+-		      usb_sndbulkpipe(serial->dev, endpoint) | dir,
+-		      buf, len, callback, ctx);
++	ep_desc = find_ep(serial, endpoint);
++	if (!ep_desc) {
++		/* leak the urb, something's wrong and the callers don't care */
++		return urb;
++	}
++	if (usb_endpoint_xfer_int(ep_desc)) {
++		ep_type_name = "INT";
++		usb_fill_int_urb(urb, serial->dev,
++				 usb_sndintpipe(serial->dev, endpoint) | dir,
++				 buf, len, callback, ctx,
++				 ep_desc->bInterval);
++	} else if (usb_endpoint_xfer_bulk(ep_desc)) {
++		ep_type_name = "BULK";
++		usb_fill_bulk_urb(urb, serial->dev,
++				  usb_sndbulkpipe(serial->dev, endpoint) | dir,
++				  buf, len, callback, ctx);
++	} else {
++		dev_warn(&serial->interface->dev,
++			 "unsupported endpoint type %x\n",
++			 ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
++		usb_free_urb(urb);
++		return NULL;
++	}
+ 
++	dbg("%s - using urb %p for %s endpoint %x",
++	    __func__, urb, ep_type_name, endpoint);
+ 	return urb;
+ }
+ 
+diff --git a/include/linux/netfilter_ipv4/ip_conntrack_core.h b/include/linux/netfilter_ipv4/ip_conntrack_core.h
+index 907d4f5..e3a6df0 100644
+--- a/include/linux/netfilter_ipv4/ip_conntrack_core.h
++++ b/include/linux/netfilter_ipv4/ip_conntrack_core.h
+@@ -45,7 +45,7 @@ static inline int ip_conntrack_confirm(struct sk_buff **pskb)
+ 	int ret = NF_ACCEPT;
+ 
+ 	if (ct) {
+-		if (!is_confirmed(ct))
++		if (!is_confirmed(ct) && !is_dying(ct))
+ 			ret = __ip_conntrack_confirm(pskb);
+ 		ip_ct_deliver_cached_events(ct);
+ 	}
+diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
+index f7be1ac..09a2532 100644
+--- a/include/net/inet_timewait_sock.h
++++ b/include/net/inet_timewait_sock.h
+@@ -66,7 +66,7 @@ struct inet_hashinfo;
+ struct inet_timewait_death_row {
+ 	/* Short-time timewait calendar */
+ 	int			twcal_hand;
+-	int			twcal_jiffie;
++	unsigned long		twcal_jiffie;
+ 	struct timer_list	twcal_timer;
+ 	struct hlist_head	twcal_row[INET_TWDR_RECYCLE_SLOTS];
+ 
+diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
+index 7fdc72c..85634e1 100644
+--- a/include/net/netfilter/nf_conntrack_core.h
++++ b/include/net/netfilter/nf_conntrack_core.h
+@@ -64,7 +64,7 @@ static inline int nf_conntrack_confirm(struct sk_buff **pskb)
+ 	int ret = NF_ACCEPT;
+ 
+ 	if (ct) {
+-		if (!nf_ct_is_confirmed(ct))
++		if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
+ 			ret = __nf_conntrack_confirm(pskb);
+ 		nf_ct_deliver_cached_events(ct);
+ 	}
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 0ed5b4f..b69192b 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1597,7 +1597,7 @@ int compat_sock_common_getsockopt(struct socket *sock, int level, int optname,
+ {
+ 	struct sock *sk = sock->sk;
+ 
+-	if (sk->sk_prot->compat_setsockopt != NULL)
++	if (sk->sk_prot->compat_getsockopt != NULL)
+ 		return sk->sk_prot->compat_getsockopt(sk, level, optname,
+ 						      optval, optlen);
+ 	return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen);
+diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
+index 8556a4f..f8b3009 100644
+--- a/net/ipv4/netfilter/ip_conntrack_core.c
++++ b/net/ipv4/netfilter/ip_conntrack_core.c
+@@ -1242,7 +1242,7 @@ get_next_corpse(int (*iter)(struct ip_conntrack *i, void *data),
+ 	list_for_each_entry(h, &unconfirmed, list) {
+ 		ct = tuplehash_to_ctrack(h);
+ 		if (iter(ct, data))
+-			goto found;
++			set_bit(IPS_DYING_BIT, &ct->status);
+ 	}
+ 	write_unlock_bh(&ip_conntrack_lock);
+ 	return NULL;
+diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+index 06e4e8a..4cd76ed 100644
+--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
++++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+@@ -821,8 +821,10 @@ void ip_conntrack_tcp_update(struct sk_buff *skb,
+ static const u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
+ {
+ 	[TH_SYN]			= 1,
+-	[TH_SYN|TH_ACK]			= 1,
+ 	[TH_SYN|TH_PUSH]		= 1,
++	[TH_SYN|TH_URG]			= 1,
++	[TH_SYN|TH_PUSH|TH_URG]		= 1,
++	[TH_SYN|TH_ACK]			= 1,
+ 	[TH_SYN|TH_ACK|TH_PUSH]		= 1,
+ 	[TH_RST]			= 1,
+ 	[TH_RST|TH_ACK]			= 1,
+diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
+index 86a9227..8de7188 100644
+--- a/net/ipv4/netfilter/nf_nat_core.c
++++ b/net/ipv4/netfilter/nf_nat_core.c
+@@ -540,8 +540,7 @@ void nf_nat_protocol_unregister(struct nf_nat_protocol *proto)
+ }
+ EXPORT_SYMBOL(nf_nat_protocol_unregister);
+ 
+-#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
+-    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
++#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+ int
+ nf_nat_port_range_to_nfattr(struct sk_buff *skb,
+ 			    const struct nf_nat_range *range)
+diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c
+index d3de579..e5a34c1 100644
+--- a/net/ipv4/netfilter/nf_nat_proto_gre.c
++++ b/net/ipv4/netfilter/nf_nat_proto_gre.c
+@@ -152,8 +152,7 @@ static struct nf_nat_protocol gre __read_mostly = {
+ 	.manip_pkt		= gre_manip_pkt,
+ 	.in_range		= gre_in_range,
+ 	.unique_tuple		= gre_unique_tuple,
+-#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
+-    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
++#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+ 	.range_to_nfattr	= nf_nat_port_range_to_nfattr,
+ 	.nfattr_to_range	= nf_nat_port_nfattr_to_range,
+ #endif
+diff --git a/net/ipv4/netfilter/nf_nat_proto_icmp.c b/net/ipv4/netfilter/nf_nat_proto_icmp.c
+index dcfd772..b93c78a 100644
+--- a/net/ipv4/netfilter/nf_nat_proto_icmp.c
++++ b/net/ipv4/netfilter/nf_nat_proto_icmp.c
+@@ -78,8 +78,7 @@ struct nf_nat_protocol nf_nat_protocol_icmp = {
+ 	.manip_pkt		= icmp_manip_pkt,
+ 	.in_range		= icmp_in_range,
+ 	.unique_tuple		= icmp_unique_tuple,
+-#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
+-    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
++#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+ 	.range_to_nfattr	= nf_nat_port_range_to_nfattr,
+ 	.nfattr_to_range	= nf_nat_port_nfattr_to_range,
+ #endif
+diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c b/net/ipv4/netfilter/nf_nat_proto_tcp.c
+index 7e26a7e..f6b99d6 100644
+--- a/net/ipv4/netfilter/nf_nat_proto_tcp.c
++++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c
+@@ -140,8 +140,7 @@ struct nf_nat_protocol nf_nat_protocol_tcp = {
+ 	.manip_pkt		= tcp_manip_pkt,
+ 	.in_range		= tcp_in_range,
+ 	.unique_tuple		= tcp_unique_tuple,
+-#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
+-    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
++#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+ 	.range_to_nfattr	= nf_nat_port_range_to_nfattr,
+ 	.nfattr_to_range	= nf_nat_port_nfattr_to_range,
+ #endif
+diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c b/net/ipv4/netfilter/nf_nat_proto_udp.c
+index ab0ce4c..c00ab6e 100644
+--- a/net/ipv4/netfilter/nf_nat_proto_udp.c
++++ b/net/ipv4/netfilter/nf_nat_proto_udp.c
+@@ -130,8 +130,7 @@ struct nf_nat_protocol nf_nat_protocol_udp = {
+ 	.manip_pkt		= udp_manip_pkt,
+ 	.in_range		= udp_in_range,
+ 	.unique_tuple		= udp_unique_tuple,
+-#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
+-    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
++#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+ 	.range_to_nfattr	= nf_nat_port_range_to_nfattr,
+ 	.nfattr_to_range	= nf_nat_port_nfattr_to_range,
+ #endif
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index cfff930..f8068b0 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1214,6 +1214,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
+ 
+ 		if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen))
+ 			goto short_packet;
++		uh = skb->h.uh;
+ 
+ 		udp4_csum_init(skb, uh);
+ 
+diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
+index f6294e5..ca50b58 100644
+--- a/net/ipv6/netfilter.c
++++ b/net/ipv6/netfilter.c
+@@ -15,6 +15,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
+ 	struct dst_entry *dst;
+ 	struct flowi fl = {
+ 		.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
++		.mark = skb->mark,
+ 		.nl_u =
+ 		{ .ip6_u =
+ 		  { .daddr = iph->daddr,
+diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+index a20615f..6155b80 100644
+--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
++++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+@@ -257,6 +257,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
+ 		}
+ 		nf_conntrack_get(reasm->nfct);
+ 		(*pskb)->nfct = reasm->nfct;
++		(*pskb)->nfctinfo = reasm->nfctinfo;
+ 		return NF_ACCEPT;
+ 	}
+ 
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 9b02ec4..cb29ba7 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -1052,7 +1052,7 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
+ 	list_for_each_entry(h, &unconfirmed, list) {
+ 		ct = nf_ct_tuplehash_to_ctrack(h);
+ 		if (iter(ct, data))
+-			goto found;
++			set_bit(IPS_DYING_BIT, &ct->status);
+ 	}
+ 	write_unlock_bh(&nf_conntrack_lock);
+ 	return NULL;
+diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
+index ac193ce..5434472 100644
+--- a/net/netfilter/nf_conntrack_proto_gre.c
++++ b/net/netfilter/nf_conntrack_proto_gre.c
+@@ -281,8 +281,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 = {
+ 	.new		 = gre_new,
+ 	.destroy	 = gre_destroy,
+ 	.me 		 = THIS_MODULE,
+-#if defined(CONFIG_NF_CONNTRACK_NETLINK) || \
+-    defined(CONFIG_NF_CONNTRACK_NETLINK_MODULE)
++#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+ 	.tuple_to_nfattr = nf_ct_port_tuple_to_nfattr,
+ 	.nfattr_to_tuple = nf_ct_port_nfattr_to_tuple,
+ #endif
+diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
+index 626b001..693d189 100644
+--- a/net/netfilter/nf_conntrack_proto_tcp.c
++++ b/net/netfilter/nf_conntrack_proto_tcp.c
+@@ -778,8 +778,10 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update);
+ static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
+ {
+ 	[TH_SYN]			= 1,
+-	[TH_SYN|TH_ACK]			= 1,
+ 	[TH_SYN|TH_PUSH]		= 1,
++	[TH_SYN|TH_URG]			= 1,
++	[TH_SYN|TH_PUSH|TH_URG]		= 1,
++	[TH_SYN|TH_ACK]			= 1,
+ 	[TH_SYN|TH_ACK|TH_PUSH]		= 1,
+ 	[TH_RST]			= 1,
+ 	[TH_RST|TH_ACK]			= 1,
+diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
+index 24c1d29..690b173 100644
+--- a/net/netfilter/nfnetlink_log.c
++++ b/net/netfilter/nfnetlink_log.c
+@@ -397,8 +397,8 @@ static void nfulnl_timer(unsigned long data)
+ 	if (timer_pending(&inst->timer))	/* is it always true or false here? */
+ 		del_timer(&inst->timer);
+ 	__nfulnl_send(inst);
+-	instance_put(inst);
+ 	spin_unlock_bh(&inst->lock);
++	instance_put(inst);
+ }
+ 
+ /* This is an inline function, we don't really care about a long
+@@ -491,7 +491,7 @@ __build_packet_message(struct nfulnl_instance *inst,
+ 			 * for physical device (when called from ipv4) */
+ 			NFA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV,
+ 				sizeof(tmp_uint), &tmp_uint);
+-			if (skb->nf_bridge) {
++			if (skb->nf_bridge && skb->nf_bridge->physoutdev) {
+ 				tmp_uint = 
+ 				    htonl(skb->nf_bridge->physoutdev->ifindex);
+ 				NFA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
+@@ -564,6 +564,7 @@ __build_packet_message(struct nfulnl_instance *inst,
+ 	}
+ 		
+ 	nlh->nlmsg_len = inst->skb->tail - old_tail;
++	inst->lastnlh = nlh;
+ 	return 0;
+ 
+ nlmsg_failure:
+@@ -619,7 +620,7 @@ nfulnl_log_packet(unsigned int pf,
+ 
+ 	plen = 0;
+ 	if (prefix)
+-		plen = strlen(prefix);
++		plen = strlen(prefix) + 1;
+ 
+ 	/* all macros expand to constant values at compile time */
+ 	/* FIXME: do we want to make the size calculation conditional based on
+@@ -720,15 +721,16 @@ nfulnl_log_packet(unsigned int pf,
+ 		inst->timer.expires = jiffies + (inst->flushtimeout*HZ/100);
+ 		add_timer(&inst->timer);
+ 	}
+-	spin_unlock_bh(&inst->lock);
+ 
++unlock_and_release:
++	spin_unlock_bh(&inst->lock);
++	instance_put(inst);
+ 	return;
+ 
+ alloc_failure:
+-	spin_unlock_bh(&inst->lock);
+-	instance_put(inst);
+ 	UDEBUG("error allocating skb\n");
+ 	/* FIXME: statistics */
++	goto unlock_and_release;
+ }
+ 
+ static int
+@@ -865,6 +867,9 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
+ 			ret = -EINVAL;
+ 			break;
+ 		}
++
++		if (!inst)
++			goto out;
+ 	} else {
+ 		if (!inst) {
+ 			UDEBUG("no config command, and no instance for "
+@@ -918,6 +923,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
+ 
+ out_put:
+ 	instance_put(inst);
++out:
+ 	return ret;
+ }
+ 

Modified: dists/trunk/linux-2.6/debian/patches/series/1~experimental.1
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	(original)
+++ dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	Tue Mar 13 22:59:19 2007
@@ -37,3 +37,4 @@
 + bugfix/all/stable/2.6.20.1
 + bugfix/all/stable/2.6.20.2
 + bugfix/powerpc/drivers_macintosh-broken.patch
++ bugfix/2.6.20.3



More information about the Kernel-svn-changes mailing list