patch-2.1.123 linux/drivers/char/psaux.c
Next file: linux/drivers/char/qpmouse.c
Previous file: linux/drivers/char/pc_keyb.c
Back to the patch index
Back to the overall index
- Lines: 365
- Date:
Sat Sep 26 23:13:18 1998
- Orig file:
v2.1.122/linux/drivers/char/psaux.c
- Orig date:
Sat Sep 5 16:46:40 1998
diff -u --recursive --new-file v2.1.122/linux/drivers/char/psaux.c linux/drivers/char/psaux.c
@@ -12,14 +12,6 @@
* Changed to prevent keyboard lockups on AST Power Exec.
* 28Jul93 Brad Bosch - brad@lachman.com
*
- * Modified by Johan Myreen (jem@pandora.pp.fi) 04Aug93
- * to include support for QuickPort mouse.
- *
- * Changed references to "QuickPort" with "82C710" since "QuickPort"
- * is not what this driver is all about -- QuickPort is just a
- * connector type, and this driver is for the mouse port on the Chips
- * & Technologies 82C710 interface chip. 15Nov93 jem@pandora.pp.fi
- *
* Added support for SIGIO. 28Jul95 jem@pandora.pp.fi
*
* Rearranged SIGIO support to use code from tty_io. 9Sept95 ctm@ardi.com
@@ -35,6 +27,18 @@
* 13-Jan-1998, Richard Gooch <rgooch@atnf.csiro.au>
*/
+/*
+ * This really should be part of the pc_kbd driver - they share the same
+ * controller, and right now we have ridiculous synchronization problems.
+ * Some of the SMP bootup problems may be due to not getting synchronization
+ * right.
+ *
+ * I moved the C&T mouse driver to a file of its own, hopefully that will
+ * make it easier to eventually fix this all.
+ *
+ * Linus
+ */
+
/* Uncomment the following line if your mouse needs initialization. */
/* #define INITIALIZE_DEVICE */
@@ -78,13 +82,7 @@
};
static struct aux_queue *queue;
-static int aux_ready = 0;
static int aux_count = 0;
-static int aux_present = 0;
-
-/*
- * Shared subroutines
- */
static unsigned int get_from_queue(void)
{
@@ -234,7 +232,6 @@
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);
@@ -270,8 +267,6 @@
static int open_aux(struct inode * inode, struct file * file)
{
- if (!aux_present)
- return -ENODEV;
aux_start_atomic();
if (aux_count++) {
aux_end_atomic();
@@ -304,7 +299,6 @@
pckbd_read_mask = AUX_STAT_OBF;
#endif
- aux_ready = 0;
return 0;
}
@@ -344,196 +338,6 @@
}
/*
- * 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(-1, 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.
- */
-
-static int open_qp(struct inode * inode, struct file * file)
-{
- unsigned char status;
-
- if (!qp_present)
- return -EINVAL;
-
- if (qp_count++)
- return 0;
-
- if (request_irq(QP_IRQ, qp_interrupt, 0, "PS/2 Mouse", NULL)) {
- qp_count--;
- return -EBUSY;
- }
-
- status = inb_p(qp_status);
- status |= (QP_ENABLE|QP_RESET);
- outb_p(status, qp_status);
- status &= ~(QP_RESET);
- outb_p(status, qp_status);
-
- queue->head = queue->tail = 0; /* Flush input queue */
- status |= QP_INTS_ON;
- 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);
- outb_p(status, qp_status);
- free_irq(QP_IRQ, NULL);
- return -EBUSY;
- }
-
- outb_p(AUX_ENABLE_DEV, qp_data); /* Wake up mouse */
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * Write to the 82C710 mouse device.
- */
-
-static ssize_t write_qp(struct file * file, const char * buffer,
- size_t count, loff_t *ppos)
-{
- ssize_t i = count;
-
- while (i--) {
- char c;
- if (!poll_qp_status())
- return -EIO;
- get_user(c, buffer++);
- outb_p(c, qp_data);
- }
- file->f_dentry->d_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.
*/
@@ -562,7 +366,6 @@
put_user(c, buffer++);
i--;
}
- aux_ready = !queue_empty();
if (count-i) {
file->f_dentry->d_inode->i_atime = CURRENT_TIME;
return count-i;
@@ -575,7 +378,7 @@
static unsigned int aux_poll(struct file *file, poll_table * wait)
{
poll_wait(file, &queue->proc_list, wait);
- if (aux_ready)
+ if (!queue_empty())
return POLLIN | POLLRDNORM;
return 0;
}
@@ -596,8 +399,7 @@
};
/*
- * Initialize driver. First check for a 82C710 chip; if found
- * forget about the Aux port and use the *_qp functions.
+ * Initialize driver.
*/
static struct miscdevice psaux_mouse = {
PSMOUSE_MINOR, "psaux", &psaux_fops
@@ -605,48 +407,33 @@
__initfunc(int psaux_init(void))
{
- int qp_found = 0;
-
-#ifdef CONFIG_82C710_MOUSE
- if ((qp_found = probe_qp())) {
- printk(KERN_INFO "82C710 type pointing device detected -- driver installed.\n");
-/* printk("82C710 address = %x (should be 0x310)\n", qp_data); */
- qp_present = 1;
- psaux_fops.write = write_qp;
- psaux_fops.open = open_qp;
- psaux_fops.release = release_qp;
- } else
-#endif
- if (aux_device_present == 0xaa) {
- printk(KERN_INFO "PS/2 auxiliary pointing device detected -- driver installed.\n");
- aux_present = 1;
- } else {
+ if (aux_device_present != 0xaa)
return -EIO;
- }
+
+ printk(KERN_INFO "PS/2 auxiliary pointing device detected -- driver installed.\n");
misc_register(&psaux_mouse);
queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
memset(queue, 0, sizeof(*queue));
queue->head = queue->tail = 0;
queue->proc_list = NULL;
- if (!qp_found) {
- aux_start_atomic();
+
+ aux_start_atomic();
#ifdef INITIALIZE_DEVICE
- outb_p(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG); /* Enable Aux */
- aux_write_ack(AUX_SET_SAMPLE);
- aux_write_ack(100); /* 100 samples/sec */
- 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();
+ outb_p(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG); /* Enable Aux */
+ aux_write_ack(AUX_SET_SAMPLE);
+ aux_write_ack(100); /* 100 samples/sec */
+ 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();
#endif /* INITIALIZE_DEVICE */
- outb_p(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG); /* Disable Aux device */
- poll_aux_status();
- outb_p(KBD_CCMD_WRITE_MODE, KBD_CNTL_REG); /* Disable controller interrupts */
- poll_aux_status();
- outb_p(AUX_INTS_OFF, KBD_DATA_REG);
- poll_aux_status();
- aux_end_atomic();
- }
+ outb_p(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG); /* Disable Aux device */
+ poll_aux_status();
+ outb_p(KBD_CCMD_WRITE_MODE, KBD_CNTL_REG); /* Disable controller interrupts */
+ poll_aux_status();
+ outb_p(AUX_INTS_OFF, KBD_DATA_REG);
+ poll_aux_status();
+ aux_end_atomic();
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov