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
- Lines: 303
- Date:
Tue Jul 23 06:48:28 1996
- Orig file:
v2.0.8/linux/drivers/char/psaux.c
- Orig date:
Tue Jul 23 08:23:12 1996
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