## Automatically generated incremental diff
## From:   linux-2.4.21-rc3
## To:     linux-2.4.21-rc4
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $

diff -urN linux-2.4.21-rc3/Makefile linux-2.4.21-rc4/Makefile
--- linux-2.4.21-rc3/Makefile	2003-05-26 15:16:17.000000000 -0700
+++ linux-2.4.21-rc4/Makefile	2003-05-26 15:16:22.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 21
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.21-rc3/arch/i386/kernel/ioport.c linux-2.4.21-rc4/arch/i386/kernel/ioport.c
--- linux-2.4.21-rc3/arch/i386/kernel/ioport.c	2003-05-26 15:16:17.000000000 -0700
+++ linux-2.4.21-rc4/arch/i386/kernel/ioport.c	2003-05-26 15:16:22.000000000 -0700
@@ -81,7 +81,7 @@
 	if (tss->bitmap == IO_BITMAP_OFFSET) { /* already active? */
 		set_bitmap(tss->io_bitmap, from, num, !turn_on);
 	} else {
-		memcpy(tss->io_bitmap, t->io_bitmap, IO_BITMAP_SIZE);
+		memcpy(tss->io_bitmap, t->io_bitmap, IO_BITMAP_BYTES);
 		tss->bitmap = IO_BITMAP_OFFSET; /* Activate it in the TSS */
 	}
 
diff -urN linux-2.4.21-rc3/arch/i386/kernel/process.c linux-2.4.21-rc4/arch/i386/kernel/process.c
--- linux-2.4.21-rc3/arch/i386/kernel/process.c	2003-05-26 15:16:17.000000000 -0700
+++ linux-2.4.21-rc4/arch/i386/kernel/process.c	2003-05-26 15:16:22.000000000 -0700
@@ -727,7 +727,7 @@
 			 * is not really acceptable.]
 			 */
 			memcpy(tss->io_bitmap, next->io_bitmap,
-				 IO_BITMAP_SIZE*sizeof(unsigned long));
+				 IO_BITMAP_BYTES);
 			tss->bitmap = IO_BITMAP_OFFSET;
 		} else
 			/*
diff -urN linux-2.4.21-rc3/drivers/char/ipmi/ipmi_kcs_intf.c linux-2.4.21-rc4/drivers/char/ipmi/ipmi_kcs_intf.c
--- linux-2.4.21-rc3/drivers/char/ipmi/ipmi_kcs_intf.c	2003-05-26 15:16:18.000000000 -0700
+++ linux-2.4.21-rc4/drivers/char/ipmi/ipmi_kcs_intf.c	2003-05-26 15:16:22.000000000 -0700
@@ -60,6 +60,14 @@
 /* Measure times between events in the driver. */
 #undef DEBUG_TIMING
 
+/* Timing parameters.  Call every 10 ms when not doing anything,
+   otherwise call every KCS_SHORT_TIMEOUT_USEC microseconds. */
+#define KCS_TIMEOUT_TIME_USEC	10000
+#define KCS_USEC_PER_JIFFY	(1000000/HZ)
+#define KCS_TIMEOUT_JIFFIES	(KCS_TIMEOUT_TIME_USEC/KCS_USEC_PER_JIFFY)
+#define KCS_SHORT_TIMEOUT_USEC  250 /* .25ms when the SM request a
+                                       short timeout */
+
 #ifdef CONFIG_IPMI_KCS
 /* This forces a dependency to the config file for this option. */
 #endif
@@ -131,6 +139,8 @@
 	int                 interrupt_disabled;
 };
 
+static void kcs_restart_short_timer(struct kcs_info *kcs_info);
+
 static void deliver_recv_msg(struct kcs_info *kcs_info, struct ipmi_smi_msg *msg)
 {
 	/* Deliver the message to the upper layer with the lock
@@ -308,6 +318,9 @@
 #endif
 	switch (kcs_info->kcs_state) {
 	case KCS_NORMAL:
+		if (!kcs_info->curr_msg)
+			break;
+			
 		kcs_info->curr_msg->rsp_size
 			= kcs_get_result(kcs_info->kcs_sm,
 					 kcs_info->curr_msg->rsp,
@@ -562,8 +575,9 @@
 		spin_lock_irqsave(&(kcs_info->kcs_lock), flags);
 		result = kcs_event_handler(kcs_info, 0);
 		while (result != KCS_SM_IDLE) {
-			udelay(500);
-			result = kcs_event_handler(kcs_info, 500);
+			udelay(KCS_SHORT_TIMEOUT_USEC);
+			result = kcs_event_handler(kcs_info,
+						   KCS_SHORT_TIMEOUT_USEC);
 		}
 		spin_unlock_irqrestore(&(kcs_info->kcs_lock), flags);
 		return;
@@ -581,6 +595,7 @@
 	    && (kcs_info->curr_msg == NULL))
 	{
 		start_next_msg(kcs_info);
+		kcs_restart_short_timer(kcs_info);
 	}
 	spin_unlock_irqrestore(&(kcs_info->kcs_lock), flags);
 }
@@ -597,8 +612,9 @@
 	if (i_run_to_completion) {
 		result = kcs_event_handler(kcs_info, 0);
 		while (result != KCS_SM_IDLE) {
-			udelay(500);
-			result = kcs_event_handler(kcs_info, 500);
+			udelay(KCS_SHORT_TIMEOUT_USEC);
+			result = kcs_event_handler(kcs_info,
+						   KCS_SHORT_TIMEOUT_USEC);
 		}
 	}
 
@@ -624,14 +640,40 @@
 	MOD_DEC_USE_COUNT;
 }
 
-/* Call every 10 ms. */
-#define KCS_TIMEOUT_TIME_USEC	10000
-#define KCS_USEC_PER_JIFFY	(1000000/HZ)
-#define KCS_TIMEOUT_JIFFIES	(KCS_TIMEOUT_TIME_USEC/KCS_USEC_PER_JIFFY)
-#define KCS_SHORT_TIMEOUT_USEC  500 /* .5ms when the SM request a
-                                       short timeout */
 static int initialized = 0;
 
+/* Must be called with interrupts off and with the kcs_lock held. */
+static void kcs_restart_short_timer(struct kcs_info *kcs_info)
+{
+#ifdef CONFIG_HIGH_RES_TIMERS
+	unsigned long jiffies_now;
+
+	if (del_timer(&(kcs_info->kcs_timer))) {
+		/* If we don't delete the timer, then it will go off
+		   immediately, anyway.  So we only process if we
+		   actually delete the timer. */
+
+		/* We already have irqsave on, so no need for it
+                   here. */
+		read_lock(&xtime_lock);
+		jiffies_now = jiffies;
+		kcs_info->kcs_timer.expires = jiffies_now;
+
+		kcs_info->kcs_timer.sub_expires
+			= quick_update_jiffies_sub(jiffies_now);
+		read_unlock(&xtime_lock);
+
+		kcs_info->kcs_timer.sub_expires
+			+= usec_to_arch_cycles(KCS_SHORT_TIMEOUT_USEC);
+		while (kcs_info->kcs_timer.sub_expires >= cycles_per_jiffies) {
+			kcs_info->kcs_timer.expires++;
+			kcs_info->kcs_timer.sub_expires -= cycles_per_jiffies;
+		}
+		add_timer(&(kcs_info->kcs_timer));
+	}
+#endif
+}
+
 static void kcs_timeout(unsigned long data)
 {
 	struct kcs_info *kcs_info = (struct kcs_info *) data;
@@ -654,12 +696,11 @@
 	printk("**Timer: %d.%9.9d\n", t.tv_sec, t.tv_usec);
 #endif
 	jiffies_now = jiffies;
+
 	time_diff = ((jiffies_now - kcs_info->last_timeout_jiffies)
 		     * KCS_USEC_PER_JIFFY);
 	kcs_result = kcs_event_handler(kcs_info, time_diff);
 
-	spin_unlock_irqrestore(&(kcs_info->kcs_lock), flags);
-
 	kcs_info->last_timeout_jiffies = jiffies_now;
 
 	if ((kcs_info->irq) && (! kcs_info->interrupt_disabled)) {
@@ -680,6 +721,7 @@
 		}
 	} else {
 		kcs_info->kcs_timer.expires = jiffies + KCS_TIMEOUT_JIFFIES;
+		kcs_info->kcs_timer.sub_expires = 0;
 	}
 #else
 	/* If requested, take the shortest delay possible */
@@ -692,6 +734,7 @@
 
  do_add_timer:
 	add_timer(&(kcs_info->kcs_timer));
+	spin_unlock_irqrestore(&(kcs_info->kcs_lock), flags);
 }
 
 static void kcs_irq_handler(int irq, void *data, struct pt_regs *regs)
@@ -838,7 +881,7 @@
 	if (kcs_port && kcs_physaddr)
 		return -EINVAL;
 
-	new_kcs = kmalloc(kcs_size(), GFP_KERNEL);
+	new_kcs = kmalloc(sizeof(*new_kcs), GFP_KERNEL);
 	if (!new_kcs) {
 		printk(KERN_ERR "ipmi_kcs: out of memory\n");
 		return -ENOMEM;
diff -urN linux-2.4.21-rc3/drivers/char/ipmi/ipmi_kcs_sm.c linux-2.4.21-rc4/drivers/char/ipmi/ipmi_kcs_sm.c
--- linux-2.4.21-rc3/drivers/char/ipmi/ipmi_kcs_sm.c	2003-05-26 15:16:18.000000000 -0700
+++ linux-2.4.21-rc4/drivers/char/ipmi/ipmi_kcs_sm.c	2003-05-26 15:16:23.000000000 -0700
@@ -468,7 +468,7 @@
 		break;
 			
 	case KCS_HOSED:
-		return KCS_SM_HOSED;
+		break;
 	}
 
 	if (kcs->state == KCS_HOSED) {
diff -urN linux-2.4.21-rc3/drivers/char/ipmi/ipmi_msghandler.c linux-2.4.21-rc4/drivers/char/ipmi/ipmi_msghandler.c
--- linux-2.4.21-rc3/drivers/char/ipmi/ipmi_msghandler.c	2003-05-26 15:16:18.000000000 -0700
+++ linux-2.4.21-rc4/drivers/char/ipmi/ipmi_msghandler.c	2003-05-26 15:16:23.000000000 -0700
@@ -174,8 +174,8 @@
 int
 ipmi_register_all_cmd_rcvr(ipmi_user_t user)
 {
-	int flags;
-	int rv = -EBUSY;
+	unsigned long flags;
+	int           rv = -EBUSY;
 
 	write_lock_irqsave(&(user->intf->users_lock), flags);
 	write_lock(&(user->intf->cmd_rcvr_lock));
@@ -193,8 +193,8 @@
 int
 ipmi_unregister_all_cmd_rcvr(ipmi_user_t user)
 {
-	int flags;
-	int rv = -EINVAL;
+	unsigned long flags;
+	int           rv = -EINVAL;
 
 	write_lock_irqsave(&(user->intf->users_lock), flags);
 	write_lock(&(user->intf->cmd_rcvr_lock));
@@ -1022,7 +1022,7 @@
 	int              rv;
 	ipmi_smi_t       new_intf;
 	struct list_head *entry;
-	unsigned int     flags;
+	unsigned long    flags;
 
 
 	/* Make sure the driver is actually initialized, this handles
@@ -1156,7 +1156,7 @@
 	int              rv = -ENODEV;
 	int              i;
 	struct list_head *entry;
-	unsigned int     flags;
+	unsigned long    flags;
 
 	down_write(&interfaces_sem);
 	if (list_empty(&(intf->users)))
@@ -1773,9 +1773,13 @@
 }
 
 
+static atomic_t smi_msg_inuse_count = ATOMIC_INIT(0);
+static atomic_t recv_msg_inuse_count = ATOMIC_INIT(0);
+
 /* FIXME - convert these to slabs. */
 static void free_smi_msg(struct ipmi_smi_msg *msg)
 {
+	atomic_dec(&smi_msg_inuse_count);
 	kfree(msg);
 }
 
@@ -1783,13 +1787,16 @@
 {
 	struct ipmi_smi_msg *rv;
 	rv = kmalloc(sizeof(struct ipmi_smi_msg), GFP_ATOMIC);
-	if (rv)
+	if (rv) {
 		rv->done = free_smi_msg;
+		atomic_inc(&smi_msg_inuse_count);
+	}
 	return rv;
 }
 
 static void free_recv_msg(struct ipmi_recv_msg *msg)
 {
+	atomic_dec(&recv_msg_inuse_count);
 	kfree(msg);
 }
 
@@ -1798,8 +1805,10 @@
 	struct ipmi_recv_msg *rv;
 
 	rv = kmalloc(sizeof(struct ipmi_recv_msg), GFP_ATOMIC);
-	if (rv)
+	if (rv) {
 		rv->done = free_recv_msg;
+		atomic_inc(&recv_msg_inuse_count);
+	}
 	return rv;
 }
 
@@ -1932,6 +1941,8 @@
 
 static __exit void cleanup_ipmi(void)
 {
+	int count;
+
 	if (!initialized)
 		return;
 
@@ -1948,6 +1959,16 @@
 	}
 
 	initialized = 0;
+
+	/* Check for buffer leaks. */
+	count = atomic_read(&smi_msg_inuse_count);
+	if (count != 0)
+		printk("ipmi_msghandler: SMI message count %d at exit\n",
+		       count);
+	count = atomic_read(&recv_msg_inuse_count);
+	if (count != 0)
+		printk("ipmi_msghandler: recv message count %d at exit\n",
+		       count);
 }
 module_exit(cleanup_ipmi);
 
diff -urN linux-2.4.21-rc3/drivers/char/ipmi/ipmi_watchdog.c linux-2.4.21-rc4/drivers/char/ipmi/ipmi_watchdog.c
--- linux-2.4.21-rc3/drivers/char/ipmi/ipmi_watchdog.c	2003-05-26 15:16:18.000000000 -0700
+++ linux-2.4.21-rc4/drivers/char/ipmi/ipmi_watchdog.c	2003-05-26 15:16:23.000000000 -0700
@@ -215,13 +215,13 @@
 			      struct ipmi_recv_msg *recv_msg,
 			      int                  *send_heartbeat_now)
 {
-	struct ipmi_msg    msg;
-	unsigned char      data[6];
-	int                rv;
+	struct ipmi_msg                   msg;
+	unsigned char                     data[6];
+	int                               rv;
 	struct ipmi_system_interface_addr addr;
+	int                               hbnow = 0;
 
 
-	*send_heartbeat_now = 0;
 	data[0] = 0;
 	WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS);
 
@@ -233,7 +233,7 @@
 	} else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) {
 		/* In ipmi 1.0, setting the timer stops the watchdog, we
 		   need to start it back up again. */
-		*send_heartbeat_now = 1;
+		hbnow = 1;
 	}
 
 	data[1] = 0;
@@ -268,10 +268,18 @@
 		       rv);
 	}
 
+	if (send_heartbeat_now)
+	    *send_heartbeat_now = hbnow;
+
 	return rv;
 }
 
-static int ipmi_set_timeout(void)
+/* Parameters to ipmi_set_timeout */
+#define IPMI_SET_TIMEOUT_NO_HB			0
+#define IPMI_SET_TIMEOUT_HB_IF_NECESSARY	1
+#define IPMI_SET_TIMEOUT_FORCE_HB		2
+
+static int ipmi_set_timeout(int do_heartbeat)
 {
 	int send_heartbeat_now;
 	int rv;
@@ -288,8 +296,12 @@
 	if (rv) {
 		up(&set_timeout_lock);
 	} else {
-		if (send_heartbeat_now)
+		if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB)
+		    || ((send_heartbeat_now)
+			&& (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY)))
+		{
 			rv = ipmi_heartbeat();
+		}
 	}
 
 	return rv;
@@ -312,7 +324,7 @@
 
 /* Special call, doesn't claim any locks.  This is only to be called
    at panic or halt time, in run-to-completion mode, when the caller
-   is the only CPU and the only thing that will be going IPMI
+   is the only CPU and the only thing that will be going is these IPMI
    calls. */
 static void panic_halt_ipmi_set_timeout(void)
 {
@@ -339,7 +351,7 @@
 	else
 		ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
 	timeout = delay;
-	ipmi_set_timeout();
+	ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
 }
 
 /* We use a semaphore to make sure that only one thing can send a
@@ -390,16 +402,14 @@
 	if (ipmi_start_timer_on_heartbeat) {
 		ipmi_start_timer_on_heartbeat = 0;
 		ipmi_watchdog_state = action_val;
-		return ipmi_set_timeout();
-	}
-
-	if (pretimeout_since_last_heartbeat) {
+		return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
+	} else if (pretimeout_since_last_heartbeat) {
 		/* A pretimeout occurred, make sure we set the timeout.
 		   We don't want to set the action, though, we want to
 		   leave that alone (thus it can't be combined with the
 		   above operation. */
 		pretimeout_since_last_heartbeat = 0;
-		return ipmi_set_timeout();
+		return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
 	}
 
 	down(&heartbeat_lock);
@@ -501,7 +511,7 @@
 		if (i)
 			return -EFAULT;
 		timeout = val;
-		return ipmi_set_timeout();
+		return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
 
 	case WDIOC_GETTIMEOUT:
 		i = copy_to_user((void *) arg,
@@ -516,7 +526,7 @@
 		if (i)
 			return -EFAULT;
 		pretimeout = val;
-		return ipmi_set_timeout();
+		return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
 
 	case WDIOC_GET_PRETIMEOUT:
 		i = copy_to_user((void *) arg,
@@ -536,14 +546,14 @@
 		if (val & WDIOS_DISABLECARD)
 		{
 			ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
-			ipmi_set_timeout();
+			ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
 			ipmi_start_timer_on_heartbeat = 0;
 		}
 
 		if (val & WDIOS_ENABLECARD)
 		{
 			ipmi_watchdog_state = action_val;
-			ipmi_set_timeout();
+			ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
 		}
 		return 0;
 
@@ -679,7 +689,7 @@
 	{
 #ifndef CONFIG_WATCHDOG_NOWAYOUT	
 		ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
-		ipmi_set_timeout();
+		ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
 #endif		
 	        ipmi_wdog_open = 0;
 	}
@@ -731,14 +741,14 @@
 			wake_up_interruptible(&read_q);
 			kill_fasync(&fasync_q, SIGIO, POLL_IN);
 
-			/* On some machines, the heartbeat will give
-			   an error and not work unless we re-enable
-			   the timer.   So do so. */
-			pretimeout_since_last_heartbeat = 1;
-
 			spin_unlock(&ipmi_read_lock);
 		}
 	}
+
+	/* On some machines, the heartbeat will give
+	   an error and not work unless we re-enable
+	   the timer.   So do so. */
+	pretimeout_since_last_heartbeat = 1;
 }
 
 static struct ipmi_user_hndl ipmi_hndlrs =
@@ -751,7 +761,7 @@
 {
 	int rv = -EBUSY;
 
-	down_read(&register_sem);
+	down_write(&register_sem);
 	if (watchdog_user)
 		goto out;
 
@@ -779,7 +789,7 @@
 		/* Run from startup, so start the timer now. */
 		start_now = 0; /* Disable this function after first startup. */
 		ipmi_watchdog_state = action_val;
-		ipmi_set_timeout();
+		ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
 		printk("Starting IPMI Watchdog now!\n");
 	}
 }
@@ -792,6 +802,12 @@
            watchdog. */
 	if ((!handled) && (preop_val == WDOG_PREOP_PANIC))
 		panic("IPMI watchdog pre-timeout");
+
+	/* On some machines, the heartbeat will give
+	   an error and not work unless we re-enable
+	   the timer.   So do so. */
+	pretimeout_since_last_heartbeat = 1;
+
 	return NOTIFY_DONE;
 }
 
@@ -916,7 +932,7 @@
 	} else if (strcmp(preaction, "pre_int") == 0) {
 		preaction_val = WDOG_PRETIMEOUT_MSG_INT;
 	} else {
-		action_val = WDOG_PRETIMEOUT_NONE;
+		preaction_val = WDOG_PRETIMEOUT_NONE;
 		printk("ipmi_watchdog: Unknown preaction '%s', defaulting to"
 		       " none\n", preaction);
 	}
@@ -928,7 +944,7 @@
 	} else if (strcmp(preop, "preop_give_data") == 0) {
 		preop_val = WDOG_PREOP_GIVE_DATA;
 	} else {
-		action_val = WDOG_PREOP_NONE;
+		preop_val = WDOG_PREOP_NONE;
 		printk("ipmi_watchdog: Unknown preop '%s', defaulting to"
 		       " none\n", preop);
 	}
@@ -1008,7 +1024,7 @@
 
 	/*  Disable the timer. */
 	ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
-	ipmi_set_timeout();
+	ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
 
 	/* Wait to make sure the message makes it out.  The lower layer has
 	   pointers to our buffers, we want to make sure they are done before
@@ -1095,7 +1111,7 @@
 		else if (strcmp(option, "preop_panic") == 0) {
 			preop = "preop_panic";
 		}
-		else if (strcmp(option, "preop_none") == 0) {
+		else if (strcmp(option, "preop_give_data") == 0) {
 			preop = "preop_give_data";
 		} else {
 		    printk("Unknown IPMI watchdog option: '%s'\n", option);
diff -urN linux-2.4.21-rc3/drivers/char/tty_io.c linux-2.4.21-rc4/drivers/char/tty_io.c
--- linux-2.4.21-rc3/drivers/char/tty_io.c	2003-05-26 15:16:18.000000000 -0700
+++ linux-2.4.21-rc4/drivers/char/tty_io.c	2003-05-26 15:16:23.000000000 -0700
@@ -751,6 +751,10 @@
 	struct tty_struct * tty;
 	struct inode *inode = file->f_dentry->d_inode;
 
+	/* Can't seek (pwrite) on ttys.  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
 	/*
 	 *      For now, we redirect writes from /dev/console as
 	 *      well as /dev/tty0.
@@ -770,16 +774,12 @@
 		spin_unlock(&redirect_lock);
 
 		if (p) {
-			ssize_t res = p->f_op->write(p, buf, count, ppos);
+			ssize_t res = p->f_op->write(p, buf, count, &p->f_pos);
 			fput(p);
 			return res;
 		}
 	}
 
-	/* Can't seek (pwrite) on ttys.  */
-	if (ppos != &file->f_pos)
-		return -ESPIPE;
-
 	tty = (struct tty_struct *)file->private_data;
 	if (tty_paranoia_check(tty, inode->i_rdev, "tty_write"))
 		return -EIO;
diff -urN linux-2.4.21-rc3/drivers/ide/Config.in linux-2.4.21-rc4/drivers/ide/Config.in
--- linux-2.4.21-rc3/drivers/ide/Config.in	2003-05-26 15:16:18.000000000 -0700
+++ linux-2.4.21-rc4/drivers/ide/Config.in	2003-05-26 15:16:23.000000000 -0700
@@ -66,7 +66,9 @@
 	    dep_bool     '      Special UDMA Feature' CONFIG_PDC202XX_BURST $CONFIG_BLK_DEV_PDC202XX_OLD $CONFI_BLK_DEV_IDEDMA_PCI
 	    dep_tristate '    PROMISE PDC202{68|69|70|71|75|76|77} support' CONFIG_BLK_DEV_PDC202XX_NEW $CONFIG_BLK_DEV_IDEDMA_PCI
 		# FIXME - probably wants to be one for old and for new
-	    dep_bool     '    Special FastTrak Feature' CONFIG_PDC202XX_FORCE
+if [ "$CONFIG_BLK_DEV_PDC202XX_OLD" = "y" -o "$CONFIG_BLK_DEV_PDC202XX_OLD" = "m" -o "$CONFIG_BLK_DEV_PDC202XX_NEW" = "y" -o "$CONFIG_BLK_DEV_PDC202XX_NEW" = "m" ]; then
+	    bool     '    Special FastTrak Feature' CONFIG_PDC202XX_FORCE
+fi
 	    dep_tristate '    RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000 $CONFIG_X86
 	    dep_tristate '    SCx200 chipset support' CONFIG_BLK_DEV_SC1200 $CONFIG_BLK_DEV_IDEDMA_PCI
 	    dep_tristate '    ServerWorks OSB4/CSB5/CSB6 chipsets support' CONFIG_BLK_DEV_SVWKS $CONFIG_BLK_DEV_IDEDMA_PCI
@@ -82,6 +84,7 @@
       fi
       if [ "$CONFIG_ALL_PPC" = "y" ]; then
 	 bool '    Builtin PowerMac IDE support' CONFIG_BLK_DEV_IDE_PMAC
+	 dep_bool '      Probe internal Kauai ATA/100 first' CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST $CONFIG_BLK_DEV_IDE_PMAC
 	 dep_bool '      PowerMac IDE DMA support' CONFIG_BLK_DEV_IDEDMA_PMAC $CONFIG_BLK_DEV_IDE_PMAC
 	 dep_bool '        Use DMA by default' CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO $CONFIG_BLK_DEV_IDEDMA_PMAC
 	 if [ "$CONFIG_BLK_DEV_IDE_PMAC" = "y" ]; then
diff -urN linux-2.4.21-rc3/drivers/ide/ppc/pmac.c linux-2.4.21-rc4/drivers/ide/ppc/pmac.c
--- linux-2.4.21-rc3/drivers/ide/ppc/pmac.c	2003-05-26 15:16:18.000000000 -0700
+++ linux-2.4.21-rc4/drivers/ide/ppc/pmac.c	2003-05-26 15:16:23.000000000 -0700
@@ -48,7 +48,7 @@
 extern void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq);
 
 #undef IDE_PMAC_DEBUG
-#define DMA_WAIT_TIMEOUT	500
+#define DMA_WAIT_TIMEOUT	100
 
 typedef struct pmac_ide_hwif {
 	ide_ioreg_t			regbase;
@@ -940,10 +940,10 @@
 {
 	struct device_node *np;
 	int i;
-	struct device_node *atas;
-	struct device_node *p, **pp, *removables, **rp;
+	struct device_node *atas = NULL;
+	struct device_node *p, *nextp, **pp, *removables, **rp;
 	unsigned long base, regbase;
-	int irq, big_delay;
+	int irq;
 	ide_hwif_t *hwif;
 
 	if (_machine != _MACH_Pmac)
@@ -959,19 +959,29 @@
 		p = find_type_devices("ata");
 	/* Move removable devices such as the media-bay CDROM
 	   on the PB3400 to the end of the list. */
-	for (; p != NULL; p = p->next) {
+	for (; p != NULL; p = nextp) {
+		nextp = p->next;
 		if (p->parent && p->parent->type
 		    && strcasecmp(p->parent->type, "media-bay") == 0) {
 			*rp = p;
 			rp = &p->next;
-		} else {
+		}
+#ifdef CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST
+		/* Move Kauai ATA/100 if it exist to first postition in list */
+		else if (device_is_compatible(p, "kauai-ata")) {
+			p->next = atas;
+			if (pp == &atas)
+				pp = &p->next;
+			atas = p;
+		}
+#endif /* CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST */
+		else {
 			*pp = p;
 			pp = &p->next;
 		}
 	}
 	*rp = NULL;
 	*pp = removables;
-	big_delay = 0;
 
 	for (i = 0, np = atas; i < MAX_HWIFS && np != NULL; np = np->next) {
 		struct device_node *tp;
@@ -1128,7 +1138,6 @@
 			ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1);
 			mdelay(10);
 			ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 0);
-			big_delay = 1;
 		}
 
 		hwif = &ide_hwifs[i];
@@ -1142,6 +1151,7 @@
 		memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
 		hwif->chipset = ide_pmac;
 		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || in_bay;
+		hwif->hold = in_bay;
 		hwif->udma_four = pmif->cable_80;
 		hwif->pci_dev = pdev;
 		hwif->drives[0].unmask = 1;
@@ -1193,9 +1203,6 @@
 
 	if (pmac_ide_count == 0)
 		return;
-		
-	if (big_delay)
-		mdelay(IDE_WAKEUP_DELAY_MS);
 
 #ifdef CONFIG_PMAC_PBOOK
 	pmu_register_sleep_notifier(&idepmac_sleep_notifier);
@@ -1573,10 +1580,6 @@
 	drive->waiting_for_dma = 1;	
 	if (drive->media != ide_disk)
 		return 0;
-	/* paranoia check */
-	if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
-		BUG();
-	ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL);
 	/*
 	 * FIX ME to use only ACB ide_task_t args Struct
 	 */
@@ -1592,8 +1595,8 @@
 		command = args->tfRegister[IDE_COMMAND_OFFSET];
 	}
 #endif
-	/* issue cmd to drive */
-	hwif->OUTB(command, IDE_COMMAND_REG);
+	 /* issue cmd to drive */
+        ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL);
 
 	return pmac_ide_dma_begin(drive);
 }
@@ -1630,10 +1633,6 @@
 	if (drive->media != ide_disk)
 		return 0;
 
-	/* paranoia check */
-	if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
-		BUG();
-	ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL);
 	/*
 	 * FIX ME to use only ACB ide_task_t args Struct
 	 */
@@ -1650,7 +1649,7 @@
 	}
 #endif
 	/* issue cmd to drive */
-	hwif->OUTB(command, IDE_COMMAND_REG);
+        ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL);
 
 	return pmac_ide_dma_begin(drive);
 }
@@ -1693,7 +1692,11 @@
 	writel(((RUN|WAKE|DEAD) << 16), &dma->control);
 	pmac_ide_destroy_dmatable(drive);
 	/* verify good dma status */
-	return (dstat & (RUN|DEAD|ACTIVE)) != RUN;
+	if ((dstat & (RUN|DEAD|ACTIVE)) == RUN)	
+		return 0;
+	printk(KERN_WARNING "%s: bad status at DMA end, dstat=%x\n",
+		drive->name, dstat);
+	return 1;
 }
 
 static int __pmac
@@ -1735,18 +1738,18 @@
 	if (!(status & ACTIVE))
 		return 1;
 	if (!drive->waiting_for_dma)
-		printk(KERN_WARNING "ide%d, ide_dma_test_irq \
-			called while not waiting\n", HWIF(drive)->index);
+		printk(KERN_WARNING "%s: ide_dma_test_irq \
+			called while not waiting\n", drive->name);
 
 	/* If dbdma didn't execute the STOP command yet, the
 	 * active bit is still set */
 	drive->waiting_for_dma++;
 	if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
-		printk(KERN_WARNING "ide%d, timeout waiting \
-			for dbdma command stop\n", HWIF(drive)->index);
+		printk(KERN_WARNING "%s: timeout waiting \
+			for dbdma command stop\n", drive->name);
 		return 1;
 	}
-	udelay(1);
+	udelay(10);
 	return 0;
 }
 
@@ -1774,7 +1777,7 @@
 	dma = pmif->dma_regs;
 
 	status = readl(&dma->status);
-	printk(KERN_ERR "ide-pmac lost interrupt, dma status: %lx\n", status);
+	printk(KERN_ERR "%s: lost interrupt, dma status: %lx\n", drive->name, status);
 	return 0;
 }
 
diff -urN linux-2.4.21-rc3/drivers/video/controlfb.c linux-2.4.21-rc4/drivers/video/controlfb.c
--- linux-2.4.21-rc3/drivers/video/controlfb.c	2002-02-25 11:38:07.000000000 -0800
+++ linux-2.4.21-rc4/drivers/video/controlfb.c	2003-05-26 15:16:24.000000000 -0700
@@ -132,7 +132,7 @@
 };
 
 /* control register access macro */
-#define CNTRL_REG(INFO,REG) (&(((INFO)->control_regs-> ## REG).r))
+#define CNTRL_REG(INFO,REG) (&(((INFO)->control_regs->REG).r))
 
 
 /******************** Prototypes for exported functions ********************/
diff -urN linux-2.4.21-rc3/include/asm-i386/processor.h linux-2.4.21-rc4/include/asm-i386/processor.h
--- linux-2.4.21-rc3/include/asm-i386/processor.h	2003-05-26 15:16:20.000000000 -0700
+++ linux-2.4.21-rc4/include/asm-i386/processor.h	2003-05-26 15:16:24.000000000 -0700
@@ -281,6 +281,7 @@
  * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
  */
 #define IO_BITMAP_SIZE	32
+#define IO_BITMAP_BYTES (IO_BITMAP_SIZE * 4)
 #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
 #define INVALID_IO_BITMAP_OFFSET 0x8000
 
diff -urN linux-2.4.21-rc3/include/asm-ppc/delay.h linux-2.4.21-rc4/include/asm-ppc/delay.h
--- linux-2.4.21-rc3/include/asm-ppc/delay.h	2003-05-26 15:16:20.000000000 -0700
+++ linux-2.4.21-rc4/include/asm-ppc/delay.h	2003-05-26 15:16:25.000000000 -0700
@@ -30,8 +30,8 @@
  * (which corresponds to ~3800 bogomips at HZ = 100).
  *  -- paulus
  */
-#define __MAX_UDELAY	(226050910/HZ)	/* maximum udelay argument */
-#define __MAX_NDELAY	(4294967295/HZ)	/* maximum ndelay argument */
+#define __MAX_UDELAY	(226050910UL/HZ)	/* maximum udelay argument */
+#define __MAX_NDELAY	(4294967295UL/HZ)	/* maximum ndelay argument */
 
 extern __inline__ void __udelay(unsigned int x)
 {
diff -urN linux-2.4.21-rc3/kernel/ksyms.c linux-2.4.21-rc4/kernel/ksyms.c
--- linux-2.4.21-rc3/kernel/ksyms.c	2003-05-26 15:16:20.000000000 -0700
+++ linux-2.4.21-rc4/kernel/ksyms.c	2003-05-26 15:16:25.000000000 -0700
@@ -65,6 +65,7 @@
 extern int request_dma(unsigned int dmanr, char * deviceID);
 extern void free_dma(unsigned int dmanr);
 extern spinlock_t dma_spin_lock;
+extern int panic_timeout;
 
 #ifdef CONFIG_MODVERSIONS
 const struct module_symbol __export_Using_Versions
@@ -471,6 +472,8 @@
 
 /* misc */
 EXPORT_SYMBOL(panic);
+EXPORT_SYMBOL(panic_notifier_list);
+EXPORT_SYMBOL(panic_timeout);
 EXPORT_SYMBOL(__out_of_line_bug);
 EXPORT_SYMBOL(sprintf);
 EXPORT_SYMBOL(snprintf);
