diff -Nru a/Makefile b/Makefile
--- a/Makefile	Wed Dec 17 19:00:07 2003
+++ b/Makefile	Wed Dec 17 19:00:07 2003
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 0
-EXTRAVERSION = -test11
+EXTRAVERSION =
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -Nru a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
--- a/arch/i386/mm/fault.c	Wed Dec 17 19:00:07 2003
+++ b/arch/i386/mm/fault.c	Wed Dec 17 19:00:07 2003
@@ -359,7 +359,8 @@
 			return;
 
 		tsk->thread.cr2 = address;
-		tsk->thread.error_code = error_code;
+		/* Kernel addresses are always protection faults */
+		tsk->thread.error_code = error_code | (address >= TASK_SIZE);
 		tsk->thread.trap_no = 14;
 		info.si_signo = SIGSEGV;
 		info.si_errno = 0;
diff -Nru a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c
--- a/drivers/block/scsi_ioctl.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/block/scsi_ioctl.c	Wed Dec 17 19:00:07 2003
@@ -432,12 +432,23 @@
 			break;
 		case SG_IO: {
 			struct sg_io_hdr hdr;
+			unsigned char cdb[BLK_MAX_CDB], *old_cdb;
 
-			if (copy_from_user(&hdr, (struct sg_io_hdr *) arg, sizeof(hdr))) {
-				err = -EFAULT;
+			err = -EFAULT;
+			if (copy_from_user(&hdr, (struct sg_io_hdr *) arg, sizeof(hdr)))
 				break;
-			}
+			err = -EINVAL;
+			if (hdr.cmd_len > sizeof(rq->cmd))
+				break;
+			err = -EFAULT;
+			if (copy_from_user(cdb, hdr.cmdp, hdr.cmd_len))
+				break;
+
+			old_cdb = hdr.cmdp;
+			hdr.cmdp = cdb;
 			err = sg_io(q, bdev, &hdr);
+
+			hdr.cmdp = old_cdb;
 			if (copy_to_user((struct sg_io_hdr *) arg, &hdr, sizeof(hdr)))
 				err = -EFAULT;
 			break;
diff -Nru a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
--- a/drivers/i2c/busses/i2c-nforce2.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/i2c/busses/i2c-nforce2.c	Wed Dec 17 19:00:07 2003
@@ -147,7 +147,7 @@
 
 		case I2C_SMBUS_BYTE:
 			if (read_write == I2C_SMBUS_WRITE)
-				outb_p(data->byte, NVIDIA_SMB_DATA);
+				outb_p(command, NVIDIA_SMB_CMD);
 			protocol |= NVIDIA_SMB_PRTCL_BYTE;
 			break;
 
diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/ide/ide-cd.c	Wed Dec 17 19:00:07 2003
@@ -799,6 +799,10 @@
 			 * sector...  If we got here the error is not correctable */
 			ide_dump_status (drive, "media error (bad sector)", stat);
 			do_end_request = 1;
+		} else if (sense_key == BLANK_CHECK) {
+			/* Disk appears blank ?? */
+			ide_dump_status (drive, "media error (blank)", stat);
+			do_end_request = 1;
 		} else if ((err & ~ABRT_ERR) != 0) {
 			/* Go to the default handler
 			   for other errors. */
diff -Nru a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
--- a/drivers/ide/ide-cd.h	Wed Dec 17 19:00:07 2003
+++ b/drivers/ide/ide-cd.h	Wed Dec 17 19:00:07 2003
@@ -501,6 +501,7 @@
 #define ILLEGAL_REQUEST         0x05
 #define UNIT_ATTENTION          0x06
 #define DATA_PROTECT            0x07
+#define BLANK_CHECK             0x08
 #define ABORTED_COMMAND         0x0b
 #define MISCOMPARE              0x0e
 
@@ -578,7 +579,7 @@
 	"Illegal request",
 	"Unit attention",
 	"Data protect",
-	"(reserved)",
+	"Blank check",
 	"(reserved)",
 	"(reserved)",
 	"Aborted command",
diff -Nru a/drivers/md/raid5.c b/drivers/md/raid5.c
--- a/drivers/md/raid5.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/md/raid5.c	Wed Dec 17 19:00:07 2003
@@ -40,6 +40,16 @@
 
 #define stripe_hash(conf, sect)	((conf)->stripe_hashtbl[((sect) >> STRIPE_SHIFT) & HASH_MASK])
 
+/* bio's attached to a stripe+device for I/O are linked together in bi_sector
+ * order without overlap.  There may be several bio's per stripe+device, and
+ * a bio could span several devices.
+ * When walking this list for a particular stripe+device, we must never proceed
+ * beyond a bio that extends past this device, as the next bio might no longer
+ * be valid.
+ * This macro is used to determine the 'next' bio in the list, given the sector
+ * of the current stripe+device
+ */
+#define r5_next_bio(bio, sect) ( ( bio->bi_sector + (bio->bi_size>>9) < sect + STRIPE_SECTORS) ? bio->bi_next : NULL)
 /*
  * The following can be used to debug the driver
  */
@@ -613,7 +623,7 @@
 	int i;
 
 	for (;bio && bio->bi_sector < sector+STRIPE_SECTORS;
-		bio = bio->bi_next) {
+	      bio = r5_next_bio(bio, sector) ) {
 		int page_offset;
 		if (bio->bi_sector >= sector)
 			page_offset = (signed)(bio->bi_sector - sector) * 512;
@@ -738,7 +748,11 @@
 	for (i = disks; i--;)
 		if (sh->dev[i].written) {
 			sector_t sector = sh->dev[i].sector;
-			copy_data(1, sh->dev[i].written, sh->dev[i].page, sector);
+			struct bio *wbi = sh->dev[i].written;
+			while (wbi && wbi->bi_sector < sector + STRIPE_SECTORS) {
+				copy_data(1, wbi, sh->dev[i].page, sector);
+				wbi = r5_next_bio(wbi, sector);
+			}
 
 			set_bit(R5_LOCKED, &sh->dev[i].flags);
 			set_bit(R5_UPTODATE, &sh->dev[i].flags);
@@ -791,8 +805,10 @@
 		bip = &sh->dev[dd_idx].towrite;
 	else
 		bip = &sh->dev[dd_idx].toread;
-	while (*bip && (*bip)->bi_sector < bi->bi_sector)
+	while (*bip && (*bip)->bi_sector < bi->bi_sector) {
+		BUG_ON((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector);
 		bip = & (*bip)->bi_next;
+	}
 /* FIXME do I need to worry about overlapping bion */
 	if (*bip && bi->bi_next && (*bip) != bi->bi_next)
 		BUG();
@@ -813,7 +829,7 @@
 		for (bi=sh->dev[dd_idx].towrite;
 		     sector < sh->dev[dd_idx].sector + STRIPE_SECTORS &&
 			     bi && bi->bi_sector <= sector;
-		     bi = bi->bi_next) {
+		     bi = r5_next_bio(bi, sh->dev[dd_idx].sector)) {
 			if (bi->bi_sector + (bi->bi_size>>9) >= sector)
 				sector = bi->bi_sector + (bi->bi_size>>9);
 		}
@@ -883,7 +899,7 @@
 			spin_unlock_irq(&conf->device_lock);
 			while (rbi && rbi->bi_sector < dev->sector + STRIPE_SECTORS) {
 				copy_data(0, rbi, dev->page, dev->sector);
-				rbi2 = rbi->bi_next;
+				rbi2 = r5_next_bio(rbi, dev->sector);
 				spin_lock_irq(&conf->device_lock);
 				if (--rbi->bi_phys_segments == 0) {
 					rbi->bi_next = return_bi;
@@ -928,7 +944,7 @@
 			if (bi) to_write--;
 
 			while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){
-				struct bio *nextbi = bi->bi_next;
+				struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
 				clear_bit(BIO_UPTODATE, &bi->bi_flags);
 				if (--bi->bi_phys_segments == 0) {
 					md_write_end(conf->mddev);
@@ -941,7 +957,7 @@
 			bi = sh->dev[i].written;
 			sh->dev[i].written = NULL;
 			while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS) {
-				struct bio *bi2 = bi->bi_next;
+				struct bio *bi2 = r5_next_bio(bi, sh->dev[i].sector);
 				clear_bit(BIO_UPTODATE, &bi->bi_flags);
 				if (--bi->bi_phys_segments == 0) {
 					md_write_end(conf->mddev);
@@ -957,7 +973,7 @@
 				sh->dev[i].toread = NULL;
 				if (bi) to_read--;
 				while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){
-					struct bio *nextbi = bi->bi_next;
+					struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
 					clear_bit(BIO_UPTODATE, &bi->bi_flags);
 					if (--bi->bi_phys_segments == 0) {
 						bi->bi_next = return_bi;
@@ -1000,7 +1016,7 @@
 			    wbi = dev->written;
 			    dev->written = NULL;
 			    while (wbi && wbi->bi_sector < dev->sector + STRIPE_SECTORS) {
-				    wbi2 = wbi->bi_next;
+				    wbi2 = r5_next_bio(wbi, dev->sector);
 				    if (--wbi->bi_phys_segments == 0) {
 					    md_write_end(conf->mddev);
 					    wbi->bi_next = return_bi;
diff -Nru a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
--- a/drivers/net/pci-skeleton.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/net/pci-skeleton.c	Wed Dec 17 19:00:07 2003
@@ -864,13 +864,6 @@
 
 	pci_release_regions (pdev);
 
-#ifndef NETDRV_NDEBUG
-	/* poison memory before freeing */
-	memset (dev, 0xBC,
-		sizeof (struct net_device) +
-		sizeof (struct netdrv_private));
-#endif /* NETDRV_NDEBUG */
-
 	free_netdev (dev);
 
 	pci_set_drvdata (pdev, NULL);
diff -Nru a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
--- a/drivers/net/pcnet32.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/net/pcnet32.c	Wed Dec 17 19:00:07 2003
@@ -1766,8 +1766,6 @@
 	next_dev = lp->next;
 	unregister_netdev(pcnet32_dev);
 	release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
-	if (lp->pci_dev)
-	    pci_unregister_driver(&pcnet32_driver);
 	pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
 	free_netdev(pcnet32_dev);
 	pcnet32_dev = next_dev;
diff -Nru a/drivers/net/r8169.c b/drivers/net/r8169.c
--- a/drivers/net/r8169.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/net/r8169.c	Wed Dec 17 19:00:07 2003
@@ -642,10 +642,6 @@
 	iounmap(tp->mmio_addr);
 	pci_release_regions(pdev);
 
-	// poison memory before freeing 
-	memset(dev, 0xBC,
-	       sizeof (struct net_device) + sizeof (struct rtl8169_private));
-
 	pci_disable_device(pdev);
 	free_netdev(dev);
 	pci_set_drvdata(pdev, NULL);
diff -Nru a/drivers/net/sis190.c b/drivers/net/sis190.c
--- a/drivers/net/sis190.c	Wed Dec 17 19:00:08 2003
+++ b/drivers/net/sis190.c	Wed Dec 17 19:00:08 2003
@@ -703,10 +703,6 @@
 	iounmap(tp->mmio_addr);
 	pci_release_regions(pdev);
 
-	// poison memory before freeing 
-	memset(dev, 0xBC,
-	       sizeof (struct net_device) + sizeof (struct sis190_private));
-
 	free_netdev(dev);
 	pci_set_drvdata(pdev, NULL);
 }
diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/net/wireless/airo.c	Wed Dec 17 19:00:07 2003
@@ -2466,11 +2466,8 @@
 			OUT4500( apriv, EVACK, EV_MIC );
 #ifdef MICSUPPORT
 			if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {
-				if (down_trylock(&apriv->sem) != 0) {
-					set_bit(JOB_MIC, &apriv->flags);
-					wake_up_interruptible(&apriv->thr_wait);
-				} else
-					micinit (apriv);
+				set_bit(JOB_MIC, &apriv->flags);
+				wake_up_interruptible(&apriv->thr_wait);
 			}
 #endif
 		}
diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
--- a/drivers/scsi/ide-scsi.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/scsi/ide-scsi.c	Wed Dec 17 19:00:07 2003
@@ -517,6 +517,7 @@
 	pc->current_position=pc->buffer;
 	bcount.all = IDE_MIN(pc->request_transfer, 63 * 1024);		/* Request to transfer the entire buffer at once */
 
+	feature.all = 0;
 	if (drive->using_dma && rq->bio) {
 		if (test_bit(PC_WRITING, &pc->flags))
 			feature.b.dma = !HWIF(drive)->ide_dma_write(drive);
diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
--- a/drivers/scsi/libata-core.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/scsi/libata-core.c	Wed Dec 17 19:00:07 2003
@@ -3224,8 +3224,6 @@
 		scsi_host_put(ap->host); /* FIXME: check return val */
 	}
 
-	kfree(host_set);
-
 	pci_release_regions(pdev);
 
 	for (i = 0; i < host_set->n_ports; i++) {
@@ -3242,6 +3240,7 @@
 		}
 	}
 
+	kfree(host_set);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
 }
diff -Nru a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
--- a/drivers/scsi/qla1280.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/scsi/qla1280.c	Wed Dec 17 19:00:07 2003
@@ -16,9 +16,13 @@
 * General Public License for more details.
 *
 ******************************************************************************/
-#define QLA1280_VERSION      "3.23.37"
+#define QLA1280_VERSION      "3.23.37.1"
 /*****************************************************************************
     Revision History:
+    Rev  3.23.37.1 December 17, 2003, Jes Sorensen
+	- Delete completion queue from srb if mailbox command failed to
+	  to avoid qla1280_done completeting qla1280_error_action's
+	  obsolete context
     Rev  3.23.37 October 1, 2003, Jes Sorensen
 	- Make MMIO depend on CONFIG_X86_VISWS instead of yet another
 	  random CONFIG option
@@ -1464,8 +1468,15 @@
 	/* If we didn't manage to issue the action, or we have no
 	 * command to wait for, exit here */
 	if (result == FAILED || handle == NULL ||
-	    handle == (unsigned char *)INVALID_HANDLE)
+	    handle == (unsigned char *)INVALID_HANDLE) {
+		/*
+		 * Clear completion queue to avoid qla1280_done() trying
+		 * to complete the command at a later stage after we
+		 * have exited the current context
+		 */
+		sp->wait = NULL;
 		goto leave;
+	}
 
 	/* set up a timer just in case we're really jammed */
 	init_timer(&timer);
diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/usb/core/devio.c	Wed Dec 17 19:00:07 2003
@@ -261,7 +261,6 @@
         spin_lock(&ps->lock);
         list_move_tail(&as->asynclist, &ps->async_completed);
         spin_unlock(&ps->lock);
-        wake_up(&ps->wait);
 	if (as->signr) {
 		sinfo.si_signo = as->signr;
 		sinfo.si_errno = as->urb->status;
@@ -269,6 +268,7 @@
 		sinfo.si_addr = (void *)as->userurb;
 		send_sig_info(as->signr, &sinfo, as->task);
 	}
+        wake_up(&ps->wait);
 }
 
 static void destroy_async (struct dev_state *ps, struct list_head *list)
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/usb/core/hub.c	Wed Dec 17 19:00:07 2003
@@ -692,6 +692,9 @@
 	struct usb_hub *hub = usb_get_intfdata(dev->actconfig->interface[0]);
 	int ret;
 
+	if (!hub)
+		return -ENODEV;
+
 	ret = get_port_status(dev, port + 1, &hub->status->port);
 	if (ret < 0)
 		dev_err (hubdev (dev),
@@ -926,7 +929,6 @@
 			break;
 		}
 
-		hub->children[port] = dev;
 		dev->state = USB_STATE_POWERED;
 
 		/* Reset the device, and detect its speed */
@@ -979,8 +981,10 @@
 		dev->dev.parent = dev->parent->dev.parent->parent;
 
 		/* Run it through the hoops (find a driver, etc) */
-		if (!usb_new_device(dev, &hub->dev))
+		if (!usb_new_device(dev, &hub->dev)) {
+			hub->children[port] = dev;
 			goto done;
+		}
 
 		/* Free the configuration if there was an error */
 		usb_put_dev(dev);
@@ -989,7 +993,6 @@
 		delay = HUB_LONG_RESET_TIME;
 	}
 
-	hub->children[port] = NULL;
 	hub_port_disable(hub, port);
 done:
 	up(&usb_address0_sem);
@@ -1342,6 +1345,7 @@
 			dev->devpath, ret);
 		return ret;
 	}
+	dev->state = USB_STATE_CONFIGURED;
 
 	for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
 		struct usb_interface *intf = dev->actconfig->interface[i];
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/usb/core/usb.c	Wed Dec 17 19:00:07 2003
@@ -1120,6 +1120,7 @@
 	if (err) {
 		dev_err(&dev->dev, "can't set config #%d, error %d\n",
 			dev->config[0].desc.bConfigurationValue, err);
+		device_del(&dev->dev);
 		goto fail;
 	}
 
diff -Nru a/drivers/usb/image/Kconfig b/drivers/usb/image/Kconfig
--- a/drivers/usb/image/Kconfig	Wed Dec 17 19:00:07 2003
+++ b/drivers/usb/image/Kconfig	Wed Dec 17 19:00:07 2003
@@ -18,12 +18,14 @@
 	  module will be called mdc800.
 
 config USB_SCANNER
-	tristate "USB Scanner support"
+	tristate "USB Scanner support (OBSOLETE)"
 	depends on USB
 	help
 	  Say Y here if you want to connect a USB scanner to your computer's
 	  USB port. Please read <file:Documentation/usb/scanner.txt> for more
 	  information.
+
+	  This driver has been obsoleted by support via libusb.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called scanner.
diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
--- a/drivers/usb/misc/auerswald.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/usb/misc/auerswald.c	Wed Dec 17 19:00:07 2003
@@ -324,7 +324,7 @@
                 urb    = acep->urbp;
                 dbg ("auerchain_complete: submitting next urb from chain");
 		urb->status = 0;	/* needed! */
-		result = usb_submit_urb(urb, GFP_KERNEL);
+		result = usb_submit_urb(urb, GFP_ATOMIC);
 
                 /* check for submit errors */
                 if (result) {
@@ -402,7 +402,7 @@
         if (acep) {
                 dbg("submitting urb immediate");
 		urb->status = 0;	/* needed! */
-                result = usb_submit_urb(urb, GFP_KERNEL);
+                result = usb_submit_urb(urb, GFP_ATOMIC);
                 /* check for submit errors */
                 if (result) {
                         urb->status = result;
diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/usb/serial/usb-serial.c	Wed Dec 17 19:00:07 2003
@@ -493,12 +493,15 @@
 	return retval;
 }
 
-static void __serial_close(struct usb_serial_port *port, struct file *filp)
+static void serial_close(struct tty_struct *tty, struct file * filp)
 {
-	if (!port->open_count) {
-		dbg ("%s - port not opened", __FUNCTION__);
+	struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
+
+	if (!serial)
 		return;
-	}
+
+	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	--port->open_count;
 	if (port->open_count <= 0) {
@@ -506,30 +509,18 @@
 		 * port is being closed by the last owner */
 		port->serial->type->close(port, filp);
 		port->open_count = 0;
+
+		if (port->tty) {
+			if (port->tty->driver_data)
+				port->tty->driver_data = NULL;
+			port->tty = NULL;
+		}
 	}
 
 	module_put(port->serial->type->owner);
 	kobject_put(&port->serial->kobj);
 }
 
-static void serial_close(struct tty_struct *tty, struct file * filp)
-{
-	struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
-	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
-
-	if (!serial)
-		return;
-
-	dbg("%s - port %d", __FUNCTION__, port->number);
-
-	/* if disconnect beat us to the punch here, there's nothing to do */
-	if (tty && tty->driver_data) {
-		__serial_close(port, filp);
-		tty->driver_data = NULL;
-	}
-	port->tty = NULL;
-}
-
 static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
@@ -848,19 +839,6 @@
 	dbg ("%s - %s", __FUNCTION__, kobj->name);
 
 	serial = to_usb_serial(kobj);
-
-	/* fail all future close/read/write/ioctl/etc calls */
-	for (i = 0; i < serial->num_ports; ++i) {
-		port = serial->port[i];
-		if (port->tty != NULL) {
-			port->tty->driver_data = NULL;
-			while (port->open_count > 0) {
-				__serial_close(port, NULL);
-			}
-			port->tty = NULL;
-		}
-	}
-
 	serial_shutdown (serial);
 
 	/* return the minor range that this device had */
@@ -1242,7 +1220,7 @@
 	/* register all of the individual ports with the driver core */
 	for (i = 0; i < num_ports; ++i) {
 		port = serial->port[i];
-		port->dev.parent = &serial->dev->dev;
+		port->dev.parent = &interface->dev;
 		port->dev.driver = NULL;
 		port->dev.bus = &usb_serial_bus_type;
 		port->dev.release = &port_release;
diff -Nru a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c
--- a/drivers/usb/storage/datafab.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/usb/storage/datafab.c	Wed Dec 17 19:00:07 2003
@@ -387,7 +387,7 @@
 
 	// we'll go ahead and extract the media capacity while we're here...
 	//
-	rc = datafab_bulk_read(us, reply, sizeof(reply));
+	rc = datafab_bulk_read(us, reply, 512);
 	if (rc == USB_STOR_XFER_GOOD) {
 		// capacity is at word offset 57-58
 		//
diff -Nru a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c
--- a/drivers/usb/storage/jumpshot.c	Wed Dec 17 19:00:07 2003
+++ b/drivers/usb/storage/jumpshot.c	Wed Dec 17 19:00:07 2003
@@ -317,7 +317,7 @@
 	}
 
 	// read the reply
-	rc = jumpshot_bulk_read(us, reply, sizeof(reply));
+	rc = jumpshot_bulk_read(us, reply, 512);
 	if (rc != USB_STOR_XFER_GOOD) {
 		rc = USB_STOR_TRANSPORT_ERROR;
 		goto leave;
diff -Nru a/fs/hpfs/dir.c b/fs/hpfs/dir.c
--- a/fs/hpfs/dir.c	Wed Dec 17 19:00:07 2003
+++ b/fs/hpfs/dir.c	Wed Dec 17 19:00:07 2003
@@ -65,6 +65,8 @@
 	int c1, c2 = 0;
 	int ret = 0;
 
+	lock_kernel();
+
 	if (hpfs_sb(inode->i_sb)->sb_chk) {
 		if (hpfs_chk_sectors(inode->i_sb, inode->i_ino, 1, "dir_fnode")) {
 			ret = -EFSERROR;
diff -Nru a/fs/libfs.c b/fs/libfs.c
--- a/fs/libfs.c	Wed Dec 17 19:00:07 2003
+++ b/fs/libfs.c	Wed Dec 17 19:00:07 2003
@@ -79,6 +79,7 @@
 			loff_t n = file->f_pos - 2;
 
 			spin_lock(&dcache_lock);
+			list_del(&cursor->d_child);
 			p = file->f_dentry->d_subdirs.next;
 			while (n && p != &file->f_dentry->d_subdirs) {
 				struct dentry *next;
@@ -87,7 +88,6 @@
 					n--;
 				p = p->next;
 			}
-			list_del(&cursor->d_child);
 			list_add_tail(&cursor->d_child, p);
 			spin_unlock(&dcache_lock);
 		}
diff -Nru a/fs/proc/base.c b/fs/proc/base.c
--- a/fs/proc/base.c	Wed Dec 17 19:00:07 2003
+++ b/fs/proc/base.c	Wed Dec 17 19:00:07 2003
@@ -1666,10 +1666,14 @@
 
 	index -= 2;
 	read_lock(&tasklist_lock);
-	do {
+	/*
+	 * The starting point task (leader_task) might be an already
+	 * unlinked task, which cannot be used to access the task-list
+	 * via next_thread().
+	 */
+	if (pid_alive(task)) do {
 		int tid = task->pid;
-		if (!pid_alive(task))
-			continue;
+
 		if (--index >= 0)
 			continue;
 		tids[nr_tids] = tid;
diff -Nru a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h
--- a/include/asm-x86_64/msr.h	Wed Dec 17 19:00:07 2003
+++ b/include/asm-x86_64/msr.h	Wed Dec 17 19:00:07 2003
@@ -50,9 +50,9 @@
      __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx")
 
 #define rdtscll(val) do { \
-     unsigned int a,d; \
-     asm volatile("rdtsc" : "=a" (a), "=d" (d)); \
-     (val) = ((unsigned long)a) | (((unsigned long)d)<<32); \
+     unsigned int __a,__d; \
+     asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \
+     (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
 } while(0)
 
 #define rdpmc(counter,low,high) \
diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	Wed Dec 17 19:00:07 2003
+++ b/include/linux/blkdev.h	Wed Dec 17 19:00:07 2003
@@ -82,6 +82,8 @@
 	wait_queue_head_t wait[2];
 };
 
+#define BLK_MAX_CDB	16
+
 /*
  * try to put the fields that are referenced together in the same cacheline
  */
@@ -147,7 +149,7 @@
 	 * when request is used as a packet command carrier
 	 */
 	unsigned int cmd_len;
-	unsigned char cmd[16];
+	unsigned char cmd[BLK_MAX_CDB];
 
 	unsigned int data_len;
 	void *data;
diff -Nru a/include/linux/list.h b/include/linux/list.h
--- a/include/linux/list.h	Wed Dec 17 19:00:07 2003
+++ b/include/linux/list.h	Wed Dec 17 19:00:07 2003
@@ -208,6 +208,18 @@
 	return head->next == head;
 }
 
+/**
+ * list_empty_careful - tests whether a list is
+ * empty _and_ checks that no other CPU might be
+ * in the process of still modifying either member
+ * @head: the list to test.
+ */
+static inline int list_empty_careful(const struct list_head *head)
+{
+	struct list_head *next = head->next;
+	return (next == head) && (next == head->prev);
+}
+
 static inline void __list_splice(struct list_head *list,
 				 struct list_head *head)
 {
diff -Nru a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
--- a/include/linux/rtnetlink.h	Wed Dec 17 19:00:07 2003
+++ b/include/linux/rtnetlink.h	Wed Dec 17 19:00:07 2003
@@ -138,6 +138,7 @@
 #define RTPROT_ZEBRA	11	/* Zebra */
 #define RTPROT_BIRD	12	/* BIRD */
 #define RTPROT_DNROUTED	13	/* DECnet routing daemon */
+#define RTPROT_XORP	14	/* XORP */
 
 /* rtm_scope
 
diff -Nru a/kernel/exit.c b/kernel/exit.c
--- a/kernel/exit.c	Wed Dec 17 19:00:07 2003
+++ b/kernel/exit.c	Wed Dec 17 19:00:07 2003
@@ -49,9 +49,11 @@
 
 void release_task(struct task_struct * p)
 {
+	int zap_leader;
 	task_t *leader;
 	struct dentry *proc_dentry;
- 
+
+repeat: 
 	BUG_ON(p->state < TASK_ZOMBIE);
  
 	atomic_dec(&p->user->processes);
@@ -70,10 +72,21 @@
 	 * group, and the leader is zombie, then notify the
 	 * group leader's parent process. (if it wants notification.)
 	 */
+	zap_leader = 0;
 	leader = p->group_leader;
-	if (leader != p && thread_group_empty(leader) &&
-		    leader->state == TASK_ZOMBIE && leader->exit_signal != -1)
+	if (leader != p && thread_group_empty(leader) && leader->state == TASK_ZOMBIE) {
+		BUG_ON(leader->exit_signal == -1);
 		do_notify_parent(leader, leader->exit_signal);
+		/*
+		 * If we were the last child thread and the leader has
+		 * exited already, and the leader's parent ignores SIGCHLD,
+		 * then we are the one who should release the leader.
+		 *
+		 * do_notify_parent() will have marked it self-reaping in
+		 * that case.
+		 */
+		zap_leader = (leader->exit_signal == -1);
+	}
 
 	p->parent->cutime += p->utime + p->cutime;
 	p->parent->cstime += p->stime + p->cstime;
@@ -88,6 +101,10 @@
 	proc_pid_flush(proc_dentry);
 	release_thread(p);
 	put_task_struct(p);
+
+	p = leader;
+	if (unlikely(zap_leader))
+		goto repeat;
 }
 
 /* we are using it only for SMP init */
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c	Wed Dec 17 19:00:07 2003
+++ b/kernel/fork.c	Wed Dec 17 19:00:07 2003
@@ -125,15 +125,28 @@
 
 EXPORT_SYMBOL(remove_wait_queue);
 
+
+/*
+ * Note: we use "set_current_state()" _after_ the wait-queue add,
+ * because we need a memory barrier there on SMP, so that any
+ * wake-function that tests for the wait-queue being active
+ * will be guaranteed to see waitqueue addition _or_ subsequent
+ * tests in this thread will see the wakeup having taken place.
+ *
+ * The spin_unlock() itself is semi-permeable and only protects
+ * one way (it only protects stuff inside the critical region and
+ * stops them from bleeding out - it would still allow subsequent
+ * loads to move into the the critical region).
+ */
 void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
 {
 	unsigned long flags;
 
-	__set_current_state(state);
 	wait->flags &= ~WQ_FLAG_EXCLUSIVE;
 	spin_lock_irqsave(&q->lock, flags);
 	if (list_empty(&wait->task_list))
 		__add_wait_queue(q, wait);
+	set_current_state(state);
 	spin_unlock_irqrestore(&q->lock, flags);
 }
 
@@ -144,11 +157,11 @@
 {
 	unsigned long flags;
 
-	__set_current_state(state);
 	wait->flags |= WQ_FLAG_EXCLUSIVE;
 	spin_lock_irqsave(&q->lock, flags);
 	if (list_empty(&wait->task_list))
 		__add_wait_queue_tail(q, wait);
+	set_current_state(state);
 	spin_unlock_irqrestore(&q->lock, flags);
 }
 
@@ -159,7 +172,20 @@
 	unsigned long flags;
 
 	__set_current_state(TASK_RUNNING);
-	if (!list_empty(&wait->task_list)) {
+	/*
+	 * We can check for list emptiness outside the lock
+	 * IFF:
+	 *  - we use the "careful" check that verifies both
+	 *    the next and prev pointers, so that there cannot
+	 *    be any half-pending updates in progress on other
+	 *    CPU's that we haven't seen yet (and that might
+	 *    still change the stack area.
+	 * and
+	 *  - all other users take the lock (ie we can only
+	 *    have _one_ other CPU that looks at or modifies
+	 *    the list).
+	 */
+	if (!list_empty_careful(&wait->task_list)) {
 		spin_lock_irqsave(&q->lock, flags);
 		list_del_init(&wait->task_list);
 		spin_unlock_irqrestore(&q->lock, flags);
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	Wed Dec 17 19:00:07 2003
+++ b/kernel/sched.c	Wed Dec 17 19:00:07 2003
@@ -646,7 +646,7 @@
 				 */
 				p->activated = -1;
 			}
-			if (sync)
+			if (sync && (task_cpu(p) == smp_processor_id()))
 				__activate_task(p, rq);
 			else {
 				activate_task(p, rq);
diff -Nru a/lib/kobject.c b/lib/kobject.c
--- a/lib/kobject.c	Wed Dec 17 19:00:07 2003
+++ b/lib/kobject.c	Wed Dec 17 19:00:07 2003
@@ -236,8 +236,6 @@
 		list_del_init(&kobj->entry);
 		up_write(&kobj->kset->subsys->rwsem);
 	}
-	if (kobj->parent) 
-		kobject_put(kobj->parent);
 	kobject_put(kobj);
 }
 
@@ -274,9 +272,11 @@
 	kobj->parent = parent;
 
 	error = create_dir(kobj);
-	if (error)
+	if (error) {
 		unlink(kobj);
-	else {
+		if (parent)
+			kobject_put(parent);
+	} else {
 		/* If this kobj does not belong to a kset,
 		   try to find a parent that does. */
 		top_kobj = kobj;
@@ -452,6 +452,7 @@
 {
 	struct kobj_type * t = get_ktype(kobj);
 	struct kset * s = kobj->kset;
+	struct kobject * parent = kobj->parent;
 
 	pr_debug("kobject %s: cleaning up\n",kobject_name(kobj));
 	if (kobj->k_name != kobj->name)
@@ -461,6 +462,8 @@
 		t->release(kobj);
 	if (s)
 		kset_put(s);
+	if (parent) 
+		kobject_put(parent);
 }
 
 /**
diff -Nru a/mm/mmap.c b/mm/mmap.c
--- a/mm/mmap.c	Wed Dec 17 19:00:07 2003
+++ b/mm/mmap.c	Wed Dec 17 19:00:07 2003
@@ -19,6 +19,7 @@
 #include <linux/hugetlb.h>
 #include <linux/profile.h>
 #include <linux/module.h>
+#include <linux/mount.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
@@ -474,8 +475,13 @@
 	struct rb_node ** rb_link, * rb_parent;
 	unsigned long charged = 0;
 
-	if (file && (!file->f_op || !file->f_op->mmap))
-		return -ENODEV;
+	if (file) {
+		if (!file->f_op || !file->f_op->mmap)
+			return -ENODEV;
+
+		if ((prot & PROT_EXEC) && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
+			return -EPERM;
+	}
 
 	if (!len)
 		return addr;
diff -Nru a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
--- a/net/bridge/br_netfilter.c	Wed Dec 17 19:00:07 2003
+++ b/net/bridge/br_netfilter.c	Wed Dec 17 19:00:07 2003
@@ -180,7 +180,7 @@
 			struct rtable *rt;
 			struct flowi fl = { .nl_u = 
 			{ .ip4_u = { .daddr = iph->daddr, .saddr = 0 ,
-				     .tos = iph->tos} }, .proto = 0};
+				     .tos = RT_TOS(iph->tos)} }, .proto = 0};
 
 			if (!ip_route_output_key(&rt, &fl)) {
 				/* Bridged-and-DNAT'ed traffic doesn't
diff -Nru a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	Wed Dec 17 19:00:07 2003
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	Wed Dec 17 19:00:07 2003
@@ -53,7 +53,7 @@
 unsigned long ip_ct_tcp_timeout_syn_recv =     60 SECS;
 unsigned long ip_ct_tcp_timeout_established =   5 DAYS;
 unsigned long ip_ct_tcp_timeout_fin_wait =      2 MINS;
-unsigned long ip_ct_tcp_timeout_close_wait =    3 DAYS;
+unsigned long ip_ct_tcp_timeout_close_wait =   60 SECS;
 unsigned long ip_ct_tcp_timeout_last_ack =     30 SECS;
 unsigned long ip_ct_tcp_timeout_time_wait =     2 MINS;
 unsigned long ip_ct_tcp_timeout_close =        10 SECS;
diff -Nru a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c	Wed Dec 17 19:00:07 2003
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c	Wed Dec 17 19:00:07 2003
@@ -201,7 +201,8 @@
 	/* Local packets are never produced too large for their
 	   interface.  We degfragment them at LOCAL_OUT, however,
 	   so we have to refragment them here. */
-	if ((*pskb)->len > dst_pmtu(&rt->u.dst)) {
+	if ((*pskb)->len > dst_pmtu(&rt->u.dst) &&
+	    !skb_shinfo(*pskb)->tso_size) {
 		/* No hook can be after us, so this should be OK. */
 		ip_fragment(*pskb, okfn);
 		return NF_STOLEN;
diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c	Wed Dec 17 19:00:07 2003
+++ b/net/ipv4/tcp_ipv4.c	Wed Dec 17 19:00:07 2003
@@ -2356,6 +2356,7 @@
 static void *tcp_seq_start(struct seq_file *seq, loff_t *pos)
 {
 	struct tcp_iter_state* st = seq->private;
+	st->state = TCP_SEQ_STATE_LISTENING;
 	st->num = 0;
 	return *pos ? tcp_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
 }
diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
--- a/net/ipv6/tcp_ipv6.c	Wed Dec 17 19:00:07 2003
+++ b/net/ipv6/tcp_ipv6.c	Wed Dec 17 19:00:07 2003
@@ -222,7 +222,7 @@
 		write_lock(lock);
 	}
 
-	sk_add_node(sk, list);
+	__sk_add_node(sk, list);
 	sock_prot_inc_use(sk->sk_prot);
 	write_unlock(lock);
 }
diff -Nru a/net/ipv6/udp.c b/net/ipv6/udp.c
--- a/net/ipv6/udp.c	Wed Dec 17 19:00:07 2003
+++ b/net/ipv6/udp.c	Wed Dec 17 19:00:07 2003
@@ -825,7 +825,7 @@
 			struct sockaddr_in sin;
 			sin.sin_family = AF_INET;
 			sin.sin_port = sin6 ? sin6->sin6_port : inet->dport;
-			sin.sin_addr.s_addr = daddr->s6_addr[3];
+			sin.sin_addr.s_addr = daddr->s6_addr32[3];
 			msg->msg_name = &sin;
 			msg->msg_namelen = sizeof(sin);
 do_udp_sendmsg:
diff -Nru a/net/sched/sch_htb.c b/net/sched/sch_htb.c
--- a/net/sched/sch_htb.c	Wed Dec 17 19:00:07 2003
+++ b/net/sched/sch_htb.c	Wed Dec 17 19:00:07 2003
@@ -74,7 +74,7 @@
 #define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */
 #define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock)
 #define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock)
-#define HTB_VER 0x3000d	/* major must be matched with number suplied by TC as version */
+#define HTB_VER 0x3000e	/* major must be matched with number suplied by TC as version */
 
 #if HTB_VER >> 16 != TC_HTB_PROTOVER
 #error "Mismatched sch_htb.c and pkt_sch.h"
@@ -290,6 +290,11 @@
  * then finish and return direct queue.
  */
 #define HTB_DIRECT (struct htb_class*)-1
+static inline u32 htb_classid(struct htb_class *cl)
+{
+	return (cl && cl != HTB_DIRECT) ? cl->classid : TC_H_UNSPEC;
+}
+
 static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch)
 {
 	struct htb_sched *q = (struct htb_sched *)sch->data;
@@ -703,7 +708,7 @@
 
     sch->q.qlen++;
     sch->stats.packets++; sch->stats.bytes += skb->len;
-    HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",cl?cl->classid:0,skb);
+    HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",htb_classid(cl),skb);
     return NET_XMIT_SUCCESS;
 }
 
@@ -731,7 +736,7 @@
 	    htb_activate (q,cl);
 
     sch->q.qlen++;
-    HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",cl?cl->classid:0,skb);
+    HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",htb_classid(cl),skb);
     return NET_XMIT_SUCCESS;
 }
 
@@ -1381,11 +1386,16 @@
 #ifdef HTB_RATECM
 	del_timer_sync (&q->rttim);
 #endif
+	/* This line used to be after htb_destroy_class call below
+	   and surprisingly it worked in 2.4. But it must precede it 
+	   because filter need its target class alive to be able to call
+	   unbind_filter on it (without Oops). */
+	htb_destroy_filters(&q->filter_list);
+	
 	while (!list_empty(&q->root)) 
 		htb_destroy_class (sch,list_entry(q->root.next,
 					struct htb_class,sibling));
 
-	htb_destroy_filters(&q->filter_list);
 	__skb_queue_purge(&q->direct_queue);
 }
 
diff -Nru a/scripts/file2alias.c b/scripts/file2alias.c
--- a/scripts/file2alias.c	Wed Dec 17 19:00:07 2003
+++ b/scripts/file2alias.c	Wed Dec 17 19:00:07 2003
@@ -52,6 +52,13 @@
 	id->bcdDevice_lo = TO_NATIVE(id->bcdDevice_lo);
 	id->bcdDevice_hi = TO_NATIVE(id->bcdDevice_hi);
 
+	/*
+	 * Some modules (visor) have empty slots as placeholder for
+	 * run-time specification that results in catch-all alias
+	 */
+	if (!(id->idVendor | id->bDeviceClass | id->bInterfaceClass))
+		return 1;
+
 	strcpy(alias, "usb:");
 	ADD(alias, "v", id->match_flags&USB_DEVICE_ID_MATCH_VENDOR,
 	    id->idVendor);
