# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	v2.5.64 -> 1.1094 
#	 drivers/video/tcx.c	1.1     -> 1.4    
#	include/linux/kernel.h	1.33    -> 1.34   
#	drivers/scsi/scsi_error.c	1.38    -> 1.39   
#	drivers/oprofile/cpu_buffer.c	1.5     -> 1.6    
#	include/linux/jiffies.h	1.7     -> 1.8    
#	  drivers/net/dgrs.c	1.14    -> 1.15   
#	arch/i386/oprofile/op_model_p4.c	1.2     -> 1.3    
#	drivers/video/sbuslib.h	1.1     -> 1.3    
#	drivers/parport/ieee1284.c	1.5     -> 1.6    
#	drivers/cpufreq/userspace.c	1.1     -> 1.2    
#	drivers/base/platform.c	1.6     -> 1.7    
#	include/linux/if_shaper.h	1.1     -> 1.2    
#	drivers/oprofile/buffer_sync.c	1.8     -> 1.9    
#	 drivers/video/cg6.c	1.1     -> 1.4    
#	drivers/video/sbuslib.c	1.1     -> 1.3    
#	sound/pci/ac97/ac97_codec.c	1.29    -> 1.30   
#	drivers/net/sis900.c	1.33    -> 1.34   
#	include/linux/profile.h	1.4     -> 1.5    
#	 include/linux/tty.h	1.8     -> 1.9    
#	 drivers/video/bw2.c	1.1     -> 1.4    
#	sound/pci/intel8x0.c	1.26    -> 1.27   
#	 drivers/video/cg3.c	1.1     -> 1.4    
#	drivers/oprofile/oprofile_stats.c	1.2     -> 1.3    
#	drivers/video/p9100.c	1.1     -> 1.4    
#	drivers/net/shaper.c	1.12    -> 1.13   
#	drivers/scsi/qlogicfc.c	1.27    -> 1.28   
#	    fs/filesystems.c	1.11    -> 1.12   
#	    fs/sysfs/mount.c	1.5     -> 1.6    
#	arch/sparc64/Kconfig	1.14    -> 1.15   
#	arch/i386/oprofile/nmi_int.c	1.8     -> 1.9    
#	drivers/oprofile/cpu_buffer.h	1.3     -> 1.4    
#	drivers/video/cg14.c	1.1     -> 1.4    
#	drivers/parport/ieee1284_ops.c	1.9     -> 1.10   
#	 drivers/video/ffb.c	1.1     -> 1.4    
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/03/04	torvalds@home.transmeta.com	1.1085
# Linux 2.5.64
# --------------------------------------------
# 03/03/05	davem@redhat.com	1.1086
# [PATCH] Fix time comparison typing bugs.
# 
# Many places use inappropriate types for comparing jiffies,
# int for example.  Fix those places up.
# --------------------------------------------
# 03/03/05	davem@nuts.ninka.net	1.1087
# Merge nuts.ninka.net:/home/davem/src/BK/sparcwork-2.5
# into nuts.ninka.net:/home/davem/src/BK/sparc-2.5
# --------------------------------------------
# 03/03/05	davem@nuts.ninka.net	1.1088
# [SPARC64]: Fix cpufreq config deps.
# --------------------------------------------
# 03/03/05	andmike@us.ibm.com	1.1089
# [PATCH] Fix SCSI error handler abort case
# 
# I had my list empty checks reversed if aborting and bus device reset
# failed.  The condition that causes the error handler to run is still
# unknown.
# --------------------------------------------
# 03/03/05	levon@movementarian.org	1.1090
# [PATCH] Fix oprofile on UP, small additional fix
# 
# The below has been in -mm for a while, and has been tested on my UP
# and 2-way machines.
# 
# OProfile was completely unsafe on UP - a spinlock is no protection
# against the NMI arriving and putting data into the buffer. Pretty stupid
# bug. This fixes it by implementing reader/writer windows in the buffer
# and removing the lock altogether. This patch was originally done by Will
# Cohen.
# 
# It also fixes the oops Dave Hansen saw on 2.5.62 SMP
# --------------------------------------------
# 03/03/05	mochel@osdl.org	1.1086.1.1
# sysfs: Make sure root inode is executable and readable by everyone.
# --------------------------------------------
# 03/03/05	mochel@osdl.org	1.1086.1.2
# driver model: fix platform_match()
# 
# - Make it compare the name in struct platform_dev to the driver's name.
# 
# From Dominik Brodowski
# --------------------------------------------
# 03/03/05	mochel@osdl.org	1.1086.1.3
# sysfs: don't complain when sysfs can't register.
# 
# During startup, sysfs won't succeed in registering with itself, because
# it's not yet inititialized. This was causing an unnecessary error on boot.
# --------------------------------------------
# 03/03/05	mochel@osdl.org	1.1086.1.4
# cpufreq: fix compile error.
# 
# Use ->dev instead of ->intf.dev in struct cpufreq_policy. Introduced whilst
# cleaning up part of the cpufreq code. 
# --------------------------------------------
# 03/03/05	torvalds@home.transmeta.com	1.1091
# Merge bk://ldm.bkbits.net/linux-2.5-core
# into home.transmeta.com:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/03/05	davem@nuts.ninka.net	1.1092
# [KERNEL]: Add typecheck macro for verifying types at compile time.
# --------------------------------------------
# 03/03/05	davem@nuts.ninka.net	1.1093
# [JIFFIES]: Use typecheck in time_foo jiffies macros.
# --------------------------------------------
# 03/03/05	torvalds@home.transmeta.com	1.1094
# Fix up some timeouts to use the proper types.
# 
# (While "signed long" is the same in practice, it is technically
# incorrect, and the new anal type-checker complains).
# --------------------------------------------
#
diff -Nru a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
--- a/arch/i386/oprofile/nmi_int.c	Wed Mar  5 22:23:02 2003
+++ b/arch/i386/oprofile/nmi_int.c	Wed Mar  5 22:23:02 2003
@@ -58,7 +58,7 @@
 	unsigned int const nr_ctrls = model->num_controls; 
 	struct op_msr_group * counters = &msrs->counters;
 	struct op_msr_group * controls = &msrs->controls;
-	int i;
+	unsigned int i;
 
 	for (i = 0; i < nr_ctrs; ++i) {
 		rdmsr(counters->addrs[i],
@@ -108,7 +108,7 @@
 	unsigned int const nr_ctrls = model->num_controls; 
 	struct op_msr_group * counters = &msrs->counters;
 	struct op_msr_group * controls = &msrs->controls;
-	int i;
+	unsigned int i;
 
 	for (i = 0; i < nr_ctrls; ++i) {
 		wrmsr(controls->addrs[i],
@@ -182,7 +182,7 @@
 
 static int nmi_create_files(struct super_block * sb, struct dentry * root)
 {
-	int i;
+	unsigned int i;
 
 	for (i = 0; i < model->num_counters; ++i) {
 		struct dentry * dir;
diff -Nru a/arch/i386/oprofile/op_model_p4.c b/arch/i386/oprofile/op_model_p4.c
--- a/arch/i386/oprofile/op_model_p4.c	Wed Mar  5 22:23:02 2003
+++ b/arch/i386/oprofile/op_model_p4.c	Wed Mar  5 22:23:02 2003
@@ -389,7 +389,7 @@
 
 static void p4_fill_in_addresses(struct op_msrs * const msrs)
 {
-	int i; 
+	unsigned int i; 
 	unsigned int addr, stag;
 
 	setup_num_counters();
diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
--- a/arch/sparc64/Kconfig	Wed Mar  5 22:23:02 2003
+++ b/arch/sparc64/Kconfig	Wed Mar  5 22:23:02 2003
@@ -151,9 +151,14 @@
 	  If in doubt, say N.
 
 config CPU_FREQ_TABLE
-       tristate
+       tristate "CPU frequency table helpers"
+       depends on CPU_FREQ
        default y
+       help
+         Many CPUFreq drivers use these helpers, so only say N here if
+	 the CPUFreq driver of your choice doesn't need these helpers.
 
+	 If in doubt, say Y.
 
 config US3_FREQ
 	tristate "UltraSPARC-III CPU Frequency driver"
diff -Nru a/drivers/base/platform.c b/drivers/base/platform.c
--- a/drivers/base/platform.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/base/platform.c	Wed Mar  5 22:23:02 2003
@@ -59,12 +59,9 @@
 
 static int platform_match(struct device * dev, struct device_driver * drv)
 {
-	char name[BUS_ID_SIZE];
+	struct platform_device *pdev = container_of(dev, struct platform_device, dev);
 
-	if (sscanf(dev->bus_id,"%s",name))
-		return (strcmp(name,drv->name) == 0);
-
-	return 0;
+	return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);
 }
 
 struct bus_type platform_bus_type = {
diff -Nru a/drivers/cpufreq/userspace.c b/drivers/cpufreq/userspace.c
--- a/drivers/cpufreq/userspace.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/cpufreq/userspace.c	Wed Mar  5 22:23:02 2003
@@ -511,7 +511,7 @@
 		cpu_min_freq[cpu] = policy->min;
 		cpu_max_freq[cpu] = policy->max;
 		cpu_cur_freq[cpu] = policy->cur;
-		device_create_file (policy->intf.dev, &dev_attr_scaling_setspeed);
+		device_create_file (policy->dev, &dev_attr_scaling_setspeed);
 		memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
 		up(&userspace_sem);
 		break;
@@ -520,7 +520,7 @@
 		cpu_is_managed[cpu] = 0;
 		cpu_min_freq[cpu] = 0;
 		cpu_max_freq[cpu] = 0;
-		device_remove_file (policy->intf.dev, &dev_attr_scaling_setspeed);
+		device_remove_file (policy->dev, &dev_attr_scaling_setspeed);
 		up(&userspace_sem);
 		module_put(THIS_MODULE);
 		break;
diff -Nru a/drivers/net/dgrs.c b/drivers/net/dgrs.c
--- a/drivers/net/dgrs.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/net/dgrs.c	Wed Mar  5 22:23:02 2003
@@ -981,7 +981,7 @@
 {
 	DGRS_PRIV	*priv0 = (DGRS_PRIV *) dev0->priv;
 	int		is;
-	int		i;
+	unsigned long	i;
 
 	static int	iv2is[16] = {
 				0, 0, 0, ES4H_IS_INT3,
@@ -1140,7 +1140,7 @@
 dgrs_probe1(struct net_device *dev)
 {
 	DGRS_PRIV	*priv = (DGRS_PRIV *) dev->priv;
-	int		i;
+	unsigned long	i;
 	int		rc;
 
 	printk("%s: Digi RightSwitch io=%lx mem=%lx irq=%d plx=%lx dma=%lx\n",
diff -Nru a/drivers/net/shaper.c b/drivers/net/shaper.c
--- a/drivers/net/shaper.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/net/shaper.c	Wed Mar  5 22:23:02 2003
@@ -88,10 +88,10 @@
 #include <net/arp.h>
 
 struct shaper_cb { 
+	unsigned long	shapeclock;		/* Time it should go out */
+	unsigned long	shapestamp;		/* Stamp for shaper    */
 	__u32		shapelatency;		/* Latency on frame */
-	__u32		shapeclock;		/* Time it should go out */
 	__u32		shapelen;		/* Frame length in clocks */
-	__u32		shapestamp;		/* Stamp for shaper    */
 	__u16		shapepend;		/* Pending */
 }; 
 #define SHAPERCB(skb) ((struct shaper_cb *) ((skb)->cb))
@@ -335,7 +335,7 @@
 		 */
 		 
 		if(sh_debug)
-			printk("Clock = %d, jiffies = %ld\n", SHAPERCB(skb)->shapeclock, jiffies);
+			printk("Clock = %ld, jiffies = %ld\n", SHAPERCB(skb)->shapeclock, jiffies);
 		if(time_before_eq(SHAPERCB(skb)->shapeclock - jiffies, SHAPER_BURST))
 		{
 			/*
diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/net/sis900.c	Wed Mar  5 22:23:02 2003
@@ -509,7 +509,7 @@
 {
 	struct sis900_private * sis_priv = net_dev->priv;
 	u16 poll_bit = MII_STAT_LINK, status = 0;
-	unsigned int timeout = jiffies + 5 * HZ;
+	unsigned long timeout = jiffies + 5 * HZ;
 	int phy_addr;
 	u8 revision;
 
diff -Nru a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
--- a/drivers/oprofile/buffer_sync.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/oprofile/buffer_sync.c	Wed Mar  5 22:23:02 2003
@@ -277,10 +277,7 @@
  */
 static struct mm_struct * take_task_mm(struct task_struct * task)
 {
-	struct mm_struct * mm;
-	task_lock(task);
-	mm = task->mm;
-	task_unlock(task);
+	struct mm_struct * mm = task->mm;
  
 	/* if task->mm !NULL, mm_count must be at least 1. It cannot
 	 * drop to 0 without the task exiting, which will have to sleep
@@ -310,6 +307,32 @@
 }
  
 
+/* compute number of filled slots in cpu_buffer queue */
+static unsigned long nr_filled_slots(struct oprofile_cpu_buffer * b)
+{
+	unsigned long head = b->head_pos;
+	unsigned long tail = b->tail_pos;
+
+	if (head >= tail)
+		return head - tail;
+
+	return head + (b->buffer_size - tail);
+}
+
+
+static void increment_tail(struct oprofile_cpu_buffer * b)
+{
+	unsigned long new_tail = b->tail_pos + 1;
+
+	rmb();
+
+	if (new_tail < (b->buffer_size))
+		b->tail_pos = new_tail;
+	else
+		b->tail_pos = 0;
+}
+
+
 /* Sync one of the CPU's buffers into the global event buffer.
  * Here we need to go through each batch of samples punctuated
  * by context switch notes, taking the task's mmap_sem and doing
@@ -322,10 +345,14 @@
 	struct task_struct * new;
 	unsigned long cookie;
 	int in_kernel = 1;
-	int i;
+	unsigned int i;
  
-	for (i=0; i < cpu_buf->pos; ++i) {
-		struct op_sample * s = &cpu_buf->buffer[i];
+	/* Remember, only we can modify tail_pos */
+
+	unsigned long const available_elements = nr_filled_slots(cpu_buf);
+  
+	for (i=0; i < available_elements; ++i) {
+		struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
  
 		if (is_ctx_switch(s->eip)) {
 			if (s->event <= 1) {
@@ -345,6 +372,8 @@
 		} else {
 			add_sample(mm, s, in_kernel);
 		}
+
+		increment_tail(cpu_buf);
 	}
 	release_mm(mm);
 
@@ -369,17 +398,8 @@
  
 		cpu_buf = &cpu_buffer[i];
  
-		/* We take a spin lock even though we might
-		 * sleep. It's OK because other users are try
-		 * lockers only, and this region is already
-		 * protected by buffer_sem. It's raw to prevent
-		 * the preempt bogometer firing. Fruity, huh ? */
-		if (cpu_buf->pos > 0) {
-			_raw_spin_lock(&cpu_buf->int_lock);
-			add_cpu_switch(i);
-			sync_buffer(cpu_buf);
-			_raw_spin_unlock(&cpu_buf->int_lock);
-		}
+		add_cpu_switch(i);
+		sync_buffer(cpu_buf);
 	}
 
 	up(&buffer_sem);
diff -Nru a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
--- a/drivers/oprofile/cpu_buffer.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/oprofile/cpu_buffer.c	Wed Mar  5 22:23:02 2003
@@ -26,8 +26,6 @@
 
 struct oprofile_cpu_buffer cpu_buffer[NR_CPUS] __cacheline_aligned;
 
-static unsigned long buffer_size;
- 
 static void __free_cpu_buffers(int num)
 {
 	int i;
@@ -47,7 +45,7 @@
 {
 	int i;
  
-	buffer_size = fs_cpu_buffer_size;
+	unsigned long buffer_size = fs_cpu_buffer_size;
  
 	for (i=0; i < NR_CPUS; ++i) {
 		struct oprofile_cpu_buffer * b = &cpu_buffer[i];
@@ -59,12 +57,12 @@
 		if (!b->buffer)
 			goto fail;
  
-		spin_lock_init(&b->int_lock);
-		b->pos = 0;
 		b->last_task = 0;
 		b->last_is_kernel = -1;
+		b->buffer_size = buffer_size;
+		b->tail_pos = 0;
+		b->head_pos = 0;
 		b->sample_received = 0;
-		b->sample_lost_locked = 0;
 		b->sample_lost_overflow = 0;
 		b->sample_lost_task_exit = 0;
 	}
@@ -80,11 +78,41 @@
 	__free_cpu_buffers(NR_CPUS);
 }
 
- 
-/* Note we can't use a semaphore here as this is supposed to
- * be safe from any context. Instead we trylock the CPU's int_lock.
- * int_lock is taken by the processing code in sync_cpu_buffers()
- * so we avoid disturbing that.
+
+/* compute number of available slots in cpu_buffer queue */
+static unsigned long nr_available_slots(struct oprofile_cpu_buffer const * b)
+{
+	unsigned long head = b->head_pos;
+	unsigned long tail = b->tail_pos;
+
+	if (tail == head)
+		return b->buffer_size;
+
+	if (tail > head)
+		return tail - head;
+
+	return tail + (b->buffer_size - head);
+}
+
+
+static void increment_head(struct oprofile_cpu_buffer * b)
+{
+	unsigned long new_head = b->head_pos + 1;
+
+	/* Ensure anything written to the slot before we
+	 * increment is visible */
+	wmb();
+
+	if (new_head < (b->buffer_size))
+		b->head_pos = new_head;
+	else
+		b->head_pos = 0;
+}
+
+
+/* This must be safe from any context. It's safe writing here
+ * because of the head/tail separation of the writer and reader
+ * of the CPU buffer.
  *
  * is_kernel is needed because on some architectures you cannot
  * tell if you are in kernel or user space simply by looking at
@@ -101,14 +129,10 @@
 
 	cpu_buf->sample_received++;
  
-	if (!spin_trylock(&cpu_buf->int_lock)) {
-		cpu_buf->sample_lost_locked++;
-		return;
-	}
 
-	if (cpu_buf->pos > buffer_size - 2) {
+	if (nr_available_slots(cpu_buf) < 3) {
 		cpu_buf->sample_lost_overflow++;
-		goto out;
+		return;
 	}
 
 	task = current;
@@ -116,18 +140,18 @@
 	/* notice a switch from user->kernel or vice versa */
 	if (cpu_buf->last_is_kernel != is_kernel) {
 		cpu_buf->last_is_kernel = is_kernel;
-		cpu_buf->buffer[cpu_buf->pos].eip = ~0UL;
-		cpu_buf->buffer[cpu_buf->pos].event = is_kernel;
-		cpu_buf->pos++;
+		cpu_buf->buffer[cpu_buf->head_pos].eip = ~0UL;
+		cpu_buf->buffer[cpu_buf->head_pos].event = is_kernel;
+		increment_head(cpu_buf);
 	}
 
 	/* notice a task switch */
 	if (cpu_buf->last_task != task) {
 		cpu_buf->last_task = task;
 		if (!(task->flags & PF_EXITING)) {
-			cpu_buf->buffer[cpu_buf->pos].eip = ~0UL;
-			cpu_buf->buffer[cpu_buf->pos].event = (unsigned long)task;
-			cpu_buf->pos++;
+			cpu_buf->buffer[cpu_buf->head_pos].eip = ~0UL;
+			cpu_buf->buffer[cpu_buf->head_pos].event = (unsigned long)task;
+			increment_head(cpu_buf);
 		}
 	}
  
@@ -138,23 +162,20 @@
 	 */
 	if (task->flags & PF_EXITING) {
 		cpu_buf->sample_lost_task_exit++;
-		goto out;
+		return;
 	}
  
-	cpu_buf->buffer[cpu_buf->pos].eip = eip;
-	cpu_buf->buffer[cpu_buf->pos].event = event;
-	cpu_buf->pos++;
-out:
-	spin_unlock(&cpu_buf->int_lock);
+	cpu_buf->buffer[cpu_buf->head_pos].eip = eip;
+	cpu_buf->buffer[cpu_buf->head_pos].event = event;
+	increment_head(cpu_buf);
 }
 
+
 /* resets the cpu buffer to a sane state - should be called with 
  * cpu_buf->int_lock held
  */
 void cpu_buffer_reset(struct oprofile_cpu_buffer *cpu_buf)
 {
-	cpu_buf->pos = 0;
-
 	/* reset these to invalid values; the next sample
 	 * collected will populate the buffer with proper
 	 * values to initialize the buffer
@@ -162,4 +183,3 @@
 	cpu_buf->last_is_kernel = -1;
 	cpu_buf->last_task = 0;
 }
-
diff -Nru a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h
--- a/drivers/oprofile/cpu_buffer.h	Wed Mar  5 22:23:02 2003
+++ b/drivers/oprofile/cpu_buffer.h	Wed Mar  5 22:23:02 2003
@@ -30,14 +30,13 @@
 };
  
 struct oprofile_cpu_buffer {
-	spinlock_t int_lock;
-	/* protected by int_lock */
-	unsigned long pos;
+	volatile unsigned long head_pos;
+	volatile unsigned long tail_pos;
+	unsigned long buffer_size;
 	struct task_struct * last_task;
 	int last_is_kernel;
 	struct op_sample * buffer;
 	unsigned long sample_received;
-	unsigned long sample_lost_locked;
 	unsigned long sample_lost_overflow;
 	unsigned long sample_lost_task_exit;
 } ____cacheline_aligned;
diff -Nru a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c
--- a/drivers/oprofile/oprofile_stats.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/oprofile/oprofile_stats.c	Wed Mar  5 22:23:02 2003
@@ -27,7 +27,6 @@
 
 		cpu_buf = &cpu_buffer[i]; 
 		cpu_buf->sample_received = 0;
-		cpu_buf->sample_lost_locked = 0;
 		cpu_buf->sample_lost_overflow = 0;
 		cpu_buf->sample_lost_task_exit = 0;
 	}
@@ -63,8 +62,6 @@
 		 */
 		oprofilefs_create_ro_ulong(sb, cpudir, "sample_received",
 			&cpu_buf->sample_received);
-		oprofilefs_create_ro_ulong(sb, cpudir, "sample_lost_locked",
-			&cpu_buf->sample_lost_locked);
 		oprofilefs_create_ro_ulong(sb, cpudir, "sample_lost_overflow",
 			&cpu_buf->sample_lost_overflow);
 		oprofilefs_create_ro_ulong(sb, cpudir, "sample_lost_task_exit",
diff -Nru a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c
--- a/drivers/parport/ieee1284.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/parport/ieee1284.c	Wed Mar  5 22:23:02 2003
@@ -170,7 +170,7 @@
 {
 	int ret;
 	int usec;
-	long deadline;
+	unsigned long deadline;
 	unsigned char status;
 
 	usec = port->physport->spintime; /* usecs of fast polling */
diff -Nru a/drivers/parport/ieee1284_ops.c b/drivers/parport/ieee1284_ops.c
--- a/drivers/parport/ieee1284_ops.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/parport/ieee1284_ops.c	Wed Mar  5 22:23:02 2003
@@ -58,7 +58,7 @@
 	parport_write_control (port, ctl);
 	parport_data_forward (port);
 	while (count < len) {
-		long expire = jiffies + dev->timeout;
+		unsigned long expire = jiffies + dev->timeout;
 		long wait = (HZ + 99) / 100;
 		unsigned char mask = (PARPORT_STATUS_ERROR
 				      | PARPORT_STATUS_BUSY);
@@ -431,7 +431,7 @@
 			      | PARPORT_CONTROL_INIT,
 			      PARPORT_CONTROL_INIT);
 	for (written = 0; written < len; written++, buf++) {
-		long expire = jiffies + port->cad->timeout;
+		unsigned long expire = jiffies + port->cad->timeout;
 		unsigned char byte;
 
 		byte = *buf;
@@ -520,7 +520,7 @@
 	parport_write_control (port,
 			       ctl | PARPORT_CONTROL_AUTOFD);
 	while (count < len) {
-		long expire = jiffies + dev->timeout;
+		unsigned long expire = jiffies + dev->timeout;
 		unsigned char byte;
 		int command;
 
@@ -668,7 +668,7 @@
 			      PARPORT_CONTROL_AUTOFD
 			      | PARPORT_CONTROL_INIT);
 	for (written = 0; written < len; written++, buf++) {
-		long expire = jiffies + port->cad->timeout;
+		unsigned long expire = jiffies + port->cad->timeout;
 		unsigned char byte;
 
 		byte = *buf;
diff -Nru a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c
--- a/drivers/scsi/qlogicfc.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/scsi/qlogicfc.c	Wed Mar  5 22:23:02 2003
@@ -694,7 +694,7 @@
 int isp2x00_detect(Scsi_Host_Template * tmpt)
 {
 	int hosts = 0;
-	int wait_time;
+	unsigned long wait_time;
 	struct Scsi_Host *host = NULL;
 	struct isp2x00_hostdata *hostdata;
 	struct pci_dev *pdev;
diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
--- a/drivers/scsi/scsi_error.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/scsi/scsi_error.c	Wed Mar  5 22:23:02 2003
@@ -1490,9 +1490,9 @@
 			       struct list_head *work_q,
 			       struct list_head *done_q)
 {
-	if (scsi_eh_bus_device_reset(shost, work_q, done_q))
-		if (scsi_eh_bus_reset(shost, work_q, done_q))
-			if (scsi_eh_host_reset(work_q, done_q))
+	if (!scsi_eh_bus_device_reset(shost, work_q, done_q))
+		if (!scsi_eh_bus_reset(shost, work_q, done_q))
+			if (!scsi_eh_host_reset(work_q, done_q))
 				scsi_eh_offline_sdevs(work_q, done_q);
 }
 
diff -Nru a/drivers/video/bw2.c b/drivers/video/bw2.c
--- a/drivers/video/bw2.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/video/bw2.c	Wed Mar  5 22:23:02 2003
@@ -33,11 +33,11 @@
  * Local functions.
  */
 
-static int bw2_check_var(struct fb_var_screeninfo *, struct fb_info *);
-static int bw2_set_par(struct fb_info *);
 static int bw2_blank(int, struct fb_info *);
 
 static int bw2_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
+static int bw2_ioctl(struct inode *, struct file *, unsigned int,
+		     unsigned long, struct fb_info *);
 
 /*
  *  Frame buffer operations
@@ -45,13 +45,12 @@
 
 static struct fb_ops bw2_ops = {
 	.owner			= THIS_MODULE,
-	.fb_check_var		= bw2_check_var,
-	.fb_set_par		= bw2_set_par,
 	.fb_blank		= bw2_blank,
 	.fb_fillrect		= cfb_fillrect,
 	.fb_copyarea		= cfb_copyarea,
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= bw2_mmap,
+	.fb_ioctl		= bw2_ioctl,
 	.fb_cursor		= soft_cursor,
 };
 
@@ -124,39 +123,6 @@
 };
 
 /**
- *      bw2_check_var - Optional function.  Validates a var passed in.
- *      @var: frame buffer variable screen structure
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int bw2_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	if (var->bits_per_pixel != 8)
-		return -EINVAL;
-
-	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
-		return -EINVAL;
-	if (var->nonstd)
-		return -EINVAL;
-	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
-		return -EINVAL;
-
-	if (var->xres != info->var.xres || var->yres != info->var.yres)
-		return -EINVAL;
-
-	return 0;
-}
-
-/**
- *      bw2_set_par - Optional function.  Alters the hardware state.
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int
-bw2_set_par(struct fb_info *info)
-{
-	return 0;
-}
-
-/**
  *      bw2_blank - Optional function.  Blanks the display.
  *      @blank_mode: the blank mode we want.
  *      @info: frame buffer structure that represents a single frame buffer
@@ -212,6 +178,15 @@
 				  vma);
 }
 
+static int bw2_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		     unsigned long arg, struct fb_info *info)
+{
+	struct bw2_par *par = (struct bw2_par *) info->par;
+
+	return sbusfb_ioctl_helper(cmd, arg, info,
+				   FBTYPE_SUN2BW, 1, par->fbsize);
+}
+
 /*
  *  Initialisation
  */
@@ -387,7 +362,6 @@
 
 	bw2_blank(0, &all->info);
 
-	bw2_set_par(&all->info);
 	bw2_init_fix(&all->info, linebytes);
 
 	if (register_framebuffer(&all->info) < 0) {
diff -Nru a/drivers/video/cg14.c b/drivers/video/cg14.c
--- a/drivers/video/cg14.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/video/cg14.c	Wed Mar  5 22:23:02 2003
@@ -28,8 +28,6 @@
  * Local functions.
  */
 
-static int cg14_check_var(struct fb_var_screeninfo *, struct fb_info *);
-static int cg14_set_par(struct fb_info *);
 static int cg14_setcolreg(unsigned, unsigned, unsigned, unsigned,
 			 unsigned, struct fb_info *);
 
@@ -43,8 +41,6 @@
 
 static struct fb_ops cg14_ops = {
 	.owner			= THIS_MODULE,
-	.fb_check_var		= cg14_check_var,
-	.fb_set_par		= cg14_set_par,
 	.fb_setcolreg		= cg14_setcolreg,
 	.fb_fillrect		= cfb_fillrect,
 	.fb_copyarea		= cfb_copyarea,
@@ -220,39 +216,6 @@
 }
 
 /**
- *      cg14_check_var - Optional function.  Validates a var passed in.
- *      @var: frame buffer variable screen structure
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int cg14_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	if (var->bits_per_pixel != 8)
-		return -EINVAL;
-
-	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
-		return -EINVAL;
-	if (var->nonstd)
-		return -EINVAL;
-	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
-		return -EINVAL;
-
-	if (var->xres != info->var.xres || var->yres != info->var.yres)
-		return -EINVAL;
-
-	return 0;
-}
-
-/**
- *      cg14_set_par - Optional function.  Alters the hardware state.
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int
-cg14_set_par(struct fb_info *info)
-{
-	return 0;
-}
-
-/**
  *      cg14_setcolreg - Optional function. Sets a color register.
  *      @regno: boolean, 0 copy local, 1 get_user() function
  *      @red: frame buffer colormap structure
@@ -358,7 +321,8 @@
 		break;
 
 	default:
-		ret = -EINVAL;
+		ret = sbusfb_ioctl_helper(cmd, arg, info,
+					  FBTYPE_MDICOLOR, 24, par->fbsize);
 		break;
 	};
 
@@ -523,7 +487,6 @@
 		return;
 	}
 
-	cg14_set_par(&all->info);
 	cg14_init_fix(&all->info, linebytes);
 
 	if (register_framebuffer(&all->info) < 0) {
diff -Nru a/drivers/video/cg3.c b/drivers/video/cg3.c
--- a/drivers/video/cg3.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/video/cg3.c	Wed Mar  5 22:23:02 2003
@@ -29,13 +29,13 @@
  * Local functions.
  */
 
-static int cg3_check_var(struct fb_var_screeninfo *, struct fb_info *);
-static int cg3_set_par(struct fb_info *);
 static int cg3_setcolreg(unsigned, unsigned, unsigned, unsigned,
 			 unsigned, struct fb_info *);
 static int cg3_blank(int, struct fb_info *);
 
 static int cg3_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
+static int cg3_ioctl(struct inode *, struct file *, unsigned int,
+		     unsigned long, struct fb_info *);
 
 /*
  *  Frame buffer operations
@@ -43,14 +43,13 @@
 
 static struct fb_ops cg3_ops = {
 	.owner			= THIS_MODULE,
-	.fb_check_var		= cg3_check_var,
-	.fb_set_par		= cg3_set_par,
 	.fb_setcolreg		= cg3_setcolreg,
 	.fb_blank		= cg3_blank,
 	.fb_fillrect		= cfb_fillrect,
 	.fb_copyarea		= cfb_copyarea,
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= cg3_mmap,
+	.fb_ioctl		= cg3_ioctl,
 	.fb_cursor		= soft_cursor,
 };
 
@@ -127,39 +126,6 @@
 };
 
 /**
- *      cg3_check_var - Optional function.  Validates a var passed in.
- *      @var: frame buffer variable screen structure
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int cg3_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	if (var->bits_per_pixel != 8)
-		return -EINVAL;
-
-	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
-		return -EINVAL;
-	if (var->nonstd)
-		return -EINVAL;
-	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
-		return -EINVAL;
-
-	if (var->xres != info->var.xres || var->yres != info->var.yres)
-		return -EINVAL;
-
-	return 0;
-}
-
-/**
- *      cg3_set_par - Optional function.  Alters the hardware state.
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int
-cg3_set_par(struct fb_info *info)
-{
-	return 0;
-}
-
-/**
  *      cg3_setcolreg - Optional function. Sets a color register.
  *      @regno: boolean, 0 copy local, 1 get_user() function
  *      @red: frame buffer colormap structure
@@ -269,6 +235,15 @@
 				  vma);
 }
 
+static int cg3_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		     unsigned long arg, struct fb_info *info)
+{
+	struct cg3_par *par = (struct cg3_par *) info->par;
+
+	return sbusfb_ioctl_helper(cmd, arg, info,
+				   FBTYPE_SUN3COLOR, 8, par->fbsize);
+}
+
 /*
  *  Initialisation
  */
@@ -445,7 +420,6 @@
 		return;
 	}
 
-	cg3_set_par(&all->info);
 	cg3_init_fix(&all->info, linebytes);
 
 	if (register_framebuffer(&all->info) < 0) {
diff -Nru a/drivers/video/cg6.c b/drivers/video/cg6.c
--- a/drivers/video/cg6.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/video/cg6.c	Wed Mar  5 22:23:02 2003
@@ -29,8 +29,6 @@
  * Local functions.
  */
 
-static int cg6_check_var(struct fb_var_screeninfo *, struct fb_info *);
-static int cg6_set_par(struct fb_info *);
 static int cg6_setcolreg(unsigned, unsigned, unsigned, unsigned,
 			 unsigned, struct fb_info *);
 static int cg6_blank(int, struct fb_info *);
@@ -39,6 +37,8 @@
 static void cg6_fillrect(struct fb_info *, struct fb_fillrect *);
 static int cg6_sync(struct fb_info *);
 static int cg6_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
+static int cg6_ioctl(struct inode *, struct file *, unsigned int,
+		     unsigned long, struct fb_info *);
 
 /*
  *  Frame buffer operations
@@ -46,8 +46,6 @@
 
 static struct fb_ops cg6_ops = {
 	.owner			= THIS_MODULE,
-	.fb_check_var		= cg6_check_var,
-	.fb_set_par		= cg6_set_par,
 	.fb_setcolreg		= cg6_setcolreg,
 	.fb_blank		= cg6_blank,
 	.fb_fillrect		= cg6_fillrect,
@@ -55,6 +53,7 @@
 	.fb_imageblit		= cg6_imageblit,
 	.fb_sync		= cg6_sync,
 	.fb_mmap		= cg6_mmap,
+	.fb_ioctl		= cg6_ioctl,
 	.fb_cursor		= soft_cursor,
 };
 
@@ -406,39 +405,6 @@
 }
 
 /**
- *      cg6_check_var - Optional function.  Validates a var passed in.
- *      @var: frame buffer variable screen structure
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int cg6_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	if (var->bits_per_pixel != 8)
-		return -EINVAL;
-
-	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
-		return -EINVAL;
-	if (var->nonstd)
-		return -EINVAL;
-	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
-		return -EINVAL;
-
-	if (var->xres != info->var.xres || var->yres != info->var.yres)
-		return -EINVAL;
-
-	return 0;
-}
-
-/**
- *      cg6_set_par - Optional function.  Alters the hardware state.
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int
-cg6_set_par(struct fb_info *info)
-{
-	return 0;
-}
-
-/**
  *      cg6_setcolreg - Optional function. Sets a color register.
  *      @regno: boolean, 0 copy local, 1 get_user() function
  *      @red: frame buffer colormap structure
@@ -535,6 +501,15 @@
 				  vma);
 }
 
+static int cg6_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		     unsigned long arg, struct fb_info *info)
+{
+	struct cg6_par *par = (struct cg6_par *) info->par;
+
+	return sbusfb_ioctl_helper(cmd, arg, info,
+				   FBTYPE_SUNFAST_COLOR, 8, par->fbsize);
+}
+
 /*
  *  Initialisation
  */
@@ -731,7 +706,6 @@
 		return;
 	}
 
-	cg6_set_par(&all->info);
 	cg6_init_fix(&all->info, linebytes);
 
 	if (register_framebuffer(&all->info) < 0) {
diff -Nru a/drivers/video/ffb.c b/drivers/video/ffb.c
--- a/drivers/video/ffb.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/video/ffb.c	Wed Mar  5 22:23:02 2003
@@ -20,6 +20,7 @@
 #include <asm/io.h>
 #include <asm/upa.h>
 #include <asm/oplib.h>
+#include <asm/fbio.h>
 
 #include "sbuslib.h"
 
@@ -27,8 +28,6 @@
  * Local functions.
  */
 
-static int ffb_check_var(struct fb_var_screeninfo *, struct fb_info *);
-static int ffb_set_par(struct fb_info *);
 static int ffb_setcolreg(unsigned, unsigned, unsigned, unsigned,
 			 unsigned, struct fb_info *);
 static int ffb_blank(int, struct fb_info *);
@@ -39,6 +38,8 @@
 static void ffb_copyarea(struct fb_info *, struct fb_copyarea *);
 static int ffb_sync(struct fb_info *);
 static int ffb_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
+static int ffb_ioctl(struct inode *, struct file *, unsigned int,
+		     unsigned long, struct fb_info *);
 
 /*
  *  Frame buffer operations
@@ -46,8 +47,6 @@
 
 static struct fb_ops ffb_ops = {
 	.owner			= THIS_MODULE,
-	.fb_check_var		= ffb_check_var,
-	.fb_set_par		= ffb_set_par,
 	.fb_setcolreg		= ffb_setcolreg,
 	.fb_blank		= ffb_blank,
 	.fb_fillrect		= ffb_fillrect,
@@ -55,6 +54,7 @@
 	.fb_imageblit		= ffb_imageblit,
 	.fb_sync		= ffb_sync,
 	.fb_mmap		= ffb_mmap,
+	.fb_ioctl		= ffb_ioctl,
 
 	/* XXX Use FFB hw cursor once fb cursor API is better understood... */
 	.fb_cursor		= soft_cursor,
@@ -673,41 +673,6 @@
 }
 
 /**
- *      ffb_check_var - Optional function.  Validates a var passed in.
- *      @var: frame buffer variable screen structure
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int ffb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	if (var->bits_per_pixel != 32)
-		return -EINVAL;
-
-	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
-		return -EINVAL;
-	if (var->nonstd)
-		return -EINVAL;
-	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
-		return -EINVAL;
-
-	if (var->xres != info->var.xres || var->yres != info->var.yres)
-		return -EINVAL;
-
-	ffb_fixup_var_rgb(var);
-
-	return 0;
-}
-
-/**
- *      ffb_set_par - Optional function.  Alters the hardware state.
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int
-ffb_set_par(struct fb_info *info)
-{
-	return 0;
-}
-
-/**
  *      ffb_setcolreg - Optional function. Sets a color register.
  *      @regno: boolean, 0 copy local, 1 get_user() function
  *      @red: frame buffer colormap structure
@@ -818,6 +783,15 @@
 				  0, vma);
 }
 
+static int ffb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		     unsigned long arg, struct fb_info *info)
+{
+	struct ffb_par *par = (struct ffb_par *) info->par;
+
+	return sbusfb_ioctl_helper(cmd, arg, info,
+				   FBTYPE_CREATOR, 24, par->fbsize);
+}
+
 /*
  *  Initialisation
  */
@@ -972,7 +946,6 @@
 		return;
 	}
 
-	ffb_set_par(&all->info);
 	ffb_init_fix(&all->info);
 
 	if (register_framebuffer(&all->info) < 0) {
diff -Nru a/drivers/video/p9100.c b/drivers/video/p9100.c
--- a/drivers/video/p9100.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/video/p9100.c	Wed Mar  5 22:23:02 2003
@@ -27,13 +27,13 @@
  * Local functions.
  */
 
-static int p9100_check_var(struct fb_var_screeninfo *, struct fb_info *);
-static int p9100_set_par(struct fb_info *);
 static int p9100_setcolreg(unsigned, unsigned, unsigned, unsigned,
 			   unsigned, struct fb_info *);
 static int p9100_blank(int, struct fb_info *);
 
 static int p9100_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
+static int p9100_ioctl(struct inode *, struct file *, unsigned int,
+		       unsigned long, struct fb_info *);
 
 /*
  *  Frame buffer operations
@@ -41,14 +41,13 @@
 
 static struct fb_ops p9100_ops = {
 	.owner			= THIS_MODULE,
-	.fb_check_var		= p9100_check_var,
-	.fb_set_par		= p9100_set_par,
 	.fb_setcolreg		= p9100_setcolreg,
 	.fb_blank		= p9100_blank,
 	.fb_fillrect		= cfb_fillrect,
 	.fb_copyarea		= cfb_copyarea,
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= p9100_mmap,
+	.fb_ioctl		= p9100_ioctl,
 	.fb_cursor		= soft_cursor,
 };
 
@@ -143,39 +142,6 @@
 };
 
 /**
- *      p9100_check_var - Optional function.  Validates a var passed in.
- *      @var: frame buffer variable screen structure
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int p9100_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	if (var->bits_per_pixel != 8)
-		return -EINVAL;
-
-	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
-		return -EINVAL;
-	if (var->nonstd)
-		return -EINVAL;
-	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
-		return -EINVAL;
-
-	if (var->xres != info->var.xres || var->yres != info->var.yres)
-		return -EINVAL;
-
-	return 0;
-}
-
-/**
- *      p9100_set_par - Optional function.  Alters the hardware state.
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int
-p9100_set_par(struct fb_info *info)
-{
-	return 0;
-}
-
-/**
  *      p9100_setcolreg - Optional function. Sets a color register.
  *      @regno: boolean, 0 copy local, 1 get_user() function
  *      @red: frame buffer colormap structure
@@ -265,6 +231,16 @@
 				  vma);
 }
 
+static int p9100_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		       unsigned long arg, struct fb_info *info)
+{
+	struct p9100_par *par = (struct p9100_par *) info->par;
+
+	/* Make it look like a cg3. */
+	return sbusfb_ioctl_helper(cmd, arg, info,
+				   FBTYPE_SUN3COLOR, 8, par->fbsize);
+}
+
 /*
  *  Initialisation
  */
@@ -344,7 +320,6 @@
 		return;
 	}
 
-	p9100_set_par(&all->info);
 	p9100_init_fix(&all->info, linebytes);
 
 	if (register_framebuffer(&all->info) < 0) {
diff -Nru a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
--- a/drivers/video/sbuslib.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/video/sbuslib.c	Wed Mar  5 22:23:02 2003
@@ -9,6 +9,7 @@
 #include <linux/fb.h>
 
 #include <asm/oplib.h>
+#include <asm/fbio.h>
 
 #include "sbuslib.h"
 
@@ -83,3 +84,84 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(sbusfb_mmap_helper);
+
+int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
+			struct fb_info *info,
+			int type, int fb_depth, unsigned long fb_size)
+{
+	switch(cmd) {
+	case FBIOGTYPE: {
+		struct fbtype *f = (struct fbtype *) arg;
+
+		if (put_user(type, &f->fb_type) ||
+		    __put_user(info->var.yres, &f->fb_height) ||
+		    __put_user(info->var.xres, &f->fb_width) ||
+		    __put_user(fb_depth, &f->fb_depth) ||
+		    __put_user(0, &f->fb_cmsize) ||
+		    __put_user(fb_size, &f->fb_cmsize))
+			return -EFAULT;
+		return 0;
+	}
+	case FBIOPUTCMAP_SPARC: {
+		struct fbcmap *c = (struct fbcmap *) arg;
+		struct fb_cmap cmap;
+		u16 red, green, blue;
+		unsigned char *ured, *ugreen, *ublue;
+		int index, count, i;
+
+		if (get_user(index, &c->index) ||
+		    __get_user(count, &c->count) ||
+		    __get_user(ured, &c->red) ||
+		    __get_user(ugreen, &c->green) ||
+		    __get_user(ublue, &c->blue))
+			return -EFAULT;
+
+		cmap.len = 1;
+		cmap.red = &red;
+		cmap.green = &green;
+		cmap.blue = &blue;
+		for (i = 0; i < count; i++) {
+			int err;
+
+			if (get_user(red, &ured[i]) ||
+			    get_user(green, &ugreen[i]) ||
+			    get_user(blue, &ublue[i]))
+				return -EFAULT;
+
+			cmap.start = index + i;
+			err = fb_set_cmap(&cmap, 0, info);
+			if (err)
+				return err;
+		}
+		return 0;
+	}
+	case FBIOGETCMAP_SPARC: {
+		struct fbcmap *c = (struct fbcmap *) arg;
+		unsigned char *ured, *ugreen, *ublue;
+		struct fb_cmap *cmap = &info->cmap;
+		int index, count, i;
+
+		if (get_user(index, &c->index) ||
+		    __get_user(count, &c->count) ||
+		    __get_user(ured, &c->red) ||
+		    __get_user(ugreen, &c->green) ||
+		    __get_user(ublue, &c->blue))
+			return -EFAULT;
+
+		if (index + count > cmap->len)
+			return -EINVAL;
+
+		for (i = 0; i < count; i++) {
+			if (put_user(cmap->red[index + i], &ured[i]) ||
+			    put_user(cmap->green[index + i], &ugreen[i]) ||
+			    put_user(cmap->blue[index + i], &ublue[i]))
+				return -EFAULT;
+		}
+		return 0;
+	}
+	default:
+		return -EINVAL;
+	};
+}
+EXPORT_SYMBOL(sbusfb_ioctl_helper);
diff -Nru a/drivers/video/sbuslib.h b/drivers/video/sbuslib.h
--- a/drivers/video/sbuslib.h	Wed Mar  5 22:23:02 2003
+++ b/drivers/video/sbuslib.h	Wed Mar  5 22:23:02 2003
@@ -17,5 +17,8 @@
 			      unsigned long physbase, unsigned long fbsize,
 			      unsigned long iospace,
 			      struct vm_area_struct *vma);
+int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
+			struct fb_info *info,
+			int type, int fb_depth, unsigned long fb_size);
 
 #endif /* _SBUSLIB_H */
diff -Nru a/drivers/video/tcx.c b/drivers/video/tcx.c
--- a/drivers/video/tcx.c	Wed Mar  5 22:23:02 2003
+++ b/drivers/video/tcx.c	Wed Mar  5 22:23:02 2003
@@ -29,13 +29,13 @@
  * Local functions.
  */
 
-static int tcx_check_var(struct fb_var_screeninfo *, struct fb_info *);
-static int tcx_set_par(struct fb_info *);
 static int tcx_setcolreg(unsigned, unsigned, unsigned, unsigned,
 			 unsigned, struct fb_info *);
 static int tcx_blank(int, struct fb_info *);
 
 static int tcx_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
+static int tcx_ioctl(struct inode *, struct file *, unsigned int,
+		     unsigned long, struct fb_info *);
 
 /*
  *  Frame buffer operations
@@ -43,14 +43,13 @@
 
 static struct fb_ops tcx_ops = {
 	.owner			= THIS_MODULE,
-	.fb_check_var		= tcx_check_var,
-	.fb_set_par		= tcx_set_par,
 	.fb_setcolreg		= tcx_setcolreg,
 	.fb_blank		= tcx_blank,
 	.fb_fillrect		= cfb_fillrect,
 	.fb_copyarea		= cfb_copyarea,
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= tcx_mmap,
+	.fb_ioctl		= tcx_ioctl,
 	.fb_cursor		= soft_cursor,
 };
 
@@ -155,39 +154,6 @@
 }
 
 /**
- *      tcx_check_var - Optional function.  Validates a var passed in.
- *      @var: frame buffer variable screen structure
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int tcx_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
-	if (var->bits_per_pixel != 8)
-		return -EINVAL;
-
-	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
-		return -EINVAL;
-	if (var->nonstd)
-		return -EINVAL;
-	if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
-		return -EINVAL;
-
-	if (var->xres != info->var.xres || var->yres != info->var.yres)
-		return -EINVAL;
-
-	return 0;
-}
-
-/**
- *      tcx_set_par - Optional function.  Alters the hardware state.
- *      @info: frame buffer structure that represents a single frame buffer
- */
-static int
-tcx_set_par(struct fb_info *info)
-{
-	return 0;
-}
-
-/**
  *      tcx_setcolreg - Optional function. Sets a color register.
  *      @regno: boolean, 0 copy local, 1 get_user() function
  *      @red: frame buffer colormap structure
@@ -298,6 +264,17 @@
 				  vma);
 }
 
+static int tcx_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		     unsigned long arg, struct fb_info *info)
+{
+	struct tcx_par *par = (struct tcx_par *) info->par;
+
+	return sbusfb_ioctl_helper(cmd, arg, info,
+				   FBTYPE_TCXCOLOR,
+				   (par->lowdepth ? 8 : 24),
+				   par->fbsize);
+}
+
 /*
  *  Initialisation
  */
@@ -431,7 +408,6 @@
 		return;
 	}
 
-	tcx_set_par(&all->info);
 	tcx_init_fix(&all->info, linebytes);
 
 	if (register_framebuffer(&all->info) < 0) {
diff -Nru a/fs/filesystems.c b/fs/filesystems.c
--- a/fs/filesystems.c	Wed Mar  5 22:23:02 2003
+++ b/fs/filesystems.c	Wed Mar  5 22:23:02 2003
@@ -125,9 +125,7 @@
 	if (!res) {
 		/* we implicitly possess reference to @fs during registration,
 		 * so it cannot be unregister from under us. */
-		if (register_fs_subsys(fs))
-			printk(KERN_WARNING "Failed to register '%s' in sysfs\n",
-			       fs->name);
+		register_fs_subsys(fs);
 	}
 	return res;
 }
diff -Nru a/fs/sysfs/mount.c b/fs/sysfs/mount.c
--- a/fs/sysfs/mount.c	Wed Mar  5 22:23:02 2003
+++ b/fs/sysfs/mount.c	Wed Mar  5 22:23:02 2003
@@ -33,7 +33,7 @@
 	sb->s_op = &sysfs_ops;
 	sysfs_sb = sb;
 
-	inode = sysfs_new_inode(S_IFDIR | S_IRUGO | S_IWUSR);
+	inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
 	if (inode) {
 		inode->i_op = &simple_dir_inode_operations;
 		inode->i_fop = &simple_dir_operations;
diff -Nru a/include/linux/if_shaper.h b/include/linux/if_shaper.h
--- a/include/linux/if_shaper.h	Wed Mar  5 22:23:02 2003
+++ b/include/linux/if_shaper.h	Wed Mar  5 22:23:02 2003
@@ -21,7 +21,7 @@
 	__u32 bitspersec;
 	__u32 shapelatency;
 	__u32 shapeclock;
-	__u32 recovery;		/* Time we can next clock a packet out on
+	unsigned long recovery;	/* Time we can next clock a packet out on
 				   an empty queue */
         unsigned long locked;
         struct net_device_stats stats;
diff -Nru a/include/linux/jiffies.h b/include/linux/jiffies.h
--- a/include/linux/jiffies.h	Wed Mar  5 22:23:02 2003
+++ b/include/linux/jiffies.h	Wed Mar  5 22:23:02 2003
@@ -1,6 +1,7 @@
 #ifndef _LINUX_JIFFIES_H
 #define _LINUX_JIFFIES_H
 
+#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/seqlock.h>
@@ -37,10 +38,16 @@
  * good compiler would generate better code (and a really good compiler
  * wouldn't care). Gcc is currently neither.
  */
-#define time_after(a,b)		((long)(b) - (long)(a) < 0)
+#define time_after(a,b)		\
+	(typecheck(unsigned long, a) && \
+	 typecheck(unsigned long, b) && \
+	 ((long)(b) - (long)(a) < 0))
 #define time_before(a,b)	time_after(b,a)
 
-#define time_after_eq(a,b)	((long)(a) - (long)(b) >= 0)
+#define time_after_eq(a,b)	\
+	(typecheck(unsigned long, a) && \
+	 typecheck(unsigned long, b) && \
+	 ((long)(a) - (long)(b) >= 0))
 #define time_before_eq(a,b)	time_after_eq(b,a)
 
 #endif
diff -Nru a/include/linux/kernel.h b/include/linux/kernel.h
--- a/include/linux/kernel.h	Wed Mar  5 22:23:02 2003
+++ b/include/linux/kernel.h	Wed Mar  5 22:23:02 2003
@@ -188,6 +188,17 @@
         const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
         (type *)( (char *)__mptr - offsetof(type,member) );})
 
+/*
+ * Check at compile time that something is of a particular type.
+ * Always evaluates to 1 so you may use it easily in conparisons.
+ */
+#define typecheck(type,x) \
+({	type __dummy; \
+	typeof(x) __dummy2; \
+	(void)(&__dummy == &__dummy2); \
+	1; \
+})
+
 #endif /* __KERNEL__ */
 
 #define SI_LOAD_SHIFT	16
diff -Nru a/include/linux/profile.h b/include/linux/profile.h
--- a/include/linux/profile.h	Wed Mar  5 22:23:02 2003
+++ b/include/linux/profile.h	Wed Mar  5 22:23:02 2003
@@ -2,15 +2,15 @@
 #define _LINUX_PROFILE_H
 
 #ifdef __KERNEL__
- 
+
 #include <linux/kernel.h>
 #include <linux/config.h>
 #include <linux/init.h>
 #include <asm/errno.h>
- 
+
 /* parse command line */
 int __init profile_setup(char * str);
- 
+
 /* init basic kernel profiler */
 void __init profile_init(void);
 
@@ -27,14 +27,14 @@
 };
 
 #ifdef CONFIG_PROFILING
- 
+
 struct notifier_block;
 struct task_struct;
 struct mm_struct;
- 
+
 /* task is in do_exit() */
 void profile_exit_task(struct task_struct * task);
- 
+
 /* change of vma mappings */
 void profile_exec_unmap(struct mm_struct * mm);
 
@@ -44,10 +44,10 @@
 int profile_event_register(enum profile_type, struct notifier_block * n);
 
 int profile_event_unregister(enum profile_type, struct notifier_block * n);
- 
+
 int register_profile_notifier(struct notifier_block * nb);
 int unregister_profile_notifier(struct notifier_block * nb);
- 
+
 /* profiling hook activated on each timer interrupt */
 void profile_hook(struct pt_regs * regs);
 
@@ -57,12 +57,12 @@
 {
 	return -ENOSYS;
 }
- 
+
 static inline int profile_event_unregister(enum profile_type t, struct notifier_block * n)
 {
 	return -ENOSYS;
 }
- 
+
 #define profile_exit_task(a) do { } while (0)
 #define profile_exec_unmap(a) do { } while (0)
 #define profile_exit_mmap(a) do { } while (0)
@@ -80,7 +80,7 @@
 #define profile_hook(regs) do { } while (0)
 
 #endif /* CONFIG_PROFILING */
- 
+
 #endif /* __KERNEL__ */
- 
+
 #endif /* _LINUX_PROFILE_H */
diff -Nru a/include/linux/tty.h b/include/linux/tty.h
--- a/include/linux/tty.h	Wed Mar  5 22:23:02 2003
+++ b/include/linux/tty.h	Wed Mar  5 22:23:02 2003
@@ -294,7 +294,7 @@
 	unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1;
 	unsigned char closing:1;
 	unsigned short minimum_to_wake;
-	unsigned overrun_time;
+	unsigned long overrun_time;
 	int num_overrun;
 	unsigned long process_char_map[256/(8*sizeof(unsigned long))];
 	char *read_buf;
diff -Nru a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
--- a/sound/pci/ac97/ac97_codec.c	Wed Mar  5 22:23:02 2003
+++ b/sound/pci/ac97/ac97_codec.c	Wed Mar  5 22:23:02 2003
@@ -1808,7 +1808,7 @@
  */
 static int ac97_reset_wait(ac97_t *ac97, int timeout, int with_modem)
 {
-	signed long end_time;
+	unsigned long end_time;
 	end_time = jiffies + timeout;
 	do {
 		unsigned short ext_mid;
@@ -1866,7 +1866,7 @@
 	int err;
 	ac97_t *ac97;
 	char name[64];
-	signed long end_time;
+	unsigned long end_time;
 	static snd_device_ops_t ops = {
 		.dev_free =	snd_ac97_dev_free,
 	};
diff -Nru a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
--- a/sound/pci/intel8x0.c	Wed Mar  5 22:23:02 2003
+++ b/sound/pci/intel8x0.c	Wed Mar  5 22:23:02 2003
@@ -1741,7 +1741,7 @@
 
 static int snd_intel8x0_ich_chip_init(intel8x0_t *chip)
 {
-	signed long end_time;
+	unsigned long end_time;
 	unsigned int cnt, status, nstatus;
 	
 	/* put logic to right state */