root/drivers/char/psaux.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. aux_write_dev
  2. aux_write_ack
  3. aux_write_cmd
  4. get_from_queue
  5. queue_empty
  6. aux_interrupt
  7. qp_interrupt
  8. release_aux
  9. release_qp
  10. fasync_aux
  11. open_aux
  12. open_qp
  13. write_aux
  14. write_qp
  15. read_aux
  16. aux_select
  17. psaux_init
  18. cleanup_module
  19. poll_aux_status
  20. poll_aux_status_nosleep
  21. poll_qp_status
  22. read_710
  23. probe_qp

   1 /*
   2  * linux/drivers/char/psaux.c
   3  *
   4  * Driver for PS/2 type mouse by Johan Myreen.
   5  *
   6  * Supports pointing devices attached to a PS/2 type
   7  * Keyboard and Auxiliary Device Controller.
   8  *
   9  * Corrections in device setup for some laptop mice & trackballs.
  10  * 02Feb93  (troyer@saifr00.cfsat.Honeywell.COM,mch@wimsey.bc.ca)
  11  *
  12  * Changed to prevent keyboard lockups on AST Power Exec.
  13  * 28Jul93  Brad Bosch - brad@lachman.com
  14  *
  15  * Modified by Johan Myreen (jem@pandora.pp.fi) 04Aug93
  16  *   to include support for QuickPort mouse.
  17  *
  18  * Changed references to "QuickPort" with "82C710" since "QuickPort"
  19  * is not what this driver is all about -- QuickPort is just a
  20  * connector type, and this driver is for the mouse port on the Chips
  21  * & Technologies 82C710 interface chip. 15Nov93 jem@pandora.pp.fi
  22  *
  23  * Added support for SIGIO. 28Jul95 jem@pandora.pp.fi
  24  *
  25  * Rearranged SIGIO support to use code from tty_io.  9Sept95 ctm@ardi.com
  26  *
  27  * Modularised 8-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
  28  */
  29 
  30 /* Uncomment the following line if your mouse needs initialization. */
  31 
  32 /* #define INITIALIZE_DEVICE */
  33 
  34 #ifdef MODULE
  35 #include <linux/module.h>
  36 #include <linux/version.h>
  37 #else
  38 #define MOD_INC_USE_COUNT
  39 #define MOD_DEC_USE_COUNT
  40 #endif
  41  
  42 #include <linux/sched.h>
  43 #include <linux/kernel.h>
  44 #include <linux/fcntl.h>
  45 #include <linux/errno.h>
  46 #include <linux/timer.h>
  47 #include <linux/malloc.h>
  48 #include <linux/mouse.h>
  49 #include <linux/random.h>
  50 
  51 #include <asm/io.h>
  52 #include <asm/segment.h>
  53 #include <asm/system.h>
  54 
  55 #include <linux/config.h>
  56 
  57 #define PSMOUSE_MINOR      1            /* minor device # for this mouse */
  58 
  59 /* aux controller ports */
  60 #define AUX_INPUT_PORT  0x60            /* Aux device output buffer */
  61 #define AUX_OUTPUT_PORT 0x60            /* Aux device input buffer */
  62 #define AUX_COMMAND     0x64            /* Aux device command buffer */
  63 #define AUX_STATUS      0x64            /* Aux device status reg */
  64 
  65 /* aux controller status bits */
  66 #define AUX_OBUF_FULL   0x21            /* output buffer (from device) full */
  67 #define AUX_IBUF_FULL   0x02            /* input buffer (to device) full */
  68 
  69 /* aux controller commands */
  70 #define AUX_CMD_WRITE   0x60            /* value to write to controller */
  71 #define AUX_MAGIC_WRITE 0xd4            /* value to send aux device data */
  72 
  73 #define AUX_INTS_ON     0x47            /* enable controller interrupts */
  74 #define AUX_INTS_OFF    0x65            /* disable controller interrupts */
  75 
  76 #define AUX_DISABLE     0xa7            /* disable aux */
  77 #define AUX_ENABLE      0xa8            /* enable aux */
  78 
  79 /* aux device commands */
  80 #define AUX_SET_RES     0xe8            /* set resolution */
  81 #define AUX_SET_SCALE11 0xe6            /* set 1:1 scaling */
  82 #define AUX_SET_SCALE21 0xe7            /* set 2:1 scaling */
  83 #define AUX_GET_SCALE   0xe9            /* get scaling factor */
  84 #define AUX_SET_STREAM  0xea            /* set stream mode */
  85 #define AUX_SET_SAMPLE  0xf3            /* set sample rate */
  86 #define AUX_ENABLE_DEV  0xf4            /* enable aux device */
  87 #define AUX_DISABLE_DEV 0xf5            /* disable aux device */
  88 #define AUX_RESET       0xff            /* reset aux device */
  89 
  90 #define MAX_RETRIES     60              /* some aux operations take long time*/
  91 #if defined(__alpha__) && !defined(CONFIG_PCI)
  92 # define AUX_IRQ        9               /* Jensen is odd indeed */
  93 #else
  94 # define AUX_IRQ        12
  95 #endif
  96 #define AUX_BUF_SIZE    2048
  97 
  98 /* 82C710 definitions */
  99 
 100 #define QP_DATA         0x310           /* Data Port I/O Address */
 101 #define QP_STATUS       0x311           /* Status Port I/O Address */
 102 
 103 #define QP_DEV_IDLE     0x01            /* Device Idle */
 104 #define QP_RX_FULL      0x02            /* Device Char received */
 105 #define QP_TX_IDLE      0x04            /* Device XMIT Idle */
 106 #define QP_RESET        0x08            /* Device Reset */
 107 #define QP_INTS_ON      0x10            /* Device Interrupt On */
 108 #define QP_ERROR_FLAG   0x20            /* Device Error */
 109 #define QP_CLEAR        0x40            /* Device Clear */
 110 #define QP_ENABLE       0x80            /* Device Enable */
 111 
 112 #define QP_IRQ          12
 113 
 114 extern unsigned char aux_device_present;
 115 extern unsigned char kbd_read_mask;     /* from keyboard.c */
 116 
 117 struct aux_queue {
 118         unsigned long head;
 119         unsigned long tail;
 120         struct wait_queue *proc_list;
 121         struct fasync_struct *fasync;
 122         unsigned char buf[AUX_BUF_SIZE];
 123 };
 124 
 125 static struct aux_queue *queue;
 126 static int aux_ready = 0;
 127 static int aux_count = 0;
 128 static int aux_present = 0;
 129 static int poll_aux_status(void);
 130 static int poll_aux_status_nosleep(void);
 131 static int fasync_aux(struct inode *inode, struct file *filp, int on);
 132 
 133 #ifdef CONFIG_82C710_MOUSE
 134 static int qp_present = 0;
 135 static int qp_count = 0;
 136 static int qp_data = QP_DATA;
 137 static int qp_status = QP_STATUS;
 138 
 139 static int poll_qp_status(void);
 140 static int probe_qp(void);
 141 #endif
 142 
 143 
 144 /*
 145  * Write to aux device
 146  */
 147 
 148 static void aux_write_dev(int val)
     /* [previous][next][first][last][top][bottom][index][help] */
 149 {
 150         poll_aux_status();
 151         outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);    /* write magic cookie */
 152         poll_aux_status();
 153         outb_p(val,AUX_OUTPUT_PORT);            /* write data */
 154 }
 155 
 156 /*
 157  * Write to device & handle returned ack
 158  */
 159 #if defined INITIALIZE_DEVICE
 160 static int aux_write_ack(int val)
     /* [previous][next][first][last][top][bottom][index][help] */
 161 {
 162         int retries = 0;
 163 
 164         poll_aux_status_nosleep();
 165         outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
 166         poll_aux_status_nosleep();
 167         outb_p(val,AUX_OUTPUT_PORT);
 168         poll_aux_status_nosleep();
 169 
 170         if ((inb(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
 171         {
 172                 return (inb(AUX_INPUT_PORT));
 173         }
 174         return 0;
 175 }
 176 #endif /* INITIALIZE_DEVICE */
 177 
 178 /*
 179  * Write aux device command
 180  */
 181 
 182 static void aux_write_cmd(int val)
     /* [previous][next][first][last][top][bottom][index][help] */
 183 {
 184         poll_aux_status();
 185         outb_p(AUX_CMD_WRITE,AUX_COMMAND);
 186         poll_aux_status();
 187         outb_p(val,AUX_OUTPUT_PORT);
 188 }
 189 
 190 
 191 static unsigned int get_from_queue(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 192 {
 193         unsigned int result;
 194         unsigned long flags;
 195 
 196         save_flags(flags);
 197         cli();
 198         result = queue->buf[queue->tail];
 199         queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
 200         restore_flags(flags);
 201         return result;
 202 }
 203 
 204 
 205 static inline int queue_empty(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 206 {
 207         return queue->head == queue->tail;
 208 }
 209 
 210 
 211 
 212 /*
 213  * Interrupt from the auxiliary device: a character
 214  * is waiting in the keyboard/aux controller.
 215  */
 216 
 217 static void aux_interrupt(int cpl, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 218 {
 219         int head = queue->head;
 220         int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1);
 221 
 222         if ((inb(AUX_STATUS) & AUX_OBUF_FULL) != AUX_OBUF_FULL)
 223                 return;
 224 
 225         add_mouse_randomness(queue->buf[head] = inb(AUX_INPUT_PORT));
 226         if (head != maxhead) {
 227                 head++;
 228                 head &= AUX_BUF_SIZE-1;
 229         }
 230         queue->head = head;
 231         aux_ready = 1;
 232         if (queue->fasync)
 233                 kill_fasync(queue->fasync, SIGIO);
 234         wake_up_interruptible(&queue->proc_list);
 235 }
 236 
 237 /*
 238  * Interrupt handler for the 82C710 mouse port. A character
 239  * is waiting in the 82C710.
 240  */
 241 
 242 #ifdef CONFIG_82C710_MOUSE
 243 static void qp_interrupt(int cpl, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 244 {
 245         int head = queue->head;
 246         int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1);
 247 
 248         add_mouse_randomness(queue->buf[head] = inb(qp_data));
 249         if (head != maxhead) {
 250                 head++;
 251                 head &= AUX_BUF_SIZE-1;
 252         }
 253         queue->head = head;
 254         aux_ready = 1;
 255         if (queue->fasync)
 256                 kill_fasync(queue->fasync, SIGIO);
 257         wake_up_interruptible(&queue->proc_list);
 258 }
 259 #endif
 260 
 261 
 262 static void release_aux(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
 263 {
 264         fasync_aux(inode, file, 0);
 265         if (--aux_count)
 266                 return;
 267         aux_write_cmd(AUX_INTS_OFF);            /* disable controller ints */
 268         poll_aux_status();
 269         outb_p(AUX_DISABLE,AUX_COMMAND);        /* Disable Aux device */
 270         poll_aux_status();
 271         free_irq(AUX_IRQ);
 272         MOD_DEC_USE_COUNT;
 273 }
 274 
 275 #ifdef CONFIG_82C710_MOUSE
 276 static void release_qp(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
 277 {
 278         unsigned char status;
 279 
 280         fasync_aux(inode, file, 0);
 281         if (--qp_count)
 282                 return;
 283         if (!poll_qp_status())
 284                 printk("Warning: Mouse device busy in release_qp()\n");
 285         status = inb_p(qp_status);
 286         outb_p(status & ~(QP_ENABLE|QP_INTS_ON), qp_status);
 287         if (!poll_qp_status())
 288                 printk("Warning: Mouse device busy in release_qp()\n");
 289         free_irq(QP_IRQ);
 290         MOD_DEC_USE_COUNT;
 291 }
 292 #endif
 293 
 294 static int fasync_aux(struct inode *inode, struct file *filp, int on)
     /* [previous][next][first][last][top][bottom][index][help] */
 295 {
 296         int retval;
 297 
 298         retval = fasync_helper(inode, filp, on, &queue->fasync);
 299         if (retval < 0)
 300                 return retval;
 301         return 0;
 302 }
 303 
 304 /*
 305  * Install interrupt handler.
 306  * Enable auxiliary device.
 307  */
 308 
 309 static int open_aux(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
 310 {
 311         if (!aux_present)
 312                 return -ENODEV;
 313         if (aux_count++)
 314                 return 0;
 315         if (!poll_aux_status()) {
 316                 aux_count--;
 317                 return -EBUSY;
 318         }
 319         queue->head = queue->tail = 0;          /* Flush input queue */
 320         if (request_irq(AUX_IRQ, aux_interrupt, 0, "PS/2 Mouse")) {
 321                 aux_count--;
 322                 return -EBUSY;
 323         }
 324         poll_aux_status();
 325         outb_p(AUX_ENABLE,AUX_COMMAND);         /* Enable Aux */
 326         aux_write_dev(AUX_ENABLE_DEV);          /* enable aux device */
 327         aux_write_cmd(AUX_INTS_ON);             /* enable controller ints */
 328         poll_aux_status();
 329         aux_ready = 0;
 330         MOD_INC_USE_COUNT;
 331         return 0;
 332 }
 333 
 334 #ifdef CONFIG_82C710_MOUSE
 335 /*
 336  * Install interrupt handler.
 337  * Enable the device, enable interrupts. 
 338  */
 339 
 340 static int open_qp(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
 341 {
 342         unsigned char status;
 343 
 344         if (!qp_present)
 345                 return -EINVAL;
 346 
 347         if (qp_count++)
 348                 return 0;
 349 
 350         if (request_irq(QP_IRQ, qp_interrupt, 0, "PS/2 Mouse")) {
 351                 qp_count--;
 352                 return -EBUSY;
 353         }
 354 
 355         status = inb_p(qp_status);
 356         status |= (QP_ENABLE|QP_RESET);
 357         outb_p(status, qp_status);
 358         status &= ~(QP_RESET);
 359         outb_p(status, qp_status);
 360 
 361         queue->head = queue->tail = 0;          /* Flush input queue */
 362         status |= QP_INTS_ON;
 363         outb_p(status, qp_status);              /* Enable interrupts */
 364 
 365         while (!poll_qp_status()) {
 366                 printk("Error: Mouse device busy in open_qp()\n");
 367                 qp_count--;
 368                 status &= ~(QP_ENABLE|QP_INTS_ON);
 369                 outb_p(status, qp_status);
 370                 free_irq(QP_IRQ);
 371                 return -EBUSY;
 372         }
 373 
 374         outb_p(AUX_ENABLE_DEV, qp_data);        /* Wake up mouse */
 375         MOD_INC_USE_COUNT;
 376         return 0;
 377 }
 378 #endif
 379 
 380 /*
 381  * Write to the aux device.
 382  */
 383 
 384 static int write_aux(struct inode * inode, struct file * file, const char * buffer, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 385 {
 386         int i = count;
 387 
 388         while (i--) {
 389                 if (!poll_aux_status())
 390                         return -EIO;
 391                 outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
 392                 if (!poll_aux_status())
 393                         return -EIO;
 394                 outb_p(get_user(buffer++),AUX_OUTPUT_PORT);
 395         }
 396         inode->i_mtime = CURRENT_TIME;
 397         return count;
 398 }
 399 
 400 
 401 #ifdef CONFIG_82C710_MOUSE
 402 /*
 403  * Write to the 82C710 mouse device.
 404  */
 405 
 406 static int write_qp(struct inode * inode, struct file * file, const char * buffer, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 407 {
 408         int i = count;
 409 
 410         while (i--) {
 411                 if (!poll_qp_status())
 412                         return -EIO;
 413                 outb_p(get_user(buffer++), qp_data);
 414         }
 415         inode->i_mtime = CURRENT_TIME;
 416         return count;
 417 }
 418 #endif
 419 
 420 
 421 /*
 422  * Put bytes from input queue to buffer.
 423  */
 424 
 425 static int read_aux(struct inode * inode, struct file * file, char * buffer, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 426 {
 427         struct wait_queue wait = { current, NULL };
 428         int i = count;
 429         unsigned char c;
 430 
 431         if (queue_empty()) {
 432                 if (file->f_flags & O_NONBLOCK)
 433                         return -EAGAIN;
 434                 add_wait_queue(&queue->proc_list, &wait);
 435 repeat:
 436                 current->state = TASK_INTERRUPTIBLE;
 437                 if (queue_empty() && !(current->signal & ~current->blocked)) {
 438                         schedule();
 439                         goto repeat;
 440                 }
 441                 current->state = TASK_RUNNING;
 442                 remove_wait_queue(&queue->proc_list, &wait);
 443         }
 444         while (i > 0 && !queue_empty()) {
 445                 c = get_from_queue();
 446                 put_user(c, buffer++);
 447                 i--;
 448         }
 449         aux_ready = !queue_empty();
 450         if (count-i) {
 451                 inode->i_atime = CURRENT_TIME;
 452                 return count-i;
 453         }
 454         if (current->signal & ~current->blocked)
 455                 return -ERESTARTSYS;
 456         return 0;
 457 }
 458 
 459 
 460 static int aux_select(struct inode *inode, struct file *file, int sel_type, select_table * wait)
     /* [previous][next][first][last][top][bottom][index][help] */
 461 {
 462         if (sel_type != SEL_IN)
 463                 return 0;
 464         if (aux_ready)
 465                 return 1;
 466         select_wait(&queue->proc_list, wait);
 467         return 0;
 468 }
 469 
 470 
 471 struct file_operations psaux_fops = {
 472         NULL,           /* seek */
 473         read_aux,
 474         write_aux,
 475         NULL,           /* readdir */
 476         aux_select,
 477         NULL,           /* ioctl */
 478         NULL,           /* mmap */
 479         open_aux,
 480         release_aux,
 481         NULL,
 482         fasync_aux,
 483 };
 484 
 485 
 486 /*
 487  * Initialize driver. First check for a 82C710 chip; if found
 488  * forget about the Aux port and use the *_qp functions.
 489  */
 490 static struct mouse psaux_mouse = {
 491         PSMOUSE_MINOR, "ps2aux", &psaux_fops
 492 };
 493 
 494 int psaux_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 495 {
 496         int qp_found = 0;
 497 
 498 #ifdef CONFIG_82C710_MOUSE
 499         if ((qp_found = probe_qp())) {
 500                 printk("82C710 type pointing device detected -- driver installed.\n");
 501 /*              printk("82C710 address = %x (should be 0x310)\n", qp_data); */
 502                 qp_present = 1;
 503                 psaux_fops.write = write_qp;
 504                 psaux_fops.open = open_qp;
 505                 psaux_fops.release = release_qp;
 506         } else
 507 #endif
 508         if (aux_device_present == 0xaa) {
 509                 printk("PS/2 auxiliary pointing device detected -- driver installed.\n");
 510                 aux_present = 1;
 511                 kbd_read_mask = AUX_OBUF_FULL;
 512         } else {
 513                 return -EIO;
 514         }
 515         mouse_register(&psaux_mouse);
 516         queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
 517         memset(queue, 0, sizeof(*queue));
 518         queue->head = queue->tail = 0;
 519         queue->proc_list = NULL;
 520         if (!qp_found) {
 521 #if defined INITIALIZE_DEVICE
 522                 outb_p(AUX_ENABLE,AUX_COMMAND);         /* Enable Aux */
 523                 aux_write_ack(AUX_SET_SAMPLE);
 524                 aux_write_ack(100);                     /* 100 samples/sec */
 525                 aux_write_ack(AUX_SET_RES);
 526                 aux_write_ack(3);                       /* 8 counts per mm */
 527                 aux_write_ack(AUX_SET_SCALE21);         /* 2:1 scaling */
 528                 poll_aux_status_nosleep();
 529 #endif /* INITIALIZE_DEVICE */
 530                 outb_p(AUX_DISABLE,AUX_COMMAND);   /* Disable Aux device */
 531                 poll_aux_status_nosleep();
 532                 outb_p(AUX_CMD_WRITE,AUX_COMMAND);
 533                 poll_aux_status_nosleep();             /* Disable interrupts */
 534                 outb_p(AUX_INTS_OFF, AUX_OUTPUT_PORT); /*  on the controller */
 535         }
 536         return 0;
 537 }
 538 
 539 #ifdef MODULE
 540 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 541 {
 542         if (MOD_IN_USE)
 543                 printk("psaux: in use, remove delayed\n");
 544         mouse_deregister(&psaux_mouse);
 545 }
 546 #endif
 547 
 548 static int poll_aux_status(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 549 {
 550         int retries=0;
 551 
 552         while ((inb(AUX_STATUS)&0x03) && retries < MAX_RETRIES) {
 553                 if ((inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
 554                         inb_p(AUX_INPUT_PORT);
 555                 current->state = TASK_INTERRUPTIBLE;
 556                 current->timeout = jiffies + (5*HZ + 99) / 100;
 557                 schedule();
 558                 retries++;
 559         }
 560         return !(retries==MAX_RETRIES);
 561 }
 562 
 563 static int poll_aux_status_nosleep(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 564 {
 565         int retries = 0;
 566 
 567         while ((inb(AUX_STATUS)&0x03) && retries < 1000000) {
 568                 if ((inb_p(AUX_STATUS) & AUX_OBUF_FULL) == AUX_OBUF_FULL)
 569                         inb_p(AUX_INPUT_PORT);
 570                 retries++;
 571         }
 572         return !(retries == 1000000);
 573 }
 574 
 575 #ifdef CONFIG_82C710_MOUSE
 576 /*
 577  * Wait for device to send output char and flush any input char.
 578  */
 579 
 580 static int poll_qp_status(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 581 {
 582         int retries=0;
 583 
 584         while ((inb(qp_status)&(QP_RX_FULL|QP_TX_IDLE|QP_DEV_IDLE))
 585                        != (QP_DEV_IDLE|QP_TX_IDLE)
 586                        && retries < MAX_RETRIES) {
 587 
 588                 if (inb_p(qp_status)&(QP_RX_FULL))
 589                         inb_p(qp_data);
 590                 current->state = TASK_INTERRUPTIBLE;
 591                 current->timeout = jiffies + (5*HZ + 99) / 100;
 592                 schedule();
 593                 retries++;
 594         }
 595         return !(retries==MAX_RETRIES);
 596 }
 597 
 598 /*
 599  * Function to read register in 82C710.
 600  */
 601 
 602 static inline unsigned char read_710(unsigned char index)
     /* [previous][next][first][last][top][bottom][index][help] */
 603 {
 604         outb_p(index, 0x390);                   /* Write index */
 605         return inb_p(0x391);                    /* Read the data */
 606 }
 607 
 608 /*
 609  * See if we can find a 82C710 device. Read mouse address.
 610  */
 611 
 612 static int probe_qp(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 613 {
 614         outb_p(0x55, 0x2fa);                    /* Any value except 9, ff or 36 */
 615         outb_p(0xaa, 0x3fa);                    /* Inverse of 55 */
 616         outb_p(0x36, 0x3fa);                    /* Address the chip */
 617         outb_p(0xe4, 0x3fa);                    /* 390/4; 390 = config address */
 618         outb_p(0x1b, 0x2fa);                    /* Inverse of e4 */
 619         if (read_710(0x0f) != 0xe4)             /* Config address found? */
 620           return 0;                             /* No: no 82C710 here */
 621         qp_data = read_710(0x0d)*4;             /* Get mouse I/O address */
 622         qp_status = qp_data+1;
 623         outb_p(0x0f, 0x390);
 624         outb_p(0x0f, 0x391);                    /* Close config mode */
 625         return 1;
 626 }
 627 #endif

/* [previous][next][first][last][top][bottom][index][help] */