## Automatically generated incremental diff
## From:   linux-2.4.26-pre3
## To:     linux-2.4.26-pre4
## Robot:  $Id: make-incremental-diff,v 1.12 2004/01/06 07:19:36 hpa Exp $

diff -urN linux-2.4.26-pre3/Documentation/Configure.help linux-2.4.26-pre4/Documentation/Configure.help
--- linux-2.4.26-pre3/Documentation/Configure.help	2004-03-16 09:59:32.000000000 -0800
+++ linux-2.4.26-pre4/Documentation/Configure.help	2004-03-16 09:59:34.000000000 -0800
@@ -2085,6 +2085,40 @@
   If you choose to compile this as a module, the module will be called
   hptraid.o.
 
+CMD/Silicon Image Medley Software RAID
+CONFIG_BLK_DEV_ATARAID_MEDLEY
+  Say Y or M if you have a Silicon Image 3112 SATA RAID controller,
+  a CMD680 based controller, or another IDE RAID controller that uses
+  CMD's Medley software RAID, and want Linux to use the software RAID
+  feature of this card.  This driver uses /dev/ataraid/dXpY (X and Y
+  numbers) as device names.
+
+  This driver currently only supports RAID0 (striped) mode, so if you
+  are using RAID1 (mirroring) this will not work for you. In that
+  case, you may want to try the Silicon Image Medley Software RAID
+  driver (below).
+
+  Support for mirroring is planned in the future.
+
+  If you choose to compile this as a module, the module will be called
+  medley.o.
+
+Silicon Image Medley Software RAID (old driver)
+CONFIG_BLK_DEV_ATARAID_SII
+  Say Y or M if you have a Silicon Image SATARaid controller
+  and want Linux to use the softwareraid feature of this card.
+  This driver uses /dev/ataraid/dXpY (X and Y numbers) as device
+  names.
+
+  This driver does not reliably detect all Medley RAID sets, and could
+  be dangerous if you have a striped set with disks of different size.
+
+  You should use the new Medley RAID driver (above), unless you use
+  RAID1 (mirroring), which the new driver does not yet support.
+
+  If you choose to compile this as a module, the module will be called
+  silraid.o.
+
 Support for Acer PICA 1 chipset
 CONFIG_ACER_PICA_61
   This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
diff -urN linux-2.4.26-pre3/Makefile linux-2.4.26-pre4/Makefile
--- linux-2.4.26-pre3/Makefile	2004-03-16 09:59:33.000000000 -0800
+++ linux-2.4.26-pre4/Makefile	2004-03-16 09:59:36.000000000 -0800
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 26
-EXTRAVERSION = -pre3
+EXTRAVERSION = -pre4
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.26-pre3/arch/sparc64/defconfig linux-2.4.26-pre4/arch/sparc64/defconfig
--- linux-2.4.26-pre3/arch/sparc64/defconfig	2004-03-16 09:59:32.000000000 -0800
+++ linux-2.4.26-pre4/arch/sparc64/defconfig	2004-03-16 09:59:34.000000000 -0800
@@ -458,6 +458,7 @@
 CONFIG_BLK_DEV_ATARAID=m
 CONFIG_BLK_DEV_ATARAID_PDC=m
 CONFIG_BLK_DEV_ATARAID_HPT=m
+CONFIG_BLK_DEV_ATARAID_MEDLEY=m
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
diff -urN linux-2.4.26-pre3/arch/sparc64/mm/modutil.c linux-2.4.26-pre4/arch/sparc64/mm/modutil.c
--- linux-2.4.26-pre3/arch/sparc64/mm/modutil.c	2001-12-21 09:41:53.000000000 -0800
+++ linux-2.4.26-pre4/arch/sparc64/mm/modutil.c	2004-03-16 09:59:34.000000000 -0800
@@ -11,9 +11,9 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-static struct vm_struct * modvmlist = NULL;
+static struct vm_struct *modvmlist = NULL;
 
-void module_unmap (void * addr)
+void __module_unmap(void *addr, int free_area_pages)
 {
 	struct vm_struct **p, *tmp;
 
@@ -26,7 +26,9 @@
 	for (p = &modvmlist ; (tmp = *p) ; p = &tmp->next) {
 		if (tmp->addr == addr) {
 			*p = tmp->next;
-			vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size);
+			if (free_area_pages)
+				vmfree_area_pages(VMALLOC_VMADDR(tmp->addr),
+						  tmp->size);
 			kfree(tmp);
 			return;
 		}
@@ -34,13 +36,19 @@
 	printk("Trying to unmap nonexistent module vm area (%p)\n", addr);
 }
 
-void * module_map (unsigned long size)
+void module_unmap(void *addr)
+{
+	__module_unmap(addr, 1);
+}
+
+void *module_map (unsigned long size)
 {
 	void * addr;
 	struct vm_struct **p, *tmp, *area;
 
 	size = PAGE_ALIGN(size);
-	if (!size || size > MODULES_LEN) return NULL;
+	if (!size || size > MODULES_LEN)
+		return NULL;
 		
 	addr = (void *) MODULES_VADDR;
 	for (p = &modvmlist; (tmp = *p) ; p = &tmp->next) {
@@ -48,17 +56,19 @@
 			break;
 		addr = (void *) (tmp->size + (unsigned long) tmp->addr);
 	}
-	if ((unsigned long) addr + size >= MODULES_END) return NULL;
+	if ((unsigned long) addr + size >= MODULES_END)
+		return NULL;
 	
 	area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
-	if (!area) return NULL;
+	if (!area)
+		return NULL;
 	area->size = size + PAGE_SIZE;
 	area->addr = addr;
 	area->next = *p;
 	*p = area;
 
 	if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, GFP_KERNEL, PAGE_KERNEL)) {
-		module_unmap(addr);
+		__module_unmap(addr, 0);
 		return NULL;
 	}
 	return addr;
diff -urN linux-2.4.26-pre3/drivers/bluetooth/hci_usb.c linux-2.4.26-pre4/drivers/bluetooth/hci_usb.c
--- linux-2.4.26-pre3/drivers/bluetooth/hci_usb.c	2004-02-18 05:36:31.000000000 -0800
+++ linux-2.4.26-pre4/drivers/bluetooth/hci_usb.c	2004-03-16 09:59:35.000000000 -0800
@@ -30,7 +30,7 @@
  *
  * $Id: hci_usb.c,v 1.8 2002/07/18 17:23:09 maxk Exp $    
  */
-#define VERSION "2.4"
+#define VERSION "2.5"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -70,9 +70,6 @@
 static struct usb_driver hci_usb_driver; 
 
 static struct usb_device_id bluetooth_ids[] = {
-	/* Digianswer device */
-	{ USB_DEVICE(0x08fd, 0x0001), driver_info: HCI_DIGIANSWER },
-
 	/* Generic Bluetooth USB device */
 	{ USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
 
@@ -90,9 +87,15 @@
 
 MODULE_DEVICE_TABLE (usb, bluetooth_ids);
 
-static struct usb_device_id ignore_ids[] = {
+static struct usb_device_id blacklist_ids[] = {
 	/* Broadcom BCM2033 without firmware */
-	{ USB_DEVICE(0x0a5c, 0x2033) },
+	{ USB_DEVICE(0x0a5c, 0x2033), driver_info: HCI_IGNORE },
+
+	/* Broadcom BCM2035 */
+	{ USB_DEVICE(0x0a5c, 0x200a), driver_info: HCI_RESET },
+
+	/* Digianswer device */
+	{ USB_DEVICE(0x08fd, 0x0001), driver_info: HCI_DIGIANSWER },
 
 	{ }	/* Terminating entry */
 };
@@ -648,7 +651,7 @@
 #endif
 			}
 			BT_DBG("new packet len %d", len);
-				
+
 			skb = bluez_skb_alloc(len, GFP_ATOMIC);
 			if (!skb) {
 				BT_ERR("%s no memory for the packet", husb->hdev.name);
@@ -796,8 +799,14 @@
 
 	iface = &udev->actconfig->interface[0];
 
-	/* Check our black list */
-	if (usb_match_id(udev, iface, ignore_ids))
+	if (!id->driver_info) {
+		const struct usb_device_id *match;
+		match = usb_match_id(udev, iface, blacklist_ids);
+		if (match)
+			id = match;
+	}
+
+	if (id->driver_info & HCI_IGNORE)
 		return NULL;
 
 	/* Check number of endpoints */
@@ -921,6 +930,9 @@
 	hdev->send  = hci_usb_send_frame;
 	hdev->destruct = hci_usb_destruct;
 
+	if (id->driver_info & HCI_RESET)
+		set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
+
 	if (hci_register_dev(hdev) < 0) {
 		BT_ERR("Can't register HCI device");
 		goto probe_error;
@@ -983,6 +995,6 @@
 module_init(hci_usb_init);
 module_exit(hci_usb_cleanup);
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("BlueZ HCI USB driver ver " VERSION);
 MODULE_LICENSE("GPL");
diff -urN linux-2.4.26-pre3/drivers/bluetooth/hci_usb.h linux-2.4.26-pre4/drivers/bluetooth/hci_usb.h
--- linux-2.4.26-pre3/drivers/bluetooth/hci_usb.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.26-pre4/drivers/bluetooth/hci_usb.h	2004-03-16 09:59:35.000000000 -0800
@@ -37,7 +37,9 @@
 #define HCI_CTRL_REQ	     0x20
 #define HCI_DIGI_REQ	     0x40
 
-#define HCI_DIGIANSWER       0x01
+#define HCI_IGNORE           0x01
+#define HCI_RESET            0x02
+#define HCI_DIGIANSWER       0x04
 
 #define HCI_MAX_IFACE_NUM	3 
 
diff -urN linux-2.4.26-pre3/drivers/ide/Config.in linux-2.4.26-pre4/drivers/ide/Config.in
--- linux-2.4.26-pre3/drivers/ide/Config.in	2004-02-18 05:36:31.000000000 -0800
+++ linux-2.4.26-pre4/drivers/ide/Config.in	2004-03-16 09:59:35.000000000 -0800
@@ -190,6 +190,7 @@
 dep_tristate 'Support for IDE Raid controllers (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL
 dep_tristate '   Support Promise software RAID (Fasttrak(tm)) (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_PDC $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID
 dep_tristate '   Highpoint 370 software RAID (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_HPT $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID
+dep_tristate '   CMD/Silicon Image Medley Software RAID (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_MEDLEY $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID
 dep_tristate '   Silicon Image Medley software RAID (EXPERIMENTAL)' CONFIG_BLK_DEV_ATARAID_SII $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID
 
 endmenu
diff -urN linux-2.4.26-pre3/drivers/ide/Makefile linux-2.4.26-pre4/drivers/ide/Makefile
--- linux-2.4.26-pre3/drivers/ide/Makefile	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.26-pre4/drivers/ide/Makefile	2004-03-16 09:59:35.000000000 -0800
@@ -28,9 +28,13 @@
 
 # Core IDE code - must come before legacy
 
-ide-core-objs	:= ide-iops.o ide-taskfile.o ide.o ide-lib.o ide-io.o ide-default.o ide-proc.o ide-probe.o ide-geometry.o
+ide-core-objs	:= ide-iops.o ide-taskfile.o ide.o ide-lib.o ide-io.o \
+		   ide-default.o ide-probe.o ide-geometry.o
 ide-detect-objs	:= ide-probe-mini.o
 
+ifeq ($(CONFIG_PROC_FS),y)
+ide-core-objs	+= ide-proc.o
+endif
 ifeq ($(CONFIG_BLK_DEV_IDEPCI),y)
 ide-core-objs += setup-pci.o
 endif
diff -urN linux-2.4.26-pre3/drivers/ide/pci/amd74xx.c linux-2.4.26-pre4/drivers/ide/pci/amd74xx.c
--- linux-2.4.26-pre3/drivers/ide/pci/amd74xx.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.26-pre4/drivers/ide/pci/amd74xx.c	2004-03-16 09:59:35.000000000 -0800
@@ -1,7 +1,7 @@
 /*
- * Version 2.10
+ * Version 2.13
  *
- * AMD 755/756/766/8111 and nVidia nForce IDE driver for Linux.
+ * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s IDE driver for Linux.
  *
  * Copyright (c) 2000-2002 Vojtech Pavlik
  *
@@ -40,9 +40,11 @@
 #define AMD_UDMA_33		0x01
 #define AMD_UDMA_66		0x02
 #define AMD_UDMA_100		0x03
+#define AMD_UDMA_133		0x04
 #define AMD_CHECK_SWDMA		0x08
 #define AMD_BAD_SWDMA		0x10
 #define AMD_BAD_FIFO		0x20
+#define AMD_CHECK_SERENADE	0x40
 
 /*
  * AMD SouthBridge chips.
@@ -50,29 +52,32 @@
 
 static struct amd_ide_chip {
 	unsigned short id;
-	unsigned char rev;
 	unsigned long base;
 	unsigned char flags;
 } amd_ide_chips[] = {
-	{ PCI_DEVICE_ID_AMD_COBRA_7401, 0x00, 0x40, AMD_UDMA_33 | AMD_BAD_SWDMA },	/* AMD-755 Cobra */
-	{ PCI_DEVICE_ID_AMD_VIPER_7409, 0x00, 0x40, AMD_UDMA_66 | AMD_CHECK_SWDMA },	/* AMD-756 Viper */
-	{ PCI_DEVICE_ID_AMD_VIPER_7411, 0x00, 0x40, AMD_UDMA_100 | AMD_BAD_FIFO },	/* AMD-766 Viper */
-	{ PCI_DEVICE_ID_AMD_OPUS_7441, 0x00, 0x40, AMD_UDMA_100 },			/* AMD-768 Opus */
-	{ PCI_DEVICE_ID_AMD_8111_IDE,  0x00, 0x40, AMD_UDMA_100 },			/* AMD-8111 */
-        { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x00, 0x50, AMD_UDMA_100 },                  /* nVidia nForce */
-        { PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, 0x00, 0x50, AMD_UDMA_100 },                  /* nVidia nForce */
-
+	{ PCI_DEVICE_ID_AMD_COBRA_7401,		0x40, AMD_UDMA_33 | AMD_BAD_SWDMA },
+	{ PCI_DEVICE_ID_AMD_VIPER_7409,		0x40, AMD_UDMA_66 | AMD_CHECK_SWDMA },
+	{ PCI_DEVICE_ID_AMD_VIPER_7411,		0x40, AMD_UDMA_100 | AMD_BAD_FIFO },
+	{ PCI_DEVICE_ID_AMD_OPUS_7441,		0x40, AMD_UDMA_100 },
+	{ PCI_DEVICE_ID_AMD_8111_IDE,		0x40, AMD_UDMA_133 | AMD_CHECK_SERENADE },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE_IDE,	0x50, AMD_UDMA_100 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,	0x50, AMD_UDMA_133 },
 	{ 0 }
 };
 
 static struct amd_ide_chip *amd_config;
-static unsigned char amd_enabled;
+static ide_pci_device_t *amd_chipset;
 static unsigned int amd_80w;
 static unsigned int amd_clock;
 
-static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3 };
-static unsigned char amd_udma2cyc[] = { 4, 6, 8, 10, 3, 2, 1, 1 };
-static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100" };
+static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
+static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 };
 
 /*
  * AMD /proc entry.
@@ -83,6 +88,7 @@
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
 
+static unsigned char amd_udma2cyc[] = { 4, 6, 8, 10, 3, 2, 1, 15 };
 static unsigned long amd_base;
 static struct pci_dev *bmide_dev;
 extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
@@ -104,7 +110,7 @@
 
 	amd_print("----------AMD BusMastering IDE Configuration----------------");
 
-	amd_print("Driver Version:                     2.10");
+	amd_print("Driver Version:                     2.13");
 	amd_print("South Bridge:                       %s", bmide_dev->name);
 
 	pci_read_config_byte(dev, PCI_REVISION_ID, &t);
@@ -155,6 +161,12 @@
 			continue;
 		}
 
+		if (den[i] && uen[i] && udma[i] == 15) {
+			speed[i] = amd_clock * 4;
+			cycle[i] = 500000 / amd_clock;
+			continue;
+		}
+
 		speed[i] = 4 * amd_clock / ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2);
 		cycle[i] = 1000000 * ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2) / amd_clock / 2;
 	}
@@ -200,6 +212,7 @@
 		case AMD_UDMA_33:  t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
 		case AMD_UDMA_66:  t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break;
 		case AMD_UDMA_100: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break;
+		case AMD_UDMA_133: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 15)]) : 0x03; break;
 		default: return;
 	}
 
@@ -234,6 +247,7 @@
 	}
 
 	if (speed == XFER_UDMA_5 && amd_clock <= 33333) t.udma = 1;
+	if (speed == XFER_UDMA_6 && amd_clock <= 33333) t.udma = 15;
 
 	amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t);
 
@@ -251,9 +265,6 @@
 
 static void amd74xx_tune_drive(ide_drive_t *drive, u8 pio)
 {
-	if (!((amd_enabled >> HWIF(drive)->channel) & 1))
-		return;
-
 	if (pio == 255) {
 		amd_set_drive(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO));
 		return;
@@ -276,7 +287,8 @@
 		XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA |
 		((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) |
 		(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) |
-		(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0));
+		(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0) |
+		(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_133 ? XFER_UDMA_133 : 0));
 
 	amd_set_drive(drive, speed);
 
@@ -312,13 +324,15 @@
 
 	switch (amd_config->flags & AMD_UDMA) {
 
+		case AMD_UDMA_133:
 		case AMD_UDMA_100:
 			pci_read_config_byte(dev, AMD_CABLE_DETECT, &t);
 			pci_read_config_dword(dev, AMD_UDMA_TIMING, &u);
 			amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 0xc) ? 2 : 0);
 			for (i = 24; i >= 0; i -= 8)
 				if (((u >> i) & 4) && !(amd_80w & (1 << (1 - (i >> 4))))) {
-					printk(KERN_WARNING "AMD_IDE: Bios didn't set cable bits corectly. Enabling workaround.\n");
+					printk(KERN_WARNING "%s: BIOS didn't set cable bits correctly. Enabling workaround.\n",
+						amd_chipset->name);
 					amd_80w |= (1 << (1 - (i >> 4)));
 				}
 			break;
@@ -331,9 +345,6 @@
 			break;
 	}
 
-	pci_read_config_dword(dev, AMD_IDE_ENABLE, &u);
-	amd_enabled = ((u & 1) ? 2 : 0) | ((u & 2) ? 1 : 0);
-
 /*
  * Take care of prefetch & postwrite.
  */
@@ -343,6 +354,15 @@
 		(amd_config->flags & AMD_BAD_FIFO) ? (t & 0x0f) : (t | 0xf0));
 
 /*
+ * Take care of incorrectly wired Serenade mainboards.
+ */
+
+	if ((amd_config->flags & AMD_CHECK_SERENADE) &&
+		dev->subsystem_vendor == PCI_VENDOR_ID_AMD &&
+		dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE)
+			amd_config->flags = AMD_UDMA_100;
+
+/*
  * Determine the system bus clock.
  */
 
@@ -355,8 +375,10 @@
 	}
 
 	if (amd_clock < 20000 || amd_clock > 50000) {
-		printk(KERN_WARNING "AMD_IDE: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", amd_clock);
-		printk(KERN_WARNING "AMD_IDE: Use ide0=ata66 if you want to assume 80-wire cable\n");
+		printk(KERN_WARNING "%s: User given PCI clock speed impossible (%d), using 33 MHz instead.\n",
+			amd_chipset->name, amd_clock);
+		printk(KERN_WARNING "%s: Use ide0=ata66 if you want to assume 80-wire cable\n",
+			amd_chipset->name);
 		amd_clock = 33333;
 	}
 
@@ -365,8 +387,8 @@
  */
 
 	pci_read_config_byte(dev, PCI_REVISION_ID, &t);
-	printk(KERN_INFO "AMD_IDE: %s (rev %02x) %s controller on pci%s\n",
-		dev->name, t, amd_dma[amd_config->flags & AMD_UDMA], dev->slot_name);
+	printk(KERN_INFO "%s: %s (rev %02x) %s controller\n",
+		amd_chipset->name, pci_name(dev), t, amd_dma[amd_config->flags & AMD_UDMA]);
 
 /*
  * Register /proc/ide/amd74xx entry
@@ -381,13 +403,7 @@
         }
 #endif /* DISPLAY_AMD_TIMINGS && CONFIG_PROC_FS */
 
-
-	return 0;
-}
-
-static unsigned int __init ata66_amd74xx(ide_hwif_t *hwif)
-{
-	return ((amd_enabled & amd_80w) >> hwif->channel) & 1;
+	return dev->irq;
 }
 
 static void __init init_hwif_amd74xx(ide_hwif_t *hwif)
@@ -414,8 +430,8 @@
         hwif->mwdma_mask = 0x07;
         hwif->swdma_mask = 0x07;
 
-        if (!(hwif->udma_four))
-                hwif->udma_four = ((amd_enabled & amd_80w) >> hwif->channel) & 1;
+	if (!hwif->udma_four)
+		hwif->udma_four = (amd_80w >> hwif->channel) & 1;
         hwif->ide_dma_check = &amd74xx_ide_dma_check;
         if (!noautodma)
                 hwif->autodma = 1;
@@ -423,37 +439,31 @@
         hwif->drives[1].autodma = hwif->autodma;
 }
 
-/*
- * We allow the BM-DMA driver only work on enabled interfaces.
- */
-
-static void __init init_dma_amd74xx(ide_hwif_t *hwif, unsigned long dmabase)
-{
-	if ((amd_enabled >> hwif->channel) & 1)
-		ide_setup_dma(hwif, dmabase, 8);
-}
-
-extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
-
 static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_pci_device_t *d = amd74xx_chipsets + id->driver_data;
+	amd_chipset = amd74xx_chipsets + id->driver_data;
 	amd_config = amd_ide_chips + id->driver_data;
-	if (dev->device != d->device) BUG();
+	if (dev->device != amd_chipset->device) BUG();
 	if (dev->device != amd_config->id) BUG();
-	ide_setup_pci_device(dev, d);
+	ide_setup_pci_device(dev, amd_chipset);
 	MOD_INC_USE_COUNT;
 	return 0;
 }
 
 static struct pci_device_id amd74xx_pci_tbl[] __devinitdata = {
-	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
-	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
-	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, 	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
+	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_COBRA_7401,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  0 },
+	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_VIPER_7409,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  1 },
+	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_VIPER_7411,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  2 },
+	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_OPUS_7441,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  3 },
+	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8111_IDE,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  4 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  5 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  6 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  7 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  8 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  9 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
 	{ 0, },
 };
 
diff -urN linux-2.4.26-pre3/drivers/ide/pci/amd74xx.h linux-2.4.26-pre4/drivers/ide/pci/amd74xx.h
--- linux-2.4.26-pre3/drivers/ide/pci/amd74xx.h	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.26-pre4/drivers/ide/pci/amd74xx.h	2004-03-16 09:59:35.000000000 -0800
@@ -27,7 +27,6 @@
 
 static unsigned int init_chipset_amd74xx(struct pci_dev *, const char *);
 static void init_hwif_amd74xx(ide_hwif_t *);
-static void init_dma_amd74xx(ide_hwif_t *, unsigned long);
 
 static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
 	{	/* 0 */
@@ -35,9 +34,7 @@
 		.device		= PCI_DEVICE_ID_AMD_COBRA_7401,
 		.name		= "AMD7401",
 		.init_chipset	= init_chipset_amd74xx,
-		.init_iops	= NULL,
 		.init_hwif	= init_hwif_amd74xx,
-		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
@@ -48,9 +45,7 @@
 		.device		= PCI_DEVICE_ID_AMD_VIPER_7409,
 		.name		= "AMD7409",
 		.init_chipset	= init_chipset_amd74xx,
-		.init_iops	= NULL,
 		.init_hwif	= init_hwif_amd74xx,
-		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
@@ -61,9 +56,7 @@
 		.device		= PCI_DEVICE_ID_AMD_VIPER_7411,
 		.name		= "AMD7411",
 		.init_chipset	= init_chipset_amd74xx,
-		.init_iops	= NULL,
 		.init_hwif	= init_hwif_amd74xx,
-		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
@@ -74,9 +67,7 @@
 		.device		= PCI_DEVICE_ID_AMD_OPUS_7441,
 		.name		= "AMD7441",
 		.init_chipset	= init_chipset_amd74xx,
-		.init_iops	= NULL,
 		.init_hwif	= init_hwif_amd74xx,
-		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
@@ -87,9 +78,7 @@
 		.device		= PCI_DEVICE_ID_AMD_8111_IDE,
 		.name		= "AMD8111",
 		.init_chipset	= init_chipset_amd74xx,
-		.init_iops	= NULL,
 		.init_hwif	= init_hwif_amd74xx,
-		.init_dma	= init_dma_amd74xx,
 		.autodma	= AUTODMA,
 		.channels	= 2,
 		.enablebits	= {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
@@ -101,9 +90,7 @@
 		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE_IDE,
 		.name		= "NFORCE",
 		.init_chipset	= init_chipset_amd74xx,
-		.init_iops	= NULL,
 		.init_hwif	= init_hwif_amd74xx,
-		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
@@ -115,15 +102,79 @@
 		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE,
 		.name		= "NFORCE2",
 		.init_chipset	= init_chipset_amd74xx,
-		.init_iops	= NULL,
 		.init_hwif	= init_hwif_amd74xx,
-		.init_dma	= init_dma_amd74xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
 		.bootable	= ON_BOARD,
 		.extra		= 0,
 	},
+	{	/* 7 */
+		.vendor		= PCI_VENDOR_ID_NVIDIA,
+		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE,
+		.name		= "NFORCE2S",
+		.init_chipset	= init_chipset_amd74xx,
+		.init_hwif	= init_hwif_amd74xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+		.bootable	= ON_BOARD,
+	},
+	{	/* 8 */
+		.vendor		= PCI_VENDOR_ID_NVIDIA,
+		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,
+		.name		= "NFORCE2S-SATA",
+		.init_chipset	= init_chipset_amd74xx,
+		.init_hwif	= init_hwif_amd74xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+		.bootable	= ON_BOARD,
+	},
+	{	/* 9 */
+		.vendor		= PCI_VENDOR_ID_NVIDIA,
+		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE,
+		.name		= "NFORCE3",
+		.init_chipset	= init_chipset_amd74xx,
+		.init_hwif	= init_hwif_amd74xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+		.bootable	= ON_BOARD,
+	},
+	{	/* 10 */
+		.vendor		= PCI_VENDOR_ID_NVIDIA,
+		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE,
+		.name		= "NFORCE3S",
+		.init_chipset	= init_chipset_amd74xx,
+		.init_hwif	= init_hwif_amd74xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+		.bootable	= ON_BOARD,
+	},
+	{	/* 11 */
+		.vendor		= PCI_VENDOR_ID_NVIDIA,
+		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,
+		.name		= "NFORCE3S-SATA",
+		.init_chipset	= init_chipset_amd74xx,
+		.init_hwif	= init_hwif_amd74xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+		.bootable	= ON_BOARD,
+	},
+	{	/* 12 */
+		.vendor		= PCI_VENDOR_ID_NVIDIA,
+		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,
+		.name		= "NFORCE3S-SATA2",
+		.init_chipset	= init_chipset_amd74xx,
+		.init_hwif	= init_hwif_amd74xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+		.bootable	= ON_BOARD,
+	},
 	{
 		.vendor		= 0,
 		.device		= 0,
diff -urN linux-2.4.26-pre3/drivers/ide/raid/Makefile linux-2.4.26-pre4/drivers/ide/raid/Makefile
--- linux-2.4.26-pre3/drivers/ide/raid/Makefile	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.26-pre4/drivers/ide/raid/Makefile	2004-03-16 09:59:35.000000000 -0800
@@ -12,6 +12,7 @@
 obj-$(CONFIG_BLK_DEV_ATARAID)		+= ataraid.o
 obj-$(CONFIG_BLK_DEV_ATARAID_PDC)	+= pdcraid.o
 obj-$(CONFIG_BLK_DEV_ATARAID_HPT)	+= hptraid.o
+obj-$(CONFIG_BLK_DEV_ATARAID_MEDLEY)	+= medley.o
 obj-$(CONFIG_BLK_DEV_ATARAID_SII)	+= silraid.o
 
 EXTRA_CFLAGS	:= -I../
diff -urN linux-2.4.26-pre3/drivers/ide/raid/medley.c linux-2.4.26-pre4/drivers/ide/raid/medley.c
--- linux-2.4.26-pre3/drivers/ide/raid/medley.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.26-pre4/drivers/ide/raid/medley.c	2004-03-16 09:59:35.000000000 -0800
@@ -0,0 +1,752 @@
+/*
+ * MEDLEY SOFTWARE RAID DRIVER (Silicon Image 3112 and others)
+ *
+ * Copyright (C) 2003 Thomas Horsten <thomas@horsten.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA
+ * Copyright (C) 2003 Thomas Horsten <thomas@horsten.com>
+ * All Rights Reserved.
+ *
+ * This driver uses the ATA RAID driver framework and is based on
+ * code from Arjan van de Ven's silraid.c and hptraid.c.
+ *
+ * It is a driver for the Medley software RAID, which is used by
+ * some IDE controllers, including the Silicon Image 3112 SATA
+ * controller found onboard many modern motherboards, and the
+ * CMD680 stand-alone PCI RAID controller.
+ *
+ * The author has only tested this on the Silicon Image SiI3112.
+ * If you have any luck using more than 2 drives, and/or more
+ * than one RAID set, and/or any other chip than the SiI3112,
+ * please let me know by sending me mail at the above address.
+ *
+ * Currently, only striped mode is supported for these RAIDs.
+ *
+ * You are welcome to contact me if you have any questions or
+ * suggestions for improvement.
+ *
+ * Change history:
+ *
+ * 20040310 - thomas@horsten.com
+ *   Removed C99 style variable declarations that confused gcc-2.x
+ *   Fixed a bug where more than one RAID set would not be detected correctly
+ *   General cleanup for submission to kernel
+ *
+ * 20031012 - thomas@horsten.com
+ *   Added support for BLKRRPART ioctl to re-read partition table
+ *
+ * 20030801 - thomas@horsten.com
+ *   First test release
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
+#include <linux/blkdev.h>
+#include <linux/blkpg.h>
+#include <linux/genhd.h>
+#include <linux/ioctl.h>
+
+#include <linux/ide.h>
+#include <asm/uaccess.h>
+
+#include "ataraid.h"
+
+/*
+ * These options can be tuned if the need should occur.
+ *
+ * Even better, this driver could be changed to allocate the structures
+ * dynamically.
+ */
+#define MAX_DRIVES_PER_SET 8
+#define MAX_MEDLEY_ARRAYS 4
+
+/*
+ * Set to 1 only if you are debugging the driver, or if it doesn't work
+ * the way you expect and you want to to report it.
+ *
+ * This will produce lots of kernel messages, some of which might
+ * help me figure out what is going wrong).
+ */
+#define DEBUGGING_MEDLEY 0
+
+#if DEBUGGING_MEDLEY
+#define dprintk(fmt, args...) printk(fmt, ##args)
+#else
+#define dprintk(fmt, args...)
+#endif
+
+/*
+ * Medley RAID metadata structure.
+ *
+ * The metadata structure is based on the ATA drive ID from the drive itself,
+ * with the RAID information in the vendor specific regions.
+ *
+ * We do not use all the fields, since we only support Striped Sets.
+ */
+struct medley_metadata {
+	u8  driveid0[46];
+	u8  ascii_version[8];
+	u8  driveid1[52];
+	u32 total_sectors_low;
+	u32 total_sectors_high;
+	u16 reserved0;
+	u8  driveid2[142];
+	u16 product_id;
+	u16 vendor_id;
+	u16 minor_ver;
+	u16 major_ver;
+	u16 creation_timestamp[3];
+	u16 chunk_size;
+	u16 reserved1;
+	u8  drive_number;
+	u8  raid_type;
+	u8  drives_per_striped_set;
+	u8  striped_set_number;
+	u8  drives_per_mirrored_set;
+	u8  mirrored_set_number;
+	u32 rebuild_ptr_low;
+	u32 rebuild_ptr_high;
+	u32 incarnation_no;
+	u8  member_status;
+	u8  mirrored_set_state;
+	u8  reported_device_location;
+	u8  member_location;
+	u8  auto_rebuild;
+	u8  reserved3[17];
+	u16 checksum;
+};
+
+/*
+ * This struct holds the information about a Medley array
+ */
+struct medley_array {
+	u8       drives;
+	u16      chunk_size;
+	u32      sectors_per_row;
+	u8       chunk_size_log;
+	u16      present;
+	u16      timestamp[3];
+	u32      sectors;
+	int      registered;
+	atomic_t valid;
+	int      access;
+
+	kdev_t   members[MAX_DRIVES_PER_SET];
+	struct   block_device *bdev[MAX_DRIVES_PER_SET];
+};
+
+static struct medley_array raid[MAX_MEDLEY_ARRAYS];
+
+/*
+ * Here we keep the offset of the ATARAID device ID's compared to our
+ * own (this will normally be 0, unless another ATARAID driver has
+ * registered some arrays before us).
+ */
+static int medley_devid_offset = 0;
+
+/*
+ * This holds the number of detected arrays.
+ */
+static int medley_arrays = 0;
+
+/*
+ * Wait queue for opening device (used when re-reading partition table)
+ */
+static DECLARE_WAIT_QUEUE_HEAD(medley_wait_open);
+
+/*
+ * The interface functions used by the ataraid framework.
+ */
+static int medley_open(struct inode *inode, struct file *filp);
+static int medley_release(struct inode *inode, struct file *filp);
+static int medley_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg);
+static int medley_make_request(request_queue_t * q, int rw,
+			       struct buffer_head *bh);
+
+static struct raid_device_operations medley_ops = {
+	open:         medley_open,
+	release:      medley_release,
+	ioctl:        medley_ioctl,
+	make_request: medley_make_request
+};
+
+/*
+ * This is the list of devices to probe.
+ */
+static const kdev_t probelist[] = {
+	MKDEV(IDE0_MAJOR, 0),
+	MKDEV(IDE0_MAJOR, 64),
+	MKDEV(IDE1_MAJOR, 0),
+	MKDEV(IDE1_MAJOR, 64),
+	MKDEV(IDE2_MAJOR, 0),
+	MKDEV(IDE2_MAJOR, 64),
+	MKDEV(IDE3_MAJOR, 0),
+	MKDEV(IDE3_MAJOR, 64),
+	MKDEV(IDE4_MAJOR, 0),
+	MKDEV(IDE4_MAJOR, 64),
+	MKDEV(IDE5_MAJOR, 0),
+	MKDEV(IDE5_MAJOR, 64),
+	MKDEV(IDE6_MAJOR, 0),
+	MKDEV(IDE6_MAJOR, 64),
+	MKDEV(0, 0)
+};
+
+/*
+ * Handler for ioctl calls to the virtual device
+ */
+static int medley_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	unsigned int minor;
+	unsigned long sectors;
+	int devminor = (inode->i_rdev >> SHIFT) & MAJOR_MASK;
+	int device = devminor - medley_devid_offset;
+	int partition;
+
+	dprintk("medley_ioctl\n");
+
+	minor = MINOR(inode->i_rdev) >> SHIFT;
+
+	switch (cmd) {
+
+	case BLKGETSIZE:	/* Return device size */
+		if (!arg)
+			return -EINVAL;
+		sectors =
+		    ataraid_gendisk.part[MINOR(inode->i_rdev)].nr_sects;
+		dprintk("medley_ioctl: BLKGETSIZE\n");
+		if (MINOR(inode->i_rdev) & 15)
+			return put_user(sectors, (unsigned long *) arg);
+		return put_user(raid[minor - medley_devid_offset].sectors,
+				(unsigned long *) arg);
+		break;
+
+	case HDIO_GETGEO: {
+			struct hd_geometry *loc =
+			    (struct hd_geometry *) arg;
+			unsigned short bios_cyl = (unsigned short)
+			    (raid[minor].sectors / 255 / 63);	/* truncate */
+
+			dprintk("medley_ioctl: HDIO_GETGEO\n");
+			if (!loc)
+				return -EINVAL;
+			if (put_user(255, (byte *) & loc->heads))
+				return -EFAULT;
+			if (put_user(63, (byte *) & loc->sectors))
+				return -EFAULT;
+			if (put_user
+			    (bios_cyl, (unsigned short *) &loc->cylinders))
+				return -EFAULT;
+			if (put_user
+			    ((unsigned) ataraid_gendisk.
+			     part[MINOR(inode->i_rdev)].start_sect,
+			     (unsigned long *) &loc->start))
+				return -EFAULT;
+			return 0;
+		}
+
+	case HDIO_GETGEO_BIG: {
+			struct hd_big_geometry *loc =
+			    (struct hd_big_geometry *) arg;
+
+			dprintk("medley_ioctl: HDIO_GETGEO_BIG\n");
+			if (!loc)
+				return -EINVAL;
+			if (put_user(255, (byte *) & loc->heads))
+				return -EFAULT;
+			if (put_user(63, (byte *) & loc->sectors))
+				return -EFAULT;
+			if (put_user
+			    (raid[minor - medley_devid_offset].sectors /
+			     255 / 63, (unsigned int *) &loc->cylinders))
+				return -EFAULT;
+			if (put_user
+			    ((unsigned) ataraid_gendisk.
+			     part[MINOR(inode->i_rdev)].start_sect,
+			     (unsigned long *) &loc->start))
+				return -EFAULT;
+			return 0;
+		}
+
+	case BLKROSET:
+	case BLKROGET:
+	case BLKSSZGET:
+		dprintk("medley_ioctl: BLK*\n");
+		return blk_ioctl(inode->i_rdev, cmd, arg);
+
+	case BLKRRPART:	/* Re-read partition tables */
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
+		if (minor != 0)
+			return -EINVAL;
+		if (atomic_read(&(raid[device].valid)) == 0)
+			return -EINVAL;
+
+		atomic_set(&(raid[device].valid), 0);
+		if (raid[device].access != 1) {
+			atomic_set(&(raid[device].valid), 1);
+			return -EBUSY;
+		}
+
+		for (partition = 15; partition >= 0; partition--) {
+			invalidate_device(MKDEV(ATARAID_MAJOR,
+						partition + devminor), 1);
+			ataraid_gendisk.part[partition +
+					     devminor].start_sect = 0;
+			ataraid_gendisk.part[partition +
+					     devminor].nr_sects = 0;
+		}
+		ataraid_register_disk(device, raid[device].sectors);
+		atomic_set(&(raid[device].valid), 1);
+		wake_up(&medley_wait_open);
+		return 0;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * Handler to map a request to the real device.
+ * If the request cannot be made because it spans multiple disks,
+ * we return -1, otherwise we modify the request and return 1.
+ */
+static int medley_make_request(request_queue_t * q, int rw,
+			       struct buffer_head *bh)
+{
+	u8 disk;
+	u32 rsect = bh->b_rsector;
+	int device =
+	    ((bh->b_rdev >> SHIFT) & MAJOR_MASK) - medley_devid_offset;
+	struct medley_array *r = raid + device;
+
+	/* Add the partition offset */
+	rsect = rsect + ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect;
+
+	dprintk("medley_make_request, rsect=%ul\n", rsect);
+
+	/* Detect if the request crosses a chunk barrier */
+	if (r->chunk_size_log) {
+		if (((rsect & (r->chunk_size - 1)) +
+		     (bh->b_size / 512)) > (1 << r->chunk_size_log)) {
+			return -1;
+		}
+	} else {
+		if ((rsect / r->chunk_size) !=
+		    ((rsect + (bh->b_size / 512) - 1) / r->chunk_size)) {
+			return -1;
+		}
+	}
+
+	/*
+	 * Medley arrays are simple enough, since the smallest disk decides the
+	 * number of sectors used per disk. So there is no need for the cutoff
+	 * magic found in other drivers like hptraid.
+	 */
+	if (r->chunk_size_log) {
+		/* We save some expensive operations (1 div, 1 mul, 1 mod),
+		 * if the chunk size is a power of 2, which is true in most
+		 * cases (at least with my version of the RAID BIOS).
+		 */
+		disk = (rsect >> r->chunk_size_log) % r->drives;
+		rsect = ((rsect / r->sectors_per_row) <<
+			 r->chunk_size_log) + (rsect & (r->chunk_size -
+							1));
+	} else {
+		disk = (rsect / r->chunk_size) % r->drives;
+		rsect = rsect / r->sectors_per_row * r->chunk_size +
+		    rsect % r->chunk_size;
+	}
+
+	dprintk("medley_make_request :-), disk=%d, rsect=%ul\n", disk,
+		rsect);
+	bh->b_rdev = r->members[disk];
+	bh->b_rsector = rsect;
+	return 1;
+}
+
+/*
+ * Find out which array a drive belongs to, and add it to that array.
+ * If it is not a member of a detected array, add a new array for it.
+ */
+void medley_add_raiddrive(kdev_t dev, struct medley_metadata *md)
+{
+	int c;
+
+	dprintk("Candidate drive %02x:%02x - drive %d of %d, stride %d, "
+		"sectors %ul (%d MB)\n",
+		MAJOR(dev), MINOR(dev), md->drive_number,
+		md->drives_per_striped_set, md->chunk_size,
+		md->total_sectors_low,
+		md->total_sectors_low / 1024 / 1024 / 2);
+
+	for (c = 0; c < medley_arrays; c++) {
+		if ((raid[c].timestamp[0] == md->creation_timestamp[0]) &&
+		    (raid[c].timestamp[1] == md->creation_timestamp[1]) &&
+		    (raid[c].timestamp[2] == md->creation_timestamp[2]) &&
+		    (raid[c].drives == md->drives_per_striped_set) &&
+		    (raid[c].chunk_size == md->chunk_size) &&
+		    ((raid[c].present & (1 << md->drive_number)) == 0)) {
+			dprintk("Existing array %d\n", c);
+			raid[c].present |= (1 << md->drive_number);
+			raid[c].members[md->drive_number] = dev;
+			break;
+		}
+	}
+	if (c == medley_arrays) {
+		dprintk("New array %d\n", medley_arrays);
+		if (medley_arrays == MAX_MEDLEY_ARRAYS) {
+			printk(KERN_ERR "Medley RAID: "
+			       "Too many RAID sets detected - you can change "
+			       "the max in the driver.\n");
+		} else {
+			raid[c].timestamp[0] = md->creation_timestamp[0];
+			raid[c].timestamp[1] = md->creation_timestamp[1];
+			raid[c].timestamp[2] = md->creation_timestamp[2];
+			raid[c].drives = md->drives_per_striped_set;
+			raid[c].chunk_size = md->chunk_size;
+			raid[c].sectors_per_row = md->chunk_size *
+			    md->drives_per_striped_set;
+
+			/* Speedup if chunk size is a power of 2 */
+			if (((raid[c].chunk_size - 1) &
+			     (raid[c].chunk_size)) == 0) {
+				raid[c].chunk_size_log =
+				    ffs(raid[c].chunk_size) - 1;
+			} else {
+				raid[c].chunk_size_log = 0;
+			}
+			raid[c].present = (1 << md->drive_number);
+			raid[c].members[md->drive_number] = dev;
+			if (md->major_ver == 1) {
+				raid[c].sectors = ((u32 *) (md))[27];
+			} else {
+				raid[c].sectors = md->total_sectors_low;
+			}
+			medley_arrays++;
+		}
+	}
+}
+
+/*
+ * Read the Medley metadata from a drive.
+ * Returns the bh if it was found, otherwise NULL.
+ */
+struct buffer_head *medley_get_metadata(kdev_t dev)
+{
+	struct buffer_head *bh = NULL;
+	struct pci_dev *pcidev;
+	u32 lba;
+	int pos;
+	struct medley_metadata *md;
+
+	ide_drive_t *drvinfo = ide_info_ptr(dev, 0);
+	if ((drvinfo == NULL) || drvinfo->capacity < 1) {
+		return NULL;
+	}
+
+	dprintk("Probing %02x:%02x\n", MAJOR(dev), MINOR(dev));
+
+	/* If this drive is not on a PCI controller, it is not Medley RAID.
+	 * Medley matches the PCI device ID with the metadata to check if
+	 * it is valid. Unfortunately it is the only reliable way to identify
+	 * the superblock */
+	pcidev = drvinfo->hwif ? drvinfo->hwif->pci_dev : NULL;
+	if (!pcidev) {
+		return NULL;
+	}
+
+	/*
+	 * 4 copies of the metadata exist, in the following 4 sectors:
+	 * last, last-0x200, last-0x400, last-0x600.
+	 *
+	 * We must try each of these in order, until we find the metadata.
+	 * FIXME: This does not take into account drives with 48/64-bit LBA
+	 * addressing, even though the Medley RAID version 2 supports these.
+	 */
+	lba = drvinfo->capacity - 1;
+	for (pos = 0; pos < 4; pos++, lba -= 0x200) {
+		bh = bread(dev, lba, 512);
+		if (!bh) {
+			printk(KERN_ERR "Medley RAID (%02x:%02x): "
+			       "Error reading metadata (lba=%d)\n",
+			       MAJOR(dev), MINOR(dev), lba);
+			break;
+		}
+
+		/* A valid Medley RAID has the PCI vendor/device ID of its
+		 * IDE controller, and the correct checksum. */
+		md = (void *) (bh->b_data);
+
+		if (pcidev->vendor == md->vendor_id &&
+		    pcidev->device == md->product_id) {
+			u16 checksum = 0;
+			u16 *p = (void *) (bh->b_data);
+			int c;
+			for (c = 0; c < 160; c++) {
+				checksum += *p++;
+			}
+			dprintk
+			    ("Probing %02x:%02x csum=%d, major_ver=%d\n",
+			     MAJOR(dev), MINOR(dev), checksum,
+			     md->major_ver);
+			if (((checksum == 0xffff) && (md->major_ver == 1))
+			    || (checksum == 0)) {
+				dprintk("Probing %02x:%02x VALID\n",
+					MAJOR(dev), MINOR(dev));
+				break;
+			}
+		}
+		/* Was not a valid superblock */
+		if (bh) {
+			brelse(bh);
+			bh = NULL;
+		}
+	}
+	return bh;
+}
+
+/*
+ * Determine if this drive belongs to a Medley array.
+ */
+static void medley_probe_drive(int major, int minor)
+{
+	struct buffer_head *bh;
+	kdev_t dev = MKDEV(major, minor);
+	struct medley_metadata *md;
+
+	bh = medley_get_metadata(dev);
+	if (!bh)
+		return;
+
+	md = (void *) (bh->b_data);
+
+	if (md->raid_type != 0x0) {
+		printk(KERN_INFO "Medley RAID (%02x:%02x): "
+		       "Sorry, this driver currently only supports "
+		       "striped sets (RAID level 0).\n", major, minor);
+	} else if (md->major_ver == 2 && md->total_sectors_high != 0) {
+		printk(KERN_ERR "Medley RAID (%02x:%02x):"
+		       "Sorry, the driver only supports 32 bit LBA disks "
+		       "(disk too big).\n", major, minor);
+	} else if (md->major_ver > 0 && md->major_ver > 2) {
+		printk(KERN_INFO "Medley RAID (%02x:%02x): "
+		       "Unsupported version (%d.%d) - this driver supports "
+		       "Medley version 1.x and 2.x\n",
+		       major, minor, md->major_ver, md->minor_ver);
+	} else if (md->drives_per_striped_set > MAX_DRIVES_PER_SET) {
+		printk(KERN_ERR "Medley RAID (%02x:%02x): "
+		       "Striped set too large (%d drives) - please report "
+		       "this (and change max in driver).\n",
+		       major, minor, md->drives_per_striped_set);
+	} else if ((md->drive_number > md->drives_per_striped_set) ||
+		   (md->drives_per_striped_set < 1) ||
+		   (md->chunk_size < 1)) {
+		printk(KERN_ERR "Medley RAID (%02x:%02x): "
+		       "Metadata appears to be corrupt.\n", major, minor);
+	} else {
+		/* We have a good candidate, put it in the correct array */
+		medley_add_raiddrive(dev, md);
+	}
+
+	if (bh) {
+		brelse(bh);
+	}
+}
+
+
+/*
+ * Taken from hptraid.c, this is called to prevent the device
+ * from disappearing from under us and also nullifies the (incorrect)
+ * partitions of the underlying disk.
+ */
+struct block_device *get_device_lock(kdev_t member)
+{
+	struct block_device *bdev = bdget(member);
+	struct gendisk *gd;
+	int minor = MINOR(member);
+	int j;
+
+	if (bdev
+	    && blkdev_get(bdev, FMODE_READ | FMODE_WRITE, 0,
+			  BDEV_RAW) == 0) {
+		/*
+		 * This is supposed to prevent others from
+		 * stealing our underlying disks. Now blank
+		 * the /proc/partitions table for the wrong
+		 * partition table, so that scripts don't
+		 * accidentally mount it and crash the kernel
+		 */
+		/* XXX: the 0 is an utter hack  --hch */
+		gd = get_gendisk(MKDEV(MAJOR(member), 0));
+		if (gd != NULL) {
+			if (gd->major == MAJOR(member)) {
+				for (j = 1 + (minor << gd->minor_shift);
+				     j < ((minor + 1) << gd->minor_shift);
+				     j++)
+					gd->part[j].nr_sects = 0;
+			}
+		}
+	}
+	return bdev;
+}
+
+/*
+ * Initialise the driver.
+ */
+static __init int medley_init(void)
+{
+	int c, d;
+
+	memset(raid, 0, MAX_MEDLEY_ARRAYS * sizeof(struct medley_array));
+
+	/* Probe each of the drives on our list */
+	for (c = 0; probelist[c] != MKDEV(0, 0); c++) {
+		medley_probe_drive(MAJOR(probelist[c]),
+				   MINOR(probelist[c]));
+	}
+
+	/* Check if the detected sets are complete */
+	for (c = 0; c < medley_arrays; c++) {
+		if (raid[c].present != (1 << raid[c].drives) - 1) {
+			printk(KERN_ERR "Medley RAID: "
+			       "Incomplete RAID set deleted - disks:");
+			for (d = 0; c < raid[c].drives; c++) {
+				if (raid[c].present & (1 << d)) {
+					printk(" %02x:%02x",
+					       MAJOR(raid[c].members[d]),
+					       MINOR(raid[c].members[d]));
+				}
+			}
+			printk("\n");
+			if (c + 1 < medley_arrays) {
+				memmove(raid + c + 1, raid + c,
+					(medley_arrays - c -
+					 1) * sizeof(struct medley_array));
+			}
+			medley_arrays--;
+		}
+	}
+
+	/* Register any remaining array(s) */
+	for (c = 0; c < medley_arrays; c++) {
+		int device = ataraid_get_device(&medley_ops);
+		if (device < 0) {
+			printk(KERN_ERR "Medley RAID: "
+			       "Could not get ATARAID device.\n");
+			break;
+		}
+		if (c == 0) {
+			/* First array, compute offset to our device ID's */
+			medley_devid_offset = device;
+			dprintk("Medley_devid_offset: %d\n",
+				medley_devid_offset);
+		} else if (device - medley_devid_offset != c) {
+			printk(KERN_ERR "Medley RAID: "
+			       "ATARAID gave us an illegal device ID.\n");
+			ataraid_release_device(device);
+			break;
+		}
+
+		printk(KERN_INFO "Medley RAID: "
+		       "Striped set %d consists of %d disks, total %dMiB "
+		       "- disks:",
+		       c, raid[c].drives,
+		       raid[c].sectors / 1024 / 1024 / 2);
+		for (d = 0; d < raid[c].drives; d++) {
+			printk(" %02x:%02x", MAJOR(raid[c].members[d]),
+			       MINOR(raid[c].members[d]));
+			raid[c].bdev[d] = get_device_lock(raid[c].members[d]);
+		}
+		printk("\n");
+		raid[c].registered = 1;
+		atomic_set(&(raid[c].valid), 1);
+		ataraid_register_disk(c, raid[c].sectors);
+	}
+
+	if (medley_arrays > 0) {
+		printk(KERN_INFO "Medley RAID: %d active RAID set%s\n",
+		       medley_arrays, medley_arrays == 1 ? "" : "s");
+		return 0;
+	}
+
+	printk(KERN_INFO "Medley RAID: No usable RAID sets found\n");
+	return -ENODEV;
+}
+
+/*
+ * Remove the arrays and clean up.
+ */
+static void __exit medley_exit(void)
+{
+	int device, d;
+	for (device = 0; device < medley_arrays; device++) {
+		for (d = 0; d < raid[device].drives; d++) {
+			if (raid[device].bdev[d]) {
+				blkdev_put(raid[device].bdev[d], BDEV_RAW);
+				raid[device].bdev[d] = NULL;
+			}
+		}
+		if (raid[device].registered) {
+			ataraid_release_device(device +
+					       medley_devid_offset);
+			raid[device].registered = 0;
+		}
+	}
+}
+
+/*
+ * Called to open the virtual device
+ */
+static int medley_open(struct inode *inode, struct file *filp)
+{
+	int device = ((inode->i_rdev >> SHIFT) & MAJOR_MASK) -
+	    medley_devid_offset;
+	dprintk("medley_open\n");
+
+	if (device < medley_arrays) {
+		while (!atomic_read(&(raid[device].valid)))
+			sleep_on(&medley_wait_open);
+		raid[device].access++;
+		MOD_INC_USE_COUNT;
+		return (0);
+	}
+	return -ENODEV;
+}
+
+/*
+ * Called to release the handle on the virtual device
+ */
+static int medley_release(struct inode *inode, struct file *filp)
+{
+	int device = ((inode->i_rdev >> SHIFT) & MAJOR_MASK) -
+	    medley_devid_offset;
+	dprintk("medley_release\n");
+	raid[device].access--;
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+module_init(medley_init);
+module_exit(medley_exit);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.26-pre3/fs/jbd/journal.c linux-2.4.26-pre4/fs/jbd/journal.c
--- linux-2.4.26-pre3/fs/jbd/journal.c	2004-02-18 05:36:31.000000000 -0800
+++ linux-2.4.26-pre4/fs/jbd/journal.c	2004-03-16 09:59:36.000000000 -0800
@@ -671,6 +671,7 @@
 
 	bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
 	lock_buffer(bh);
+	memset(bh->b_data, 0, journal->j_blocksize);
 	BUFFER_TRACE(bh, "return this buffer");
 	return journal_add_journal_head(bh);
 }
diff -urN linux-2.4.26-pre3/include/linux/pci_ids.h linux-2.4.26-pre4/include/linux/pci_ids.h
--- linux-2.4.26-pre3/include/linux/pci_ids.h	2004-03-16 09:59:33.000000000 -0800
+++ linux-2.4.26-pre4/include/linux/pci_ids.h	2004-03-16 09:59:36.000000000 -0800
@@ -427,6 +427,7 @@
 #define PCI_DEVICE_ID_AMD_LANCE		0x2000
 #define PCI_DEVICE_ID_AMD_LANCE_HOME	0x2001
 #define PCI_DEVICE_ID_AMD_SCSI		0x2020
+#define PCI_DEVICE_ID_AMD_SERENADE	0x36c0
 #define PCI_DEVICE_ID_AMD_FE_GATE_7006	0x7006
 #define PCI_DEVICE_ID_AMD_FE_GATE_7007	0x7007
 #define PCI_DEVICE_ID_AMD_FE_GATE_700C	0x700C
@@ -972,9 +973,15 @@
 #define PCI_DEVICE_ID_NVIDIA_VTNT2		0x002C
 #define PCI_DEVICE_ID_NVIDIA_UVTNT2		0x002D
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE	0x0065
+#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE	0x0085
+#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA	0x008e
 #define PCI_DEVICE_ID_NVIDIA_ITNT2		0x00A0
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3		0x00d1
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE	0x00d5
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S		0x00e1
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA	0x00e3
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE	0x00e5
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2	0x00ee
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR	0x0100
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR	0x0101
 #define PCI_DEVICE_ID_NVIDIA_QUADRO		0x0103
diff -urN linux-2.4.26-pre3/include/net/bluetooth/hci.h linux-2.4.26-pre4/include/net/bluetooth/hci.h
--- linux-2.4.26-pre3/include/net/bluetooth/hci.h	2004-02-18 05:36:32.000000000 -0800
+++ linux-2.4.26-pre4/include/net/bluetooth/hci.h	2004-03-16 09:59:36.000000000 -0800
@@ -50,6 +50,11 @@
 #define HCI_RS232 	4
 #define HCI_PCI		5
 
+/* HCI device quirks */
+enum {
+	HCI_QUIRK_RESET_ON_INIT
+};
+
 /* HCI device flags */
 enum {
 	HCI_UP,
diff -urN linux-2.4.26-pre3/include/net/bluetooth/hci_core.h linux-2.4.26-pre4/include/net/bluetooth/hci_core.h
--- linux-2.4.26-pre3/include/net/bluetooth/hci_core.h	2004-02-18 05:36:32.000000000 -0800
+++ linux-2.4.26-pre4/include/net/bluetooth/hci_core.h	2004-03-16 09:59:36.000000000 -0800
@@ -72,7 +72,9 @@
 	__u16		pkt_type;
 	__u16		link_policy;
 	__u16		link_mode;
-	
+
+	unsigned long	quirks;
+
 	atomic_t 	cmd_cnt;
 	unsigned int 	acl_cnt;
 	unsigned int 	sco_cnt;
diff -urN linux-2.4.26-pre3/include/net/sock.h linux-2.4.26-pre4/include/net/sock.h
--- linux-2.4.26-pre3/include/net/sock.h	2004-03-16 09:59:33.000000000 -0800
+++ linux-2.4.26-pre4/include/net/sock.h	2004-03-16 09:59:36.000000000 -0800
@@ -435,7 +435,6 @@
 
 /* TCP Westwood structure */
         struct {
-                __u32    bw_sample;        /* bandwidth sample */
                 __u32    bw_ns_est;        /* first bandwidth estimation..not too smoothed 8) */
                 __u32    bw_est;           /* bandwidth estimate */
                 __u32    rtt_win_sx;       /* here starts a new evaluation... */
diff -urN linux-2.4.26-pre3/include/net/tcp.h linux-2.4.26-pre4/include/net/tcp.h
--- linux-2.4.26-pre3/include/net/tcp.h	2004-03-16 09:59:33.000000000 -0800
+++ linux-2.4.26-pre4/include/net/tcp.h	2004-03-16 09:59:36.000000000 -0800
@@ -1880,16 +1880,18 @@
 void __tcp_westwood_slow_bw(struct sock *, struct sk_buff *);
 
 /*
- * This function initializes fields used in TCP Westwood.
- * We can't get no information about RTT at this time so
- * we are forced to set it to 0.
+ * This function initializes fields used in TCP Westwood+. We can't
+ * get no information about RTTmin at this time so we simply set it to
+ * TCP_WESTWOOD_INIT_RTT. This value was chosen to be too conservative
+ * since in this way we're sure it will be updated in a consistent
+ * way as soon as possible. It will reasonably happen within the first
+ * RTT period of the connection lifetime.
  */
 
 static inline void __tcp_init_westwood(struct sock *sk)
 {
 	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
 
-	tp->westwood.bw_sample = 0;
 	tp->westwood.bw_ns_est = 0;
 	tp->westwood.bw_est = 0;
 	tp->westwood.accounted = 0;
diff -urN linux-2.4.26-pre3/mm/vmalloc.c linux-2.4.26-pre4/mm/vmalloc.c
--- linux-2.4.26-pre3/mm/vmalloc.c	2004-03-16 09:59:33.000000000 -0800
+++ linux-2.4.26-pre4/mm/vmalloc.c	2004-03-16 09:59:36.000000000 -0800
@@ -184,7 +184,7 @@
 	spin_unlock(&init_mm.page_table_lock);
 	flush_cache_all();
 	if (address > start)
-		vmfree_area_pages((address - start), address - start);
+		vmfree_area_pages(address, address - start);
 	return -ENOMEM;
 }
 
diff -urN linux-2.4.26-pre3/net/bluetooth/af_bluetooth.c linux-2.4.26-pre4/net/bluetooth/af_bluetooth.c
--- linux-2.4.26-pre3/net/bluetooth/af_bluetooth.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.26-pre4/net/bluetooth/af_bluetooth.c	2004-03-16 09:59:36.000000000 -0800
@@ -218,15 +218,31 @@
 	return err ? : copied;
 }
 
+static inline unsigned int bluez_accept_poll(struct sock *parent)
+{
+	struct list_head *p, *n;
+	struct sock *sk;
+
+	list_for_each_safe(p, n, &bluez_pi(parent)->accept_q) {
+		sk = (struct sock *) list_entry(p, struct bluez_pinfo, accept_q);
+		if (sk->state == BT_CONNECTED)
+			return POLLIN | POLLRDNORM;
+	}
+
+	return 0;
+}
+
 unsigned int bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
 {
 	struct sock *sk = sock->sk;
-	unsigned int mask;
+	unsigned int mask = 0;
 
 	BT_DBG("sock %p, sk %p", sock, sk);
 
 	poll_wait(file, sk->sleep, wait);
-	mask = 0;
+
+	if (sk->state == BT_LISTEN)
+		return bluez_accept_poll(sk);
 
 	if (sk->err || !skb_queue_empty(&sk->error_queue))
 		mask |= POLLERR;
@@ -235,16 +251,17 @@
 		mask |= POLLHUP;
 
 	if (!skb_queue_empty(&sk->receive_queue) || 
-			!list_empty(&bluez_pi(sk)->accept_q) ||
 			(sk->shutdown & RCV_SHUTDOWN))
 		mask |= POLLIN | POLLRDNORM;
 
 	if (sk->state == BT_CLOSED)
 		mask |= POLLHUP;
 
-	if (sk->state == BT_CONNECT || sk->state == BT_CONNECT2)
+	if (sk->state == BT_CONNECT ||
+			sk->state == BT_CONNECT2 ||
+			sk->state == BT_CONFIG)
 		return mask;
-	
+
 	if (sock_writeable(sk))
 		mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
 	else
diff -urN linux-2.4.26-pre3/net/bluetooth/bnep/sock.c linux-2.4.26-pre4/net/bluetooth/bnep/sock.c
--- linux-2.4.26-pre3/net/bluetooth/bnep/sock.c	2004-02-18 05:36:32.000000000 -0800
+++ linux-2.4.26-pre4/net/bluetooth/bnep/sock.c	2004-03-16 09:59:36.000000000 -0800
@@ -94,8 +94,10 @@
 		if (!nsock)
 			return err;
 
-		if (nsock->sk->state != BT_CONNECTED)
+		if (nsock->sk->state != BT_CONNECTED) {
+			fput(nsock->file);
 			return -EBADFD;
+		}
 
 		err = bnep_add_connection(&ca, nsock);
 		if (!err) {
diff -urN linux-2.4.26-pre3/net/bluetooth/cmtp/sock.c linux-2.4.26-pre4/net/bluetooth/cmtp/sock.c
--- linux-2.4.26-pre3/net/bluetooth/cmtp/sock.c	2004-02-18 05:36:32.000000000 -0800
+++ linux-2.4.26-pre4/net/bluetooth/cmtp/sock.c	2004-03-16 09:59:36.000000000 -0800
@@ -86,8 +86,10 @@
 		if (!nsock)
 			return err;
 
-		if (nsock->sk->state != BT_CONNECTED)
+		if (nsock->sk->state != BT_CONNECTED) {
+			fput(nsock->file);
 			return -EBADFD;
+		}
 
 		err = cmtp_add_connection(&ca, nsock);
 		if (!err) {
diff -urN linux-2.4.26-pre3/net/bluetooth/hci_conn.c linux-2.4.26-pre4/net/bluetooth/hci_conn.c
--- linux-2.4.26-pre3/net/bluetooth/hci_conn.c	2004-02-18 05:36:32.000000000 -0800
+++ linux-2.4.26-pre4/net/bluetooth/hci_conn.c	2004-03-16 09:59:36.000000000 -0800
@@ -358,21 +358,24 @@
 	struct hci_conn_info *ci;
 	struct hci_dev *hdev;
 	struct list_head *p;
-	int n = 0, size;
+	int n = 0, size, err;
 
 	if (copy_from_user(&req, (void *) arg, sizeof(req)))
 		return -EFAULT;
 
-	if (!(hdev = hci_dev_get(req.dev_id)))
-		return -ENODEV;
-
-	size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
+	if (!req.conn_num || req.conn_num > (PAGE_SIZE * 2) / sizeof(*ci))
+		return -EINVAL;
 
-	if (verify_area(VERIFY_WRITE, (void *)arg, size))
-		return -EFAULT;
+	size = sizeof(req) + req.conn_num * sizeof(*ci);
 
 	if (!(cl = (void *) kmalloc(size, GFP_KERNEL)))
 		return -ENOMEM;
+
+	if (!(hdev = hci_dev_get(req.dev_id))) {
+		kfree(cl);
+		return -ENODEV;
+	}
+
 	ci = cl->conn_info;
 
 	hci_dev_lock_bh(hdev);
@@ -386,20 +389,21 @@
 		(ci + n)->out   = c->out;
 		(ci + n)->state = c->state;
 		(ci + n)->link_mode = c->link_mode;
-		n++;
+		if (++n >= req.conn_num)
+			break;
 	}
 	hci_dev_unlock_bh(hdev);
 
 	cl->dev_id = hdev->id;
 	cl->conn_num = n;
-	size = n * sizeof(struct hci_conn_info) + sizeof(req);
+	size = sizeof(req) + n * sizeof(*ci);
 
 	hci_dev_put(hdev);
 
-	copy_to_user((void *) arg, cl, size);
+	err = copy_to_user((void *) arg, cl, size);
 	kfree(cl);
 
-	return 0;
+	return err ? -EFAULT : 0;
 }
 
 int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg)
@@ -412,9 +416,6 @@
 	if (copy_from_user(&req, (void *) arg, sizeof(req)))
 		return -EFAULT;
 
-	if (verify_area(VERIFY_WRITE, ptr, sizeof(ci)))
-		return -EFAULT;
-
 	hci_dev_lock_bh(hdev);
 	conn = conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
 	if (conn) {
@@ -430,6 +431,5 @@
 	if (!conn)
 		return -ENOENT;
 
-	copy_to_user(ptr, &ci, sizeof(ci));
-	return 0;
+	return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0;
 }
diff -urN linux-2.4.26-pre3/net/bluetooth/hci_core.c linux-2.4.26-pre4/net/bluetooth/hci_core.c
--- linux-2.4.26-pre3/net/bluetooth/hci_core.c	2004-02-18 05:36:32.000000000 -0800
+++ linux-2.4.26-pre4/net/bluetooth/hci_core.c	2004-03-16 09:59:36.000000000 -0800
@@ -218,6 +218,10 @@
 
 	/* Mandatory initialization */
 
+	/* Reset */
+	if (test_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks))
+		hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
+
 	/* Read Local Supported Features */
 	hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
 
@@ -712,22 +716,20 @@
 	struct hci_dev_list_req *dl;
 	struct hci_dev_req *dr;
 	struct list_head *p;
-	int n = 0, size;
+	int n = 0, size, err;
 	__u16 dev_num;
 
 	if (get_user(dev_num, (__u16 *) arg))
 		return -EFAULT;
 
-	if (!dev_num)
+	if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
 		return -EINVAL;
-	
-	size = dev_num * sizeof(*dr) + sizeof(*dl);
 
-	if (verify_area(VERIFY_WRITE, (void *) arg, size))
-		return -EFAULT;
+	size = sizeof(*dl) + dev_num * sizeof(*dr);
 
 	if (!(dl = kmalloc(size, GFP_KERNEL)))
 		return -ENOMEM;
+
 	dr = dl->dev_req;
 
 	read_lock_bh(&hdev_list_lock);
@@ -742,12 +744,12 @@
 	read_unlock_bh(&hdev_list_lock);
 
 	dl->dev_num = n;
-	size = n * sizeof(*dr) + sizeof(*dl);
+	size = sizeof(*dl) + n * sizeof(*dr);
 
-	copy_to_user((void *) arg, dl, size);
+	err = copy_to_user((void *) arg, dl, size);
 	kfree(dl);
 
-	return 0;
+	return err ? -EFAULT : 0;
 }
 
 int hci_get_dev_info(unsigned long arg)
diff -urN linux-2.4.26-pre3/net/bluetooth/l2cap.c linux-2.4.26-pre4/net/bluetooth/l2cap.c
--- linux-2.4.26-pre3/net/bluetooth/l2cap.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.26-pre4/net/bluetooth/l2cap.c	2004-03-16 09:59:36.000000000 -0800
@@ -1649,6 +1649,8 @@
 	l2cap_cmd_hdr cmd;
 	int err = 0;
 
+	l2cap_raw_recv(conn, skb);
+
 	while (len >= L2CAP_CMD_HDR_SIZE) {
 		memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
 		data += L2CAP_CMD_HDR_SIZE;
@@ -1690,7 +1692,6 @@
 
 		case L2CAP_COMMAND_REJ:
 			/* FIXME: We should process this */
-			l2cap_raw_recv(conn, skb);
 			break;
 
 		case L2CAP_ECHO_REQ:
@@ -1700,11 +1701,10 @@
 		case L2CAP_ECHO_RSP:
 		case L2CAP_INFO_REQ:
 		case L2CAP_INFO_RSP:
-			l2cap_raw_recv(conn, skb);
 			break;
 
 		default:
-			BT_ERR("Uknown signaling command 0x%2.2x", cmd.code);
+			BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
 			err = -EINVAL;
 			break;
 		};
diff -urN linux-2.4.26-pre3/net/bluetooth/rfcomm/core.c linux-2.4.26-pre4/net/bluetooth/rfcomm/core.c
--- linux-2.4.26-pre3/net/bluetooth/rfcomm/core.c	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.26-pre4/net/bluetooth/rfcomm/core.c	2004-03-16 09:59:36.000000000 -0800
@@ -1654,9 +1654,10 @@
 	nsock->sk->state_change = rfcomm_l2state_change;
 
 	s = rfcomm_session_add(nsock, BT_OPEN);
-	if (s)
+	if (s) {
 		rfcomm_session_hold(s);
-	else
+		rfcomm_schedule(RFCOMM_SCHED_RX);
+	} else
 		sock_release(nsock);
 }
 
diff -urN linux-2.4.26-pre3/net/bluetooth/rfcomm/tty.c linux-2.4.26-pre4/net/bluetooth/rfcomm/tty.c
--- linux-2.4.26-pre3/net/bluetooth/rfcomm/tty.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.26-pre4/net/bluetooth/rfcomm/tty.c	2004-03-16 09:59:36.000000000 -0800
@@ -109,6 +109,13 @@
 
 static inline void rfcomm_dev_put(struct rfcomm_dev *dev)
 {
+	/* The reason this isn't actually a race, as you no
+	   doubt have a little voice screaming at you in your
+	   head, is that the refcount should never actually
+	   reach zero unless the device has already been taken
+	   off the list, in rfcomm_dev_del(). And if that's not
+	   true, we'll hit the BUG() in rfcomm_dev_destruct()
+	   anyway. */
 	if (atomic_dec_and_test(&dev->refcnt))
 		rfcomm_dev_destruct(dev);
 }
@@ -132,10 +139,13 @@
 	struct rfcomm_dev *dev;
 
 	read_lock(&rfcomm_dev_lock);
+
 	dev = __rfcomm_dev_get(id);
+	if (dev)
+		rfcomm_dev_hold(dev);
+
 	read_unlock(&rfcomm_dev_lock);
 
-	if (dev) rfcomm_dev_hold(dev);
 	return dev;
 }
 
@@ -347,7 +357,7 @@
 	struct rfcomm_dev_list_req *dl;
 	struct rfcomm_dev_info *di;
 	struct list_head *p;
-	int n = 0, size;
+	int n = 0, size, err;
 	u16 dev_num;
 
 	BT_DBG("");
@@ -355,14 +365,11 @@
 	if (get_user(dev_num, (u16 *) arg))
 		return -EFAULT;
 
-	if (!dev_num)
+	if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
 		return -EINVAL;
 
 	size = sizeof(*dl) + dev_num * sizeof(*di);
 
-	if (verify_area(VERIFY_WRITE, (void *)arg, size))
-		return -EFAULT;
-
 	if (!(dl = kmalloc(size, GFP_KERNEL)))
 		return -ENOMEM;
 
@@ -387,9 +394,10 @@
 	dl->dev_num = n;
 	size = sizeof(*dl) + n * sizeof(*di);
 
-	copy_to_user((void *) arg, dl, size);
+	err = copy_to_user((void *) arg, dl, size);
 	kfree(dl);
-	return 0;
+
+	return err ? -EFAULT : 0;
 }
 
 static int rfcomm_get_dev_info(unsigned long arg)
@@ -486,7 +494,8 @@
 				rfcomm_dev_del(dev);
 
 				/* We have to drop DLC lock here, otherwise
-				 * rfcomm_dev_put() will dead lock if it's the last refference */
+				   rfcomm_dev_put() will dead lock if it's
+				   the last reference. */
 				rfcomm_dlc_unlock(dlc);
 				rfcomm_dev_put(dev);
 				rfcomm_dlc_lock(dlc);
@@ -541,6 +550,10 @@
 
 	BT_DBG("tty %p id %d", tty, id);
 
+	/* We don't leak this refcount. For reasons which are not entirely
+	   clear, the TTY layer will call our ->close() method even if the
+	   open fails. We decrease the refcount there, and decreasing it
+	   here too would cause breakage. */
 	dev = rfcomm_dev_get(id);
 	if (!dev)
 		return -ENODEV;
diff -urN linux-2.4.26-pre3/net/ipv4/ipvs/Config.in linux-2.4.26-pre4/net/ipv4/ipvs/Config.in
--- linux-2.4.26-pre3/net/ipv4/ipvs/Config.in	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.26-pre4/net/ipv4/ipvs/Config.in	2004-03-16 09:59:36.000000000 -0800
@@ -11,7 +11,7 @@
   comment 'IPVS scheduler'
   dep_tristate '  round-robin scheduling' CONFIG_IP_VS_RR $CONFIG_IP_VS
   dep_tristate '  weighted round-robin scheduling' CONFIG_IP_VS_WRR $CONFIG_IP_VS
-  dep_tristate '  least-connection scheduling scheduling' CONFIG_IP_VS_LC $CONFIG_IP_VS
+  dep_tristate '  least-connection scheduling' CONFIG_IP_VS_LC $CONFIG_IP_VS
   dep_tristate '  weighted least-connection scheduling' CONFIG_IP_VS_WLC $CONFIG_IP_VS
   dep_tristate '  locality-based least-connection scheduling' CONFIG_IP_VS_LBLC $CONFIG_IP_VS
   dep_tristate '  locality-based least-connection with replication scheduling' CONFIG_IP_VS_LBLCR $CONFIG_IP_VS
diff -urN linux-2.4.26-pre3/net/ipv4/tcp_input.c linux-2.4.26-pre4/net/ipv4/tcp_input.c
--- linux-2.4.26-pre3/net/ipv4/tcp_input.c	2004-03-16 09:59:33.000000000 -0800
+++ linux-2.4.26-pre4/net/ipv4/tcp_input.c	2004-03-16 09:59:36.000000000 -0800
@@ -2038,8 +2038,7 @@
 }
 
 /*
- * TCP Westwood
- * Functions needed for estimating bandwidth.
+ * TCP Westwood+
  */
 
 /*
@@ -2055,14 +2054,13 @@
 static void westwood_filter(struct sock *sk, __u32 delta)
 {
 	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	__u32 sample = (tp->westwood.bk) / delta;
 
 	tp->westwood.bw_ns_est =
-		westwood_do_filter(tp->westwood.bw_ns_est, sample);
+		westwood_do_filter(tp->westwood.bw_ns_est, 
+				   tp->westwood.bk / delta);
 	tp->westwood.bw_est =
 		westwood_do_filter(tp->westwood.bw_est,
 				   tp->westwood.bw_ns_est);
-	tp->westwood.bw_sample = sample;
 }
 
 /* @westwood_update_rttmin
@@ -2086,8 +2084,7 @@
 
 /*
  * @westwood_acked
- * Evaluate increases for dk. It requires no lock since when it is
- * called lock should already be held. Be careful about it!
+ * Evaluate increases for dk. 
  */
 
 static __u32 westwood_acked(struct sock *sk)
@@ -2134,10 +2131,7 @@
 /*
  * @westwood_update_window
  * It updates RTT evaluation window if it is the right moment to do
- * it. If so it calls filter for evaluating bandwidth. Be careful
- * about __westwood_update_window() since it is called without
- * any form of lock. It should be used only for internal purposes.
- * Call westwood_update_window() instead.
+ * it. If so it calls filter for evaluating bandwidth. 
  */
  
 static void __westwood_update_window(struct sock *sk, __u32 now)
@@ -2162,7 +2156,7 @@
 }
 
 /*
- * @__westwood_fast_bw
+ * @__tcp_westwood_fast_bw
  * It is called when we are in fast path. In particular it is called when
  * header prediction is successfull. In such case infact update is
  * straight forward and doesn't need any particular care.
@@ -2253,7 +2247,7 @@
 }
 
 /*
- * @__westwood_slow_bw
+ * @__tcp_westwood_slow_bw
  * It is called when something is going wrong..even if there could
  * be no problems! Infact a simple delayed packet may trigger a
  * dupack. But we need to be careful in such case.
@@ -2269,7 +2263,7 @@
 	tp->westwood.rtt_min = westwood_update_rttmin(sk);
 }
 
-/* TCP Westwood routines end here */
+/* TCP Westwood+ routines end here */
 
 /* This routine deals with incoming acks, but not outgoing ones. */
 static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
diff -urN linux-2.4.26-pre3/net/sched/sch_htb.c linux-2.4.26-pre4/net/sched/sch_htb.c
--- linux-2.4.26-pre3/net/sched/sch_htb.c	2004-02-18 05:36:32.000000000 -0800
+++ linux-2.4.26-pre4/net/sched/sch_htb.c	2004-03-16 09:59:36.000000000 -0800
@@ -433,13 +433,13 @@
 		cl->pq_key++;
 
 	/* update the nearest event cache */
-	if (q->near_ev_cache[cl->level] - cl->pq_key < 0x80000000)
+	if (time_after(q->near_ev_cache[cl->level], cl->pq_key))
 		q->near_ev_cache[cl->level] = cl->pq_key;
 	
 	while (*p) {
 		struct htb_class *c; parent = *p;
 		c = rb_entry(parent, struct htb_class, pq_node);
-		if (cl->pq_key - c->pq_key < 0x80000000)
+		if (time_after_eq(cl->pq_key, c->pq_key))
 			p = &parent->rb_right;
 		else 
 			p = &parent->rb_left;
@@ -878,7 +878,7 @@
 		while (p->rb_left) p = p->rb_left;
 
 		cl = rb_entry(p, struct htb_class, pq_node);
-		if (cl->pq_key - (q->jiffies+1) < 0x80000000) {
+		if (time_after(cl->pq_key, q->jiffies)) {
 			HTB_DBG(8,3,"htb_do_ev_ret delay=%ld\n",cl->pq_key - q->jiffies);
 			return cl->pq_key - q->jiffies;
 		}
@@ -1057,7 +1057,7 @@
 		/* common case optimization - skip event handler quickly */
 		int m;
 		long delay;
-		if (q->jiffies - q->near_ev_cache[level] < 0x80000000 || 0) {
+		if (time_after_eq(q->jiffies, q->near_ev_cache[level])) {
 			delay = htb_do_events(q,level);
 			q->near_ev_cache[level] = q->jiffies + (delay ? delay : HZ);
 #ifdef HTB_DEBUG
