summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-07-24 01:55:37 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-07-24 01:55:37 +0000
commite940c15ebb25269923db9a8a912727046cfffa77 (patch)
tree0e4bbd46c2d69a129bfc30bd4e1f8dce132ba64b /drivers
parent79fa43ce85955f44a4b6fd7b5134743f12c225b0 (diff)
Cleanup the architecture specifics of keyboard and PS/2 mouse drivers.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/pc_keyb.c63
-rw-r--r--drivers/char/psaux.c650
2 files changed, 318 insertions, 395 deletions
diff --git a/drivers/char/pc_keyb.c b/drivers/char/pc_keyb.c
index 9e3267aaf..fd1c8e862 100644
--- a/drivers/char/pc_keyb.c
+++ b/drivers/char/pc_keyb.c
@@ -16,15 +16,15 @@
#include <linux/init.h>
#include <linux/kbd_ll.h>
-/* Some configuration switches are present in the include file... */
-
-#include "pc_keyb.h"
-
#include <asm/keyboard.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/system.h>
+/* Some configuration switches are present in the include file... */
+
+#include "pc_keyb.h"
+
/*
* In case we run on a non-x86 hardware we need to initialize both the keyboard
* controller and the keyboard. On a x86, the BIOS will already have initialized
@@ -40,7 +40,7 @@ __initfunc(static int kbd_wait_for_input(void))
n = KBD_TIMEOUT;
do {
- status = kbd_inb(KBD_STATUS_REG);
+ status = kbd_read_status();
/*
* Wait for input data to become available. This bit will
* then be cleared by the following read of the DATA
@@ -50,7 +50,7 @@ __initfunc(static int kbd_wait_for_input(void))
if (!(status & KBD_STAT_OBF))
continue;
- data = kbd_inb(KBD_DATA_REG);
+ data = kbd_read_input();
/*
* Check to see if a timeout error has occurred. This means
@@ -66,14 +66,24 @@ __initfunc(static int kbd_wait_for_input(void))
return -1; /* timed-out if fell through to here... */
}
-__initfunc(static void kbd_write(int address, int data))
+__initfunc(static void init_write_command(int data))
+{
+ int status;
+
+ do {
+ status = kbd_read_status();
+ } while (status & KBD_STAT_IBF);
+ kbd_write_command(data);
+}
+
+__initfunc(static void init_write_output(int data))
{
int status;
do {
- status = kbd_inb(KBD_STATUS_REG);
+ status = kbd_read_status();
} while (status & KBD_STAT_IBF);
- kbd_outb(data, address);
+ kbd_write_output(data);
}
__initfunc(static char *initialize_kbd2(void))
@@ -89,7 +99,7 @@ __initfunc(static char *initialize_kbd2(void))
* If the test is successful a x55 is placed in the input buffer.
*/
- kbd_write(KBD_CNTL_REG, KBD_CCMD_SELF_TEST);
+ init_write_command(KBD_CCMD_SELF_TEST);
if (kbd_wait_for_input() != 0x55)
return "Keyboard failed self test";
@@ -99,13 +109,13 @@ __initfunc(static char *initialize_kbd2(void))
* test are placed in the input buffer.
*/
- kbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_TEST);
+ init_write_command(KBD_CCMD_KBD_TEST);
if (kbd_wait_for_input() != 0x00)
return "Keyboard interface failed self test";
/* Enable the keyboard by allowing the keyboard clock to run. */
- kbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_ENABLE);
+ init_write_command(KBD_CCMD_KBD_ENABLE);
/*
* Reset keyboard. If the read times out
@@ -114,7 +124,7 @@ __initfunc(static char *initialize_kbd2(void))
* This defaults the keyboard to scan-code set 2.
*/
- kbd_write(KBD_DATA_REG, KBD_CMD_RESET);
+ init_write_output(KBD_CMD_RESET);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Keyboard reset failed, no ACK";
if (kbd_wait_for_input() != KBD_REPLY_POR)
@@ -125,17 +135,17 @@ __initfunc(static char *initialize_kbd2(void))
* in the disabled state.
*/
- kbd_write(KBD_DATA_REG, KBD_CMD_DISABLE);
+ init_write_output(KBD_CMD_DISABLE);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Disable keyboard: no ACK";
- kbd_write(KBD_CNTL_REG, KBD_CCMD_WRITE_MODE);
- kbd_write(KBD_DATA_REG, KBD_MODE_KBD_INT
+ init_write_command(KBD_CCMD_WRITE_MODE);
+ init_write_output(KBD_MODE_KBD_INT
| KBD_MODE_SYS
| KBD_MODE_DISABLE_MOUSE
| KBD_MODE_KCC);
- kbd_write(KBD_DATA_REG, KBD_CMD_ENABLE);
+ init_write_output(KBD_CMD_ENABLE);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Enable keyboard: no ACK";
@@ -143,10 +153,10 @@ __initfunc(static char *initialize_kbd2(void))
* Finally, set the typematic rate to maximum.
*/
- kbd_write(KBD_DATA_REG, KBD_CMD_SET_RATE);
+ init_write_output(KBD_CMD_SET_RATE);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Set rate: no ACK";
- kbd_write(KBD_DATA_REG, 0x00);
+ init_write_output(0x00);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Set rate: no ACK";
@@ -184,7 +194,7 @@ static inline void kb_wait(void)
int i;
for (i=0; i<KBD_TIMEOUT; i++)
- if (! (kbd_inb_p(KBD_STATUS_REG) & KBD_STAT_IBF))
+ if (! (kbd_read_status() & KBD_STAT_IBF))
return;
printk(KERN_WARNING "Keyboard timed out\n");
}
@@ -329,7 +339,7 @@ int pckbd_getkeycode(unsigned int scancode)
static inline void send_cmd(unsigned char c)
{
kb_wait();
- kbd_outb(c, KBD_CNTL_REG);
+ kbd_write_command(c);
}
#define disable_keyboard() do { send_cmd(KBD_CCMD_KBD_DISABLE); kb_wait(); } while (0)
@@ -490,7 +500,7 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
kbd_pt_regs = regs;
disable_keyboard();
- status = kbd_inb_p(KBD_STATUS_REG);
+ status = kbd_read_status();
do {
unsigned char scancode;
@@ -498,11 +508,11 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (status & kbd_read_mask & KBD_STAT_MOUSE_OBF)
break;
- scancode = kbd_inb(KBD_DATA_REG);
+ scancode = kbd_read_input();
if ((status & KBD_STAT_OBF) && do_acknowledge(scancode))
handle_scancode(scancode);
- status = kbd_inb(KBD_STATUS_REG);
+ status = kbd_read_status();
} while (status & (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF));
mark_bh(KEYBOARD_BH);
@@ -524,9 +534,10 @@ static int send_data(unsigned char data)
acknowledge = 0;
resend = 0;
reply_expected = 1;
- kbd_outb_p(data, KBD_DATA_REG);
+ kbd_write_output(data);
+ kbd_pause();
for(i=0; i<0x200000; i++) {
- kbd_inb_p(KBD_STATUS_REG); /* just as a delay */
+ kbd_read_status(); /* just as a delay */
if (acknowledge)
return 1;
if (resend)
diff --git a/drivers/char/psaux.c b/drivers/char/psaux.c
index eea857b8a..d329a6883 100644
--- a/drivers/char/psaux.c
+++ b/drivers/char/psaux.c
@@ -28,6 +28,8 @@
*
* Fixed keyboard lockups at open time
* 3-Jul-96, 22-Aug-96 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
+ *
+ * Cleanup by Martin Mares, 01-Jun-97 (now uses the new PC kbd include)
*/
/* Uncomment the following line if your mouse needs initialization. */
@@ -36,7 +38,6 @@
#include <linux/module.h>
-#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
@@ -53,140 +54,115 @@
#include <asm/uaccess.h>
#include <asm/system.h>
-#include "pc_keyb.h"
-
-#ifdef CONFIG_SGI
-#include <asm/segment.h>
-#include <asm/sgihpc.h>
-#endif
-
-#define PSMOUSE_MINOR 1 /* minor device # for this mouse */
-
-/* aux controller ports */
-#define AUX_INPUT_PORT 0x60 /* Aux device output buffer */
-#define AUX_OUTPUT_PORT 0x60 /* Aux device input buffer */
-#define AUX_COMMAND 0x64 /* Aux device command buffer */
-#define AUX_STATUS 0x64 /* Aux device status reg */
-
-/* aux controller status bits */
-#define AUX_OBUF_FULL 0x21 /* output buffer (from device) full */
-#define AUX_IBUF_FULL 0x02 /* input buffer (to device) full */
+#include <linux/config.h>
-/* aux controller commands */
-#define AUX_CMD_WRITE 0x60 /* value to write to controller */
-#define AUX_MAGIC_WRITE 0xd4 /* value to send aux device data */
+#include "pc_keyb.h"
-#define AUX_INTS_ON 0x47 /* enable controller interrupts */
-#define AUX_INTS_OFF 0x65 /* disable controller interrupts */
+#include <asm/keyboard.h>
-#define AUX_DISABLE 0xa7 /* disable aux */
-#define AUX_ENABLE 0xa8 /* enable aux */
+/*
+ * Generic declarations for both PS2 and 82C710
+ */
+#define PSMOUSE_MINOR 1 /* minor device # for this mouse */
-#define MAX_RETRIES 60 /* some aux operations take long time*/
-#if defined(__alpha__) && !defined(CONFIG_PCI)
-# define AUX_IRQ 9 /* Jensen is odd indeed */
-#else
-# define AUX_IRQ 12
-#endif
#define AUX_BUF_SIZE 2048
-#ifdef CONFIG_SGI
-extern volatile struct hpc_keyb *sgi_kh; /* see keyboard.c */
+struct aux_queue {
+ unsigned long head;
+ unsigned long tail;
+ struct wait_queue *proc_list;
+ struct fasync_struct *fasync;
+ unsigned char buf[AUX_BUF_SIZE];
+};
-extern __inline__ int
-ps2_inb_p(unsigned short port)
-{
- int result;
+static struct aux_queue *queue;
+static int aux_ready = 0;
+static int aux_count = 0;
+static int aux_present = 0;
- if(port == AUX_INPUT_PORT)
- result = sgi_kh->data;
- else if(port == AUX_STATUS)
- result = sgi_kh->command;
- return result;
-}
+/*
+ * Shared subroutines
+ */
-extern __inline__ int
-ps2_inb(unsigned short port)
+static unsigned int get_from_queue(void)
{
- int result;
-
- if(port == AUX_INPUT_PORT)
- result = sgi_kh->data;
- else if(port == AUX_STATUS)
- result = sgi_kh->command;
+ unsigned int result;
+ unsigned long flags;
+ save_flags(flags);
+ cli();
+ result = queue->buf[queue->tail];
+ queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
+ restore_flags(flags);
return result;
}
-extern __inline__ void
-ps2_outb_p(unsigned char data, unsigned short port)
-{
- if(port == AUX_OUTPUT_PORT)
- sgi_kh->data = data;
- else if(port == AUX_COMMAND)
- sgi_kh->command = data;
-}
-extern __inline__ void
-ps2_outb(unsigned char data, unsigned short port)
+static inline int queue_empty(void)
{
- if(port == AUX_OUTPUT_PORT)
- sgi_kh->data = data;
- else if(port == AUX_COMMAND)
- sgi_kh->command = data;
+ return queue->head == queue->tail;
}
-#else
-#define ps2_inb_p inb_p
-#define ps2_inb inb
-#define ps2_outb_p outb_p
-#define ps2_outb outb
-#endif
-
-/* 82C710 definitions */
-#define QP_DATA 0x310 /* Data Port I/O Address */
-#define QP_STATUS 0x311 /* Status Port I/O Address */
+static int fasync_aux(struct inode *inode, struct file *filp, int on)
+{
+ int retval;
-#define QP_DEV_IDLE 0x01 /* Device Idle */
-#define QP_RX_FULL 0x02 /* Device Char received */
-#define QP_TX_IDLE 0x04 /* Device XMIT Idle */
-#define QP_RESET 0x08 /* Device Reset */
-#define QP_INTS_ON 0x10 /* Device Interrupt On */
-#define QP_ERROR_FLAG 0x20 /* Device Error */
-#define QP_CLEAR 0x40 /* Device Clear */
-#define QP_ENABLE 0x80 /* Device Enable */
+ retval = fasync_helper(inode, filp, on, &queue->fasync);
+ if (retval < 0)
+ return retval;
+ return 0;
+}
-#define QP_IRQ 12
+/*
+ * PS/2 Aux Device
+ */
-extern unsigned char aux_device_present;
-extern unsigned char kbd_read_mask; /* from keyboard.c */
+#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
+#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
-struct aux_queue {
- unsigned long head;
- unsigned long tail;
- struct wait_queue *proc_list;
- struct fasync_struct *fasync;
- unsigned char buf[AUX_BUF_SIZE];
-};
+#define MAX_RETRIES 60 /* some aux operations take long time*/
-static struct aux_queue *queue;
-static int aux_ready = 0;
-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);
+/*
+ * Status polling
+ */
-#ifdef CONFIG_82C710_MOUSE
-static int qp_present = 0;
-static int qp_count = 0;
-static int qp_data = QP_DATA;
-static int qp_status = QP_STATUS;
+static int poll_aux_status(void)
+{
+ int retries=0;
+ unsigned char status;
-static int poll_qp_status(void);
-static int probe_qp(void);
-#endif
+ while ((kbd_read_status() & 0x03) && retries < MAX_RETRIES) {
+ status = kbd_read_status();
+ kbd_pause();
+ if ((status & AUX_STAT_OBF) == AUX_STAT_OBF) {
+ kbd_read_input();
+ kbd_pause();
+ }
+ current->state = TASK_INTERRUPTIBLE;
+ current->timeout = jiffies + (5*HZ + 99) / 100;
+ schedule();
+ retries++;
+ }
+ return !(retries==MAX_RETRIES);
+}
+static int poll_aux_status_nosleep(void)
+{
+ int retries = 0;
+ unsigned char status;
+
+ while ((kbd_read_status() & (KBD_STAT_IBF | KBD_STAT_OBF))
+ && retries < 1000000) {
+ status = kbd_read_status();
+ kbd_pause();
+ if ((status & AUX_STAT_OBF) == AUX_STAT_OBF) {
+ kbd_read_input();
+ kbd_pause();
+ }
+ retries++;
+ }
+ return !(retries == 1000000);
+}
/*
* Write to aux device
@@ -195,9 +171,9 @@ static int probe_qp(void);
static void aux_write_dev(int val)
{
poll_aux_status();
- ps2_outb_p(AUX_MAGIC_WRITE,AUX_COMMAND); /* write magic cookie */
+ kbd_write_command(KBD_CCMD_WRITE_MOUSE); /* Write magic cookie */
poll_aux_status();
- ps2_outb_p(val,AUX_OUTPUT_PORT); /* write data */
+ kbd_write_output(val); /* Write data */
}
/*
@@ -208,24 +184,19 @@ static void aux_write_dev(int val)
__initfunc(static void aux_write_dev_nosleep(int val))
{
poll_aux_status_nosleep();
- ps2_outb_p(KBD_CCMD_WRITE_MOUSE, KBD_CNTL_REG);
+ kbd_write_command(KBD_CCMD_WRITE_MOUSE);
poll_aux_status_nosleep();
- ps2_outb_p(val, KBD_DATA_REG);
+ kbd_write_output(val);
}
-static int aux_write_ack(int val)
+__initfunc(static int aux_write_ack(int val))
{
- int retries = 0;
-
- poll_aux_status_nosleep();
- ps2_outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
- poll_aux_status_nosleep();
- ps2_outb_p(val,AUX_OUTPUT_PORT);
+ aux_write_dev_nosleep(val);
poll_aux_status_nosleep();
- if ((ps2_inb(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
+ if ((kbd_read_status() & AUX_STAT_OBF) == AUX_STAT_OBF)
{
- return (ps2_inb(AUX_INPUT_PORT));
+ return kbd_read_input();
}
return 0;
}
@@ -238,38 +209,15 @@ static int aux_write_ack(int val)
static void aux_write_cmd(int val)
{
poll_aux_status();
- ps2_outb_p(AUX_CMD_WRITE,AUX_COMMAND);
+ kbd_write_command(KBD_CCMD_WRITE_MODE);
poll_aux_status();
- ps2_outb_p(val,AUX_OUTPUT_PORT);
+ kbd_write_output(val);
}
-
-static unsigned int get_from_queue(void)
-{
- unsigned int result;
- unsigned long flags;
-
- save_flags(flags);
- cli();
- result = queue->buf[queue->tail];
- queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
- restore_flags(flags);
- return result;
-}
-
-
-static inline int queue_empty(void)
-{
- return queue->head == queue->tail;
-}
-
-
-
/*
* Interrupt from the auxiliary device: a character
* is waiting in the keyboard/aux controller.
*/
-
#ifdef CONFIG_SGI
/* On the SGI we export this routine because the keyboard chirps at
* the same interrupt level. The status and data bytes are passed
@@ -282,7 +230,7 @@ void aux_interrupt(unsigned char status, unsigned char data)
int head = queue->head;
int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1);
- if ((status & AUX_OBUF_FULL) != AUX_OBUF_FULL)
+ if ((status & AUX_STAT_OBF) != AUX_STAT_OBF)
return;
add_mouse_randomness(queue->buf[head] = data);
@@ -304,10 +252,10 @@ static void aux_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
int head = queue->head;
int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1);
- if ((ps2_inb(AUX_STATUS) & AUX_OBUF_FULL) != AUX_OBUF_FULL)
+ if ((kbd_read_status() & AUX_STAT_OBF) != AUX_STAT_OBF)
return;
- add_mouse_randomness(queue->buf[head] = ps2_inb(AUX_INPUT_PORT));
+ add_mouse_randomness(queue->buf[head] = kbd_read_input());
if (head != maxhead) {
head++;
head &= AUX_BUF_SIZE-1;
@@ -320,31 +268,6 @@ static void aux_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
}
#endif /* !defined(CONFIG_SGI) */
-/*
- * Interrupt handler for the 82C710 mouse port. A character
- * is waiting in the 82C710.
- */
-
-#ifdef CONFIG_82C710_MOUSE
-static void qp_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
-{
- int head = queue->head;
- int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1);
-
- add_mouse_randomness(queue->buf[head] = ps2_inb(qp_data));
- if (head != maxhead) {
- head++;
- head &= AUX_BUF_SIZE-1;
- }
- queue->head = head;
- aux_ready = 1;
- if (queue->fasync)
- kill_fasync(queue->fasync, SIGIO);
- wake_up_interruptible(&queue->proc_list);
-}
-#endif
-
-
static int release_aux(struct inode * inode, struct file * file)
{
fasync_aux(inode, file, 0);
@@ -352,57 +275,17 @@ static int release_aux(struct inode * inode, struct file * file)
return 0;
/* disable kbd bh to avoid mixing of cmd bytes */
disable_bh(KEYBOARD_BH);
- aux_write_cmd(AUX_INTS_OFF); /* disable controller ints */
+ aux_write_cmd(AUX_INTS_OFF); /* Disable controller ints */
poll_aux_status();
- ps2_outb_p(AUX_DISABLE,AUX_COMMAND); /* Disable Aux device */
+ kbd_write_command(KBD_CCMD_MOUSE_DISABLE); /* Disable Aux device */
poll_aux_status();
/* reenable kbd bh */
enable_bh(KEYBOARD_BH);
-#ifdef CONFIG_MCA
- free_irq(AUX_IRQ, inode);
-#else
-#ifndef CONFIG_SGI
- free_irq(AUX_IRQ, NULL);
-#endif
-#endif
+ ps2_free_irq(inode);
MOD_DEC_USE_COUNT;
return 0;
}
-#ifdef CONFIG_82C710_MOUSE
-static int release_qp(struct inode * inode, struct file * file)
-{
- unsigned char status;
-
- fasync_aux(inode, file, 0);
- if (!--qp_count) {
- if (!poll_qp_status())
- printk("Warning: Mouse device busy in release_qp()\n");
- status = ps2_inb_p(qp_status);
- ps2_outb_p(status & ~(QP_ENABLE|QP_INTS_ON), qp_status);
- if (!poll_qp_status())
- printk("Warning: Mouse device busy in release_qp()\n");
- free_irq(QP_IRQ, NULL);
- MOD_DEC_USE_COUNT;
- }
- return 0;
-}
-#endif
-
-static int fasync_aux(struct inode *inode, struct file *filp, int on)
-{
- int retval;
-
- retval = fasync_helper(inode, filp, on, &queue->fasync);
- if (retval < 0)
- return retval;
- return 0;
-}
-
-/*
- * Install interrupt handler.
- * Enable auxiliary device.
- */
static int open_aux(struct inode * inode, struct file * file)
{
@@ -415,14 +298,7 @@ static int open_aux(struct inode * inode, struct file * file)
return -EBUSY;
}
queue->head = queue->tail = 0; /* Flush input queue */
-#ifdef CONFIG_MCA
- if (request_irq(AUX_IRQ, aux_interrupt, MCA_bus ? SA_SHIRQ : 0, "PS/2 Mouse", inode))
-#else
-#ifndef CONFIG_SGI
- if (request_irq(AUX_IRQ, aux_interrupt, 0, "PS/2 Mouse", NULL))
-#endif
-#endif
- {
+ if(ps2_request_irq()) {
aux_count--;
return -EBUSY;
}
@@ -430,9 +306,9 @@ static int open_aux(struct inode * inode, struct file * file)
/* disable kbd bh to avoid mixing of cmd bytes */
disable_bh(KEYBOARD_BH);
poll_aux_status();
- ps2_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 */
+ kbd_write_command(KBD_CCMD_MOUSE_ENABLE); /* Enable Aux */
+ aux_write_dev(AUX_ENABLE_DEV); /* Enable aux device */
+ aux_write_cmd(AUX_INTS_ON); /* Enable controller ints */
poll_aux_status();
/* reenable kbd bh */
enable_bh(KEYBOARD_BH);
@@ -441,7 +317,112 @@ static int open_aux(struct inode * inode, struct file * file)
return 0;
}
+/*
+ * Write to the aux device.
+ */
+
+static long write_aux(struct inode * inode, struct file * file,
+ const char * buffer, unsigned long count)
+{
+ int retval = 0;
+
+ if (count) {
+ int written = 0;
+
+ /* disable kbd bh to avoid mixing of cmd bytes */
+ disable_bh(KEYBOARD_BH);
+
+ do {
+ char c;
+ if (!poll_aux_status())
+ break;
+ kbd_write_command(KBD_CCMD_WRITE_MOUSE);
+ if (!poll_aux_status())
+ break;
+ get_user(c, buffer++);
+ kbd_write_output(c);
+ written++;
+ } while (--count);
+ /* reenable kbd bh */
+ enable_bh(KEYBOARD_BH);
+ retval = -EIO;
+ if (written) {
+ retval = written;
+ inode->i_mtime = CURRENT_TIME;
+ }
+ }
+
+ return retval;
+}
+
+/*
+ * 82C710 Interface
+ */
+
#ifdef CONFIG_82C710_MOUSE
+
+#define QP_DATA 0x310 /* Data Port I/O Address */
+#define QP_STATUS 0x311 /* Status Port I/O Address */
+
+#define QP_DEV_IDLE 0x01 /* Device Idle */
+#define QP_RX_FULL 0x02 /* Device Char received */
+#define QP_TX_IDLE 0x04 /* Device XMIT Idle */
+#define QP_RESET 0x08 /* Device Reset */
+#define QP_INTS_ON 0x10 /* Device Interrupt On */
+#define QP_ERROR_FLAG 0x20 /* Device Error */
+#define QP_CLEAR 0x40 /* Device Clear */
+#define QP_ENABLE 0x80 /* Device Enable */
+
+#define QP_IRQ 12
+
+static int qp_present = 0;
+static int qp_count = 0;
+static int qp_data = QP_DATA;
+static int qp_status = QP_STATUS;
+
+static int poll_qp_status(void);
+static int probe_qp(void);
+
+/*
+ * Interrupt handler for the 82C710 mouse port. A character
+ * is waiting in the 82C710.
+ */
+
+static void qp_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
+{
+ int head = queue->head;
+ int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1);
+
+ add_mouse_randomness(queue->buf[head] = inb(qp_data));
+ if (head != maxhead) {
+ head++;
+ head &= AUX_BUF_SIZE-1;
+ }
+ queue->head = head;
+ aux_ready = 1;
+ if (queue->fasync)
+ kill_fasync(queue->fasync, SIGIO);
+ wake_up_interruptible(&queue->proc_list);
+}
+
+static int release_qp(struct inode * inode, struct file * file)
+{
+ unsigned char status;
+
+ fasync_aux(inode, file, 0);
+ if (!--qp_count) {
+ if (!poll_qp_status())
+ printk("Warning: Mouse device busy in release_qp()\n");
+ status = inb_p(qp_status);
+ outb_p(status & ~(QP_ENABLE|QP_INTS_ON), qp_status);
+ if (!poll_qp_status())
+ printk("Warning: Mouse device busy in release_qp()\n");
+ free_irq(QP_IRQ, NULL);
+ MOD_DEC_USE_COUNT;
+ }
+ return 0;
+}
+
/*
* Install interrupt handler.
* Enable the device, enable interrupts.
@@ -462,71 +443,30 @@ static int open_qp(struct inode * inode, struct file * file)
return -EBUSY;
}
- status = ps2_inb_p(qp_status);
+ status = inb_p(qp_status);
status |= (QP_ENABLE|QP_RESET);
- ps2_outb_p(status, qp_status);
+ outb_p(status, qp_status);
status &= ~(QP_RESET);
- ps2_outb_p(status, qp_status);
+ outb_p(status, qp_status);
queue->head = queue->tail = 0; /* Flush input queue */
status |= QP_INTS_ON;
- ps2_outb_p(status, qp_status); /* Enable interrupts */
+ outb_p(status, qp_status); /* Enable interrupts */
while (!poll_qp_status()) {
printk("Error: Mouse device busy in open_qp()\n");
qp_count--;
status &= ~(QP_ENABLE|QP_INTS_ON);
- ps2_outb_p(status, qp_status);
+ outb_p(status, qp_status);
free_irq(QP_IRQ, NULL);
return -EBUSY;
}
- ps2_outb_p(AUX_ENABLE_DEV, qp_data); /* Wake up mouse */
+ outb_p(AUX_ENABLE_DEV, qp_data); /* Wake up mouse */
MOD_INC_USE_COUNT;
return 0;
}
-#endif
-
-/*
- * Write to the aux device.
- */
-
-static long write_aux(struct inode * inode, struct file * file,
- const char * buffer, unsigned long count)
-{
- int retval = 0;
-
- if (count) {
- int written = 0;
-
- /* disable kbd bh to avoid mixing of cmd bytes */
- disable_bh(KEYBOARD_BH);
-
- do {
- char c;
- if (!poll_aux_status())
- break;
- ps2_outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
- if (!poll_aux_status())
- break;
- get_user(c, buffer++);
- ps2_outb_p(c, AUX_OUTPUT_PORT);
- written++;
- } while (--count);
- /* reenable kbd bh */
- enable_bh(KEYBOARD_BH);
- retval = -EIO;
- if (written) {
- retval = written;
- inode->i_mtime = CURRENT_TIME;
- }
- }
-
- return retval;
-}
-
-#ifdef CONFIG_82C710_MOUSE
/*
* Write to the 82C710 mouse device.
*/
@@ -541,13 +481,69 @@ static long write_qp(struct inode * inode, struct file * file,
if (!poll_qp_status())
return -EIO;
get_user(c, buffer++);
- ps2_outb_p(c, qp_data);
+ outb_p(c, qp_data);
}
inode->i_mtime = CURRENT_TIME;
return count;
}
+
+/*
+ * Wait for device to send output char and flush any input char.
+ */
+
+static int poll_qp_status(void)
+{
+ int retries=0;
+
+ while ((inb(qp_status)&(QP_RX_FULL|QP_TX_IDLE|QP_DEV_IDLE))
+ != (QP_DEV_IDLE|QP_TX_IDLE)
+ && retries < MAX_RETRIES) {
+
+ if (inb_p(qp_status)&(QP_RX_FULL))
+ inb_p(qp_data);
+ current->state = TASK_INTERRUPTIBLE;
+ current->timeout = jiffies + (5*HZ + 99) / 100;
+ schedule();
+ retries++;
+ }
+ return !(retries==MAX_RETRIES);
+}
+
+/*
+ * Function to read register in 82C710.
+ */
+
+static inline unsigned char read_710(unsigned char index)
+{
+ outb_p(index, 0x390); /* Write index */
+ return inb_p(0x391); /* Read the data */
+}
+
+/*
+ * See if we can find a 82C710 device. Read mouse address.
+ */
+
+__initfunc(static int probe_qp(void))
+{
+ outb_p(0x55, 0x2fa); /* Any value except 9, ff or 36 */
+ outb_p(0xaa, 0x3fa); /* Inverse of 55 */
+ outb_p(0x36, 0x3fa); /* Address the chip */
+ outb_p(0xe4, 0x3fa); /* 390/4; 390 = config address */
+ outb_p(0x1b, 0x2fa); /* Inverse of e4 */
+ if (read_710(0x0f) != 0xe4) /* Config address found? */
+ return 0; /* No: no 82C710 here */
+ qp_data = read_710(0x0d)*4; /* Get mouse I/O address */
+ qp_status = qp_data+1;
+ outb_p(0x0f, 0x390);
+ outb_p(0x0f, 0x391); /* Close config mode */
+ return 1;
+}
+
#endif
+/*
+ * Generic part continues...
+ */
/*
* Put bytes from input queue to buffer.
@@ -588,7 +584,6 @@ repeat:
return 0;
}
-
static unsigned int aux_poll(struct file *file, poll_table * wait)
{
poll_wait(&queue->proc_list, wait);
@@ -597,7 +592,6 @@ static unsigned int aux_poll(struct file *file, poll_table * wait)
return 0;
}
-
struct file_operations psaux_fops = {
NULL, /* seek */
read_aux,
@@ -612,7 +606,6 @@ struct file_operations psaux_fops = {
fasync_aux,
};
-
/*
* Initialize driver. First check for a 82C710 chip; if found
* forget about the Aux port and use the *_qp functions.
@@ -643,7 +636,7 @@ __initfunc(int psaux_init(void))
printk(KERN_INFO "PS/2 auxiliary pointing device detected -- driver installed.\n");
aux_present = 1;
#ifdef CONFIG_VT
- kbd_read_mask = AUX_OBUF_FULL;
+ kbd_read_mask = AUX_STAT_OBF;
#endif
} else {
return -EIO;
@@ -654,8 +647,8 @@ __initfunc(int psaux_init(void))
queue->head = queue->tail = 0;
queue->proc_list = NULL;
if (!qp_found) {
-#if defined INITIALIZE_DEVICE
- ps2_outb_p(AUX_ENABLE,AUX_COMMAND); /* Enable Aux */
+#ifdef INITIALIZE_DEVICE
+ kbd_write_command(AUX_ENABLE); /* Enable Aux */
aux_write_ack(AUX_SET_SAMPLE);
aux_write_ack(100); /* 100 samples/sec */
aux_write_ack(AUX_SET_RES);
@@ -663,11 +656,11 @@ __initfunc(int psaux_init(void))
aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */
poll_aux_status_nosleep();
#endif /* INITIALIZE_DEVICE */
- ps2_outb_p(KBD_CCMD_MOUSE_DISABLE, AUX_COMMAND); /* Disable Aux device */
- poll_aux_status_nosleep();
- ps2_outb_p(KBD_CCMD_WRITE_MODE, AUX_COMMAND);
+ kbd_write_command(KBD_CCMD_MOUSE_DISABLE); /* Disable Aux device */
poll_aux_status_nosleep();
- ps2_outb_p(AUX_INTS_OFF, AUX_OUTPUT_PORT);
+ kbd_write_command(KBD_CCMD_WRITE_MODE);
+ poll_aux_status_nosleep(); /* Disable interrupts */
+ kbd_write_output(AUX_INTS_OFF); /* on the controller */
}
return 0;
}
@@ -675,7 +668,7 @@ __initfunc(int psaux_init(void))
#ifdef MODULE
int init_module(void)
{
- return psaux_init(); /*?? Bjorn */
+ return psaux_init();
}
void cleanup_module(void)
@@ -684,84 +677,3 @@ void cleanup_module(void)
kfree(queue);
}
#endif
-
-static int poll_aux_status(void)
-{
- int retries=0;
-
- while ((ps2_inb(AUX_STATUS)&0x03) && retries < MAX_RETRIES) {
- if ((ps2_inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
- ps2_inb_p(AUX_INPUT_PORT);
- current->state = TASK_INTERRUPTIBLE;
- current->timeout = jiffies + (5*HZ + 99) / 100;
- schedule();
- retries++;
- }
- return !(retries==MAX_RETRIES);
-}
-
-static int poll_aux_status_nosleep(void)
-{
- int retries = 0;
-
- while ((ps2_inb(AUX_STATUS)&0x03) && retries < 1000000) {
- if ((ps2_inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
- ps2_inb_p(AUX_INPUT_PORT);
- retries++;
- }
- return !(retries == 1000000);
-}
-
-#ifdef CONFIG_82C710_MOUSE
-/*
- * Wait for device to send output char and flush any input char.
- */
-
-static int poll_qp_status(void)
-{
- int retries=0;
-
- while ((ps2_inb(qp_status)&(QP_RX_FULL|QP_TX_IDLE|QP_DEV_IDLE))
- != (QP_DEV_IDLE|QP_TX_IDLE)
- && retries < MAX_RETRIES) {
-
- if (ps2_inb_p(qp_status)&(QP_RX_FULL))
- ps2_inb_p(qp_data);
- current->state = TASK_INTERRUPTIBLE;
- current->timeout = jiffies + (5*HZ + 99) / 100;
- schedule();
- retries++;
- }
- return !(retries==MAX_RETRIES);
-}
-
-/*
- * Function to read register in 82C710.
- */
-
-static inline unsigned char read_710(unsigned char index)
-{
- ps2_outb_p(index, 0x390); /* Write index */
- return ps2_inb_p(0x391); /* Read the data */
-}
-
-/*
- * See if we can find a 82C710 device. Read mouse address.
- */
-
-__initfunc(static int probe_qp(void))
-{
- ps2_outb_p(0x55, 0x2fa); /* Any value except 9, ff or 36 */
- ps2_outb_p(0xaa, 0x3fa); /* Inverse of 55 */
- ps2_outb_p(0x36, 0x3fa); /* Address the chip */
- ps2_outb_p(0xe4, 0x3fa); /* 390/4; 390 = config address */
- ps2_outb_p(0x1b, 0x2fa); /* Inverse of e4 */
- if (read_710(0x0f) != 0xe4) /* Config address found? */
- return 0; /* No: no 82C710 here */
- qp_data = read_710(0x0d)*4; /* Get mouse I/O address */
- qp_status = qp_data+1;
- ps2_outb_p(0x0f, 0x390);
- ps2_outb_p(0x0f, 0x391); /* Close config mode */
- return 1;
-}
-#endif