patch-2.0.9 linux/drivers/char/psaux.c

Next file: linux/drivers/char/tty_io.c
Previous file: linux/drivers/char/mem.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.8/linux/drivers/char/psaux.c linux/drivers/char/psaux.c
@@ -25,10 +25,6 @@
  * Rearranged SIGIO support to use code from tty_io.  9Sept95 ctm@ardi.com
  *
  * Modularised 8-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
- *
- * Fixed keyboard lockups at open time (intervening kbd interrupts), handle
- * RESEND replies, better error checking
- * 3-Jul-96 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
  */
 
 /* Uncomment the following line if your mouse needs initialization. */
@@ -61,10 +57,8 @@
 #define AUX_STATUS	0x64		/* Aux device status reg */
 
 /* aux controller status bits */
-#define AUX_KOBUF_FULL	0x01		/* output buffer (from controller) full */
 #define AUX_OBUF_FULL	0x21		/* output buffer (from device) full */
 #define AUX_IBUF_FULL	0x02		/* input buffer (to device) full */
-#define AUX_TIMEOUT	0x40		/* controller reports timeout */
 
 /* aux controller commands */
 #define AUX_CMD_WRITE	0x60		/* value to write to controller */
@@ -87,14 +81,6 @@
 #define AUX_DISABLE_DEV	0xf5		/* disable aux device */
 #define AUX_RESET	0xff		/* reset aux device */
 
-/* kbd controller commands */
-#define KBD_DISABLE	0xad
-#define KBD_ENABLE	0xae
-
-/* replies */
-#define AUX_ACK		0xfa
-#define AUX_RESEND	0xfe
-
 #define MAX_RETRIES	60		/* some aux operations take long time*/
 #if defined(__alpha__) && !defined(CONFIG_PCI)
 # define AUX_IRQ	9		/* Jensen is odd indeed */
@@ -135,6 +121,7 @@
 static int aux_count = 0;
 static int aux_present = 0;
 static int poll_aux_status(void);
+static int poll_aux_status_nosleep(void);
 static int fasync_aux(struct inode *inode, struct file *filp, int on);
 
 #ifdef CONFIG_82C710_MOUSE
@@ -149,70 +136,49 @@
 
 
 /*
- * Write a byte to the kbd controller and wait for it being processed
+ * Write to aux device
  */
 
-static int aux_write_byte(int val,int port)
+static void aux_write_dev(int val)
 {
-	outb_p(val, port);
-	return poll_aux_status();
+	poll_aux_status();
+	outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);	/* write magic cookie */
+	poll_aux_status();
+	outb_p(val,AUX_OUTPUT_PORT);		/* write data */
 }
 
 /*
- * Write to device, handle returned resend requests and wait for ack
+ * Write to device & handle returned ack
  */
+#if defined INITIALIZE_DEVICE
 static int aux_write_ack(int val)
 {
-	int rv, retries = 0, stat;
+	int retries = 0;
 
-  repeat:
-	if (poll_aux_status() < 0)
-		return -1;
-	outb_p(AUX_MAGIC_WRITE, AUX_COMMAND);
-	if (poll_aux_status() < 0)
-		return -1;
-	outb_p(val, AUX_OUTPUT_PORT);
-
-	if ((rv = poll_aux_status()) < 0)
-		/* timeout */
-		return -1;
-	else if (rv == AUX_RESEND)
-	    /* controller needs last byte again... */
-		goto repeat;
-	else if (rv == AUX_ACK)
-	    /* already got ACK */
-		return 0;
-	else {
-		/* wait for ACK from controller */
-		while (retries < MAX_RETRIES) {
-			stat = inb_p(AUX_STATUS);
-			if ((stat & AUX_OBUF_FULL) == AUX_OBUF_FULL &&
-				inb_p(AUX_INPUT_PORT) == AUX_ACK)
-				return 0;
-			current->state = TASK_INTERRUPTIBLE;
-			current->timeout = jiffies + (5*HZ + 99) / 100;
-			schedule();
-			retries++;
-		}
-		return -1;
+	poll_aux_status_nosleep();
+	outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
+	poll_aux_status_nosleep();
+	outb_p(val,AUX_OUTPUT_PORT);
+	poll_aux_status_nosleep();
+
+	if ((inb(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
+	{
+		return (inb(AUX_INPUT_PORT));
 	}
+	return 0;
 }
+#endif /* INITIALIZE_DEVICE */
 
 /*
  * Write aux device command
  */
 
-static int aux_write_cmd(int val)
+static void aux_write_cmd(int val)
 {
-	if (poll_aux_status() < 0)
-		return -1;
-	outb_p(AUX_CMD_WRITE, AUX_COMMAND);
-	if (poll_aux_status() < 0)
-		return -1;
-	outb_p(val, AUX_OUTPUT_PORT);
-	if (poll_aux_status() < 0)
-		return -1;
-	return 0;
+	poll_aux_status();
+	outb_p(AUX_CMD_WRITE,AUX_COMMAND);
+	poll_aux_status();
+	outb_p(val,AUX_OUTPUT_PORT);
 }
 
 
@@ -292,19 +258,10 @@
 	fasync_aux(inode, file, 0);
 	if (--aux_count)
 		return;
-	/* disable keyboard to avoid clashes with multi-byte command sequences */
+	aux_write_cmd(AUX_INTS_OFF);		/* disable controller ints */
+	poll_aux_status();
+	outb_p(AUX_DISABLE,AUX_COMMAND);      	/* Disable Aux device */
 	poll_aux_status();
-	if (aux_write_byte(KBD_DISABLE, AUX_COMMAND) < 0)
-		printk(KERN_ERR "psaux: controller timeout\n");
-	/* disable controller ints */
-	if (aux_write_cmd(AUX_INTS_OFF) < 0)
-		printk(KERN_ERR "psaux: controller timeout\n");
-	/* Disable Aux device */
-	if (aux_write_byte(AUX_DISABLE, AUX_COMMAND) < 0)
-		printk(KERN_ERR "psaux: controller timeout\n");
-	/* re-enable keyboard */
-	if (aux_write_byte(KBD_ENABLE, AUX_COMMAND) < 0)
-		printk(KERN_ERR "psaux: controller timeout\n");
 	free_irq(AUX_IRQ, NULL);
 	MOD_DEC_USE_COUNT;
 }
@@ -349,7 +306,7 @@
 		return -ENODEV;
 	if (aux_count++)
 		return 0;
-	if (poll_aux_status() < 0) {
+	if (!poll_aux_status()) {
 		aux_count--;
 		return -EBUSY;
 	}
@@ -360,27 +317,12 @@
 	}
 	MOD_INC_USE_COUNT;
 	poll_aux_status();
-	/* disable keyboard to avoid clashes with multi-byte command sequences */
-	if (aux_write_byte(KBD_DISABLE, AUX_COMMAND) < 0)
-		goto open_error;
-	/* Enable Aux in kbd controller */
-	if (aux_write_byte(AUX_ENABLE, AUX_COMMAND) < 0)
-		goto open_error;
-	/* enable aux device */
-	if (aux_write_ack(AUX_ENABLE_DEV) < 0)
-		goto open_error;
-	/* enable controller ints */
-	if (aux_write_cmd(AUX_INTS_ON) < 0)
-		goto open_error;
-	/* re-enable keyboard */
-	if (aux_write_byte(KBD_ENABLE, AUX_COMMAND) < 0)
-		goto open_error;
-
+	outb_p(AUX_ENABLE,AUX_COMMAND);		/* Enable Aux */
+	aux_write_dev(AUX_ENABLE_DEV);		/* enable aux device */
+	aux_write_cmd(AUX_INTS_ON);		/* enable controller ints */
+	poll_aux_status();
 	aux_ready = 0;
 	return 0;
-  open_error:
-	printk( KERN_ERR "psaux: controller timeout\n" );
-	return -EIO;
 }
 
 #ifdef CONFIG_82C710_MOUSE
@@ -436,31 +378,17 @@
 static int write_aux(struct inode * inode, struct file * file, const char * buffer, int count)
 {
 	int i = count;
-	int rv = 0;
-	
-	/* temporary disable keyboard to avoid clashes with multi-byte command
-	 * sequence */
-	if (aux_write_byte(KBD_DISABLE, AUX_COMMAND) < 0)
-		return -EIO;
 
 	while (i--) {
-		if (poll_aux_status() < 0) {
-			rv = -EIO;
-			break;
-		}
+		if (!poll_aux_status())
+			return -EIO;
 		outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
-		if (poll_aux_status() < 0) {
-			rv = -EIO;
-			break;
-		}
+		if (!poll_aux_status())
+			return -EIO;
 		outb_p(get_user(buffer++),AUX_OUTPUT_PORT);
 	}
-	/* reenable keyboard */
-	if (poll_aux_status() < 0 || aux_write_byte(KBD_ENABLE, AUX_COMMAND) < 0)
-		rv = -EIO;
-
 	inode->i_mtime = CURRENT_TIME;
-	return rv ? rv : count;
+	return count;
 }
 
 
@@ -591,11 +519,13 @@
 		aux_write_ack(AUX_SET_RES);
 		aux_write_ack(3);			/* 8 counts per mm */
 		aux_write_ack(AUX_SET_SCALE21);		/* 2:1 scaling */
+		poll_aux_status_nosleep();
 #endif /* INITIALIZE_DEVICE */
-		/* Disable Aux device and its interrupts on the controller */
-		if (aux_write_byte(AUX_DISABLE, AUX_COMMAND) < 0 ||
-		    aux_write_cmd(AUX_INTS_OFF) < 0)
-		    printk(KERN_ERR "psaux: controller timeout\n");
+		outb_p(AUX_DISABLE,AUX_COMMAND);   /* Disable Aux device */
+		poll_aux_status_nosleep();
+		outb_p(AUX_CMD_WRITE,AUX_COMMAND);
+		poll_aux_status_nosleep();             /* Disable interrupts */
+		outb_p(AUX_INTS_OFF, AUX_OUTPUT_PORT); /*  on the controller */
 	}
 	return 0;
 }
@@ -603,7 +533,7 @@
 #ifdef MODULE
 int init_module(void)
 {
-	return psaux_init();
+	return psaux_init(); /*?? Bjorn */
 }
 
 void cleanup_module(void)
@@ -615,18 +545,28 @@
 static int poll_aux_status(void)
 {
 	int retries=0;
-	int reply=0;
 
-	while ((inb(AUX_STATUS) & (AUX_KOBUF_FULL|AUX_IBUF_FULL)) &&
-	       retries < MAX_RETRIES) {
+	while ((inb(AUX_STATUS)&0x03) && retries < MAX_RETRIES) {
  		if ((inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
-			reply = inb_p(AUX_INPUT_PORT);
+			inb_p(AUX_INPUT_PORT);
 		current->state = TASK_INTERRUPTIBLE;
 		current->timeout = jiffies + (5*HZ + 99) / 100;
 		schedule();
 		retries++;
 	}
-	return (retries==MAX_RETRIES) ? -1 : reply;
+	return !(retries==MAX_RETRIES);
+}
+
+static int poll_aux_status_nosleep(void)
+{
+	int retries = 0;
+
+	while ((inb(AUX_STATUS)&0x03) && retries < 1000000) {
+ 		if ((inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
+			inb_p(AUX_INPUT_PORT);
+		retries++;
+	}
+	return !(retries == 1000000);
 }
 
 #ifdef CONFIG_82C710_MOUSE

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov