summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/psm.c
diff options
context:
space:
mode:
authornate <nate@FreeBSD.org>1996-11-15 06:17:36 +0000
committernate <nate@FreeBSD.org>1996-11-15 06:17:36 +0000
commit7ad9f1fc7f0c7f952767e11d81a8bec53d055d0b (patch)
treed8efc933a14207e6af94b920565da539e1ac7035 /sys/i386/isa/psm.c
parent244d25ed3a8775c648b5096a16f56b9a56921a02 (diff)
downloadFreeBSD-src-7ad9f1fc7f0c7f952767e11d81a8bec53d055d0b.zip
FreeBSD-src-7ad9f1fc7f0c7f952767e11d81a8bec53d055d0b.tar.gz
KNF'ify and fix boo-boo I made in last commit.
Diffstat (limited to 'sys/i386/isa/psm.c')
-rw-r--r--sys/i386/isa/psm.c1795
1 files changed, 910 insertions, 885 deletions
diff --git a/sys/i386/isa/psm.c b/sys/i386/isa/psm.c
index 9acfc30..03faf6c 100644
--- a/sys/i386/isa/psm.c
+++ b/sys/i386/isa/psm.c
@@ -19,7 +19,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: psm.c,v 1.26 1996/11/15 05:30:52 nate Exp $
+ * $Id: psm.c,v 1.27 1996/11/15 05:41:34 nate Exp $
*/
/*
@@ -48,7 +48,7 @@
*
* Hardware access routines and probe logic rewritten by
* Kazutaka Yokota <yokota@zodiac.mech.utsunomiya-u.ac.jp>
- * - 3 October 1996.
+ * - 3 October 1996.
* - 14 October 1996.
* - 22 October 1996.
* - 28 October 1996. Start adding IOCTLs.
@@ -70,7 +70,7 @@
#include <sys/syslog.h>
#ifdef DEVFS
#include <sys/devfsext.h>
-#endif /*DEVFS*/
+#endif
#include <i386/include/mouse.h>
#include <i386/include/clock.h>
@@ -79,23 +79,22 @@
#include <i386/isa/isa_device.h>
#include <i386/isa/kbdio.h>
-/* driver specific options: the following options may be set by
- `options' statements in the kernel configuration file. */
+/*
+ * driver specific options: the following options may be set by
+ * `options' statements in the kernel configuration file.
+ */
/* debugging */
#ifndef PSM_DEBUG
-#define PSM_DEBUG 0 /* controls debug logging:
- 0: no logging, 1: brief, 2: verbose */
+#define PSM_DEBUG 0 /* logging: 0: none, 1: brief, 2: verbose */
#endif
/* features */
-/* #define PSM_NOCHECKSYNC the driver does not check the header data
- byte, if defined */
+/* #define PSM_NOCHECKSYNC if defined, don't check the header data byte */
#ifndef PSM_ACCEL
-#define PSM_ACCEL 2 /* the default acceleration factor, must
- be one or greater; acceleration will be
- disabled if zero */
+#define PSM_ACCEL 2 /* must be one or greater; acceleration will be
+ * disabled if zero */
#endif
/* #define PSM_NOEMULATION disables protocol emulation */
@@ -112,59 +111,58 @@
#define PSM_MKMINOR(unit,block) (((unit) << 1) | ((block) ? 0:1))
#ifndef max
-#define max(x,y) ((x) > (y) ? (x) : (y))
+#define max(x,y) ((x) > (y) ? (x) : (y))
#endif
#ifndef min
-#define min(x,y) ((x) < (y) ? (x) : (y))
+#define min(x,y) ((x) < (y) ? (x) : (y))
#endif
/* mouse status block */
typedef struct mousestatus {
- int button; /* button status */
- int obutton; /* previous button status */
- int dx; /* x movement */
- int dy; /* y movement */
+ int button; /* button status */
+ int obutton; /* previous button status */
+ int dx; /* x movement */
+ int dy; /* y movement */
} mousestatus_t;
/* ring buffer */
-#define PSM_BUFSIZE 256
+#define PSM_BUFSIZE 256
typedef struct ringbuf {
- int count;
- int head;
- int tail;
- mousestatus_t buf[PSM_BUFSIZE];
+ int count;
+ int head;
+ int tail;
+ mousestatus_t buf[PSM_BUFSIZE];
} ringbuf_t;
/* driver control block */
typedef int (*packetfunc_t) __P((unsigned char *, int *, int, mousestatus_t *));
-static struct psm_softc { /* Driver status information */
- struct selinfo rsel; /* Process selecting for Input */
- unsigned char state; /* Mouse driver state */
- int addr; /* I/O port address */
- int command_byte; /* controller command byte */
- mousehw_t hw; /* hardware information */
- mousemode_t mode; /* operation mode */
- ringbuf_t queue; /* mouse status queue */
- packetfunc_t mkpacket; /* func. to turn queued data
- into output format */
- char ipacket[MOUSE_PS2_PACKETSIZE]; /* interim input buffer */
- unsigned char opacket[PSM_BUFSIZE]; /* output buffer */
- int inputbytes; /* # of bytes in the input buffer */
- int outputbytes; /* # of bytes in the output buffer */
- int outputhead; /* points the head of the output buffer */
- int button; /* the latest button state */
+static struct psm_softc { /* Driver status information */
+ struct selinfo rsel; /* Process selecting for Input */
+ unsigned char state; /* Mouse driver state */
+ int addr; /* I/O port address */
+ int command_byte; /* controller command byte */
+ mousehw_t hw; /* hardware information */
+ mousemode_t mode; /* operation mode */
+ ringbuf_t queue; /* mouse status queue */
+ packetfunc_t mkpacket; /* func. to turn queued data into output format */
+ char ipacket[MOUSE_PS2_PACKETSIZE]; /* interim input buffer */
+ unsigned char opacket[PSM_BUFSIZE]; /* output buffer */
+ int inputbytes; /* # of bytes in the input buffer */
+ int outputbytes; /* # of bytes in the output buffer */
+ int outputhead; /* points the head of the output buffer */
+ int button; /* the latest button state */
#ifdef DEVFS
- void *devfs_token;
- void *n_devfs_token;
+ void *devfs_token;
+ void *n_devfs_token;
#endif
} psm_softc[NPSM];
/* driver state flags (state) */
-#define PSM_VALID 0x80
-#define PSM_OPEN 1 /* Device is open */
-#define PSM_ASLP 2 /* Waiting for mouse data */
+#define PSM_VALID 0x80
+#define PSM_OPEN 1 /* Device is open */
+#define PSM_ASLP 2 /* Waiting for mouse data */
/* function prototypes */
static int psmprobe __P((struct isa_device *));
@@ -181,13 +179,12 @@ static d_select_t psmselect;
/* device driver declarateion */
struct isa_driver psmdriver = { psmprobe, psmattach, "psm", FALSE };
+#define CDEV_MAJOR 21
-#define CDEV_MAJOR 21
-
-static struct cdevsw psm_cdevsw = {
+static struct cdevsw psm_cdevsw = {
psmopen, psmclose, psmread, nowrite, /* 21 */
- psmioctl, nostop, nullreset, nodevtotty,
- psmselect, nommap, NULL, "psm", NULL, -1
+ psmioctl, nostop, nullreset, nodevtotty,
+ psmselect, nommap, NULL, "psm", NULL, -1
};
/* debug message level */
@@ -197,216 +194,227 @@ static int verbose = PSM_DEBUG;
static int
enable_aux_dev(int port)
{
- int res;
+ int res;
- res = send_aux_command(port,PSMC_ENABLE_DEV);
- if (verbose >= 2)
- log(LOG_DEBUG, "psm: ENABLE_DEV return code:%04x\n",res);
+ res = send_aux_command(port, PSMC_ENABLE_DEV);
+ if (verbose >= 2)
+ log(LOG_DEBUG, "psm: ENABLE_DEV return code:%04x\n", res);
- return (res == PSM_ACK);
+ return (res == PSM_ACK);
}
static int
disable_aux_dev(int port)
{
- int res;
+ int res;
- res = send_aux_command(port, PSMC_DISABLE_DEV);
- if (verbose >= 2)
- log(LOG_DEBUG, "psm: DISABLE_DEV return code:%04x\n",res);
+ res = send_aux_command(port, PSMC_DISABLE_DEV);
+ if (verbose >= 2)
+ log(LOG_DEBUG, "psm: DISABLE_DEV return code:%04x\n", res);
- return (res == PSM_ACK);
+ return (res == PSM_ACK);
}
static int
get_mouse_status(int port, int *status)
{
- int res;
+ int res;
- empty_both_buffers(port);
- res = send_aux_command(port,PSMC_SEND_DEV_STATUS);
- if (verbose >= 2)
- log(LOG_DEBUG, "psm: SEND_AUX_STATUS return code:%04x\n",res);
- if (res != PSM_ACK)
- return FALSE;
+ empty_both_buffers(port);
+ res = send_aux_command(port, PSMC_SEND_DEV_STATUS);
+ if (verbose >= 2)
+ log(LOG_DEBUG, "psm: SEND_AUX_STATUS return code:%04x\n", res);
+ if (res != PSM_ACK)
+ return FALSE;
- status[0] = read_aux_data(port);
- status[1] = read_aux_data(port);
- status[2] = read_aux_data(port);
+ status[0] = read_aux_data(port);
+ status[1] = read_aux_data(port);
+ status[2] = read_aux_data(port);
- return TRUE;
+ return TRUE;
}
static int
get_aux_id(int port)
{
- int retry;
- int id;
- int c;
-
- for(retry = KBD_MAXRETRY; retry > 0; --retry) {
- empty_both_buffers(port);
- write_aux_command(port,PSMC_SEND_DEV_ID);
- /* 10ms delay */
- DELAY(10000);
- c = read_controller_data(port);
- if (verbose >= 2)
- log(LOG_DEBUG, "psm: SEND_DEV_ID return code:%04x\n",c);
- if (c == PSM_ACK)
- break;
- }
- if (retry <= 0)
- return -1;
-
- id = read_aux_data(port);
- if (verbose >= 2)
- log(LOG_DEBUG, "psm: device ID: %04x\n",id);
-
- return id;
+ int retry;
+ int id;
+ int c;
+
+ for (retry = KBD_MAXRETRY; retry > 0; --retry) {
+ empty_both_buffers(port);
+ write_aux_command(port, PSMC_SEND_DEV_ID);
+ /* 10ms delay */
+ DELAY(10000);
+ c = read_controller_data(port);
+ if (verbose >= 2)
+ log(LOG_DEBUG, "psm: SEND_DEV_ID return code:%04x\n", c);
+ if (c == PSM_ACK)
+ break;
+ }
+ if (retry <= 0)
+ return -1;
+
+ id = read_aux_data(port);
+ if (verbose >= 2)
+ log(LOG_DEBUG, "psm: device ID: %04x\n", id);
+
+ return id;
}
static int
set_mouse_sampling_rate(int port, int rate)
{
- int res;
+ int res;
- res = send_aux_command_and_data(port,PSMC_SET_SAMPLING_RATE,rate);
- if (verbose >= 2)
- log(LOG_DEBUG, "psm: SET_SAMPLING_RATE (%d) %04x\n",rate,res);
+ res = send_aux_command_and_data(port, PSMC_SET_SAMPLING_RATE, rate);
+ if (verbose >= 2)
+ log(LOG_DEBUG, "psm: SET_SAMPLING_RATE (%d) %04x\n", rate, res);
- return ((res == PSM_ACK) ? rate : -1);
+ return ((res == PSM_ACK) ? rate : -1);
}
static int
set_mouse_scaling(int port)
{
- int res;
+ int res;
- res = send_aux_command(port,PSMC_SET_SCALING11);
- if (verbose >= 2)
- log(LOG_DEBUG, "psm: SET_SCALING11 return code:%04x\n",res);
+ res = send_aux_command(port, PSMC_SET_SCALING11);
+ if (verbose >= 2)
+ log(LOG_DEBUG, "psm: SET_SCALING11 return code:%04x\n", res);
- return (res == PSM_ACK);
+ return (res == PSM_ACK);
}
static int
set_mouse_resolution(int port, int res)
{
- static struct {
- int resolution;
- int code;
- } rescode[] = {
- { 25, PSMD_RESOLUTION_25 },
- { 50, PSMD_RESOLUTION_50 },
- { 100, PSMD_RESOLUTION_100 },
- { 200, PSMD_RESOLUTION_200 },
- { 400, PSMD_RESOLUTION_400 }, /* ?? */
- { 800, PSMD_RESOLUTION_800 }, /* ?? */
- { INT_MAX, PSMD_MAX_RESOLUTION },
- };
- int ret;
- int i;
-
- if (res <= 0)
- return FALSE;
- for(i = 0; rescode[i].resolution > 0; ++i) {
- if (rescode[i].resolution >= res)
- break;
- }
-
- for(; i >= 0; --i) {
- ret = send_aux_command_and_data(port,
- PSMC_SET_RESOLUTION,rescode[i].code);
- if (verbose >= 2)
- log(LOG_DEBUG, "psm: SET_RESOLUTION (%d) %04x\n",
- rescode[i].code,ret);
- if (ret == PSM_ACK)
- return rescode[i].resolution;
- }
-
- return (-1);
+ static struct {
+ int resolution;
+ int code;
+ } rescode[] = {
+ { 25, PSMD_RESOLUTION_25 },
+ { 50, PSMD_RESOLUTION_50 },
+ { 100, PSMD_RESOLUTION_100 },
+ { 200, PSMD_RESOLUTION_200 },
+ { 400, PSMD_RESOLUTION_400 }, /* ?? */
+ { 800, PSMD_RESOLUTION_800 }, /* ?? */
+ { INT_MAX, PSMD_MAX_RESOLUTION },
+ };
+ int ret;
+ int i;
+
+ if (res <= 0)
+ return FALSE;
+ for (i = 0; rescode[i].resolution > 0; ++i)
+ if (rescode[i].resolution >= res)
+ break;
+
+ for (; i >= 0; --i) {
+ ret = send_aux_command_and_data(port,
+ PSMC_SET_RESOLUTION, rescode[i].code);
+ if (verbose >= 2)
+ log(LOG_DEBUG, "psm: SET_RESOLUTION (%d) %04x\n",
+ rescode[i].code, ret);
+ if (ret == PSM_ACK)
+ return rescode[i].resolution;
+ }
+
+ return (-1);
}
-/* NOTE: once `set_mouse_mode()' is called, the mouse device must be
- re-enabled by calling `enable_aux_dev()' */
+/*
+ * NOTE: once `set_mouse_mode()' is called, the mouse device must be
+ * re-enabled by calling `enable_aux_dev()'
+ */
static int
set_mouse_mode(int port)
{
- int res;
+ int res;
- res = send_aux_command(port,PSMC_SET_STREAM_MODE);
- if (verbose >= 2)
- log(LOG_DEBUG, "psm: SET_STREAM_MODE return code:%04x\n",res);
+ res = send_aux_command(port, PSMC_SET_STREAM_MODE);
+ if (verbose >= 2)
+ log(LOG_DEBUG, "psm: SET_STREAM_MODE return code:%04x\n", res);
- return (res == PSM_ACK);
+ return (res == PSM_ACK);
}
static int
get_mouse_buttons(int port)
{
- int c = 2; /* assume two buttons by default */
- int status[3];
-
- /* NOTE: a special sequence to obtain Logitech-Mouse-specific
- information: set resolution to 25 ppi, set scaling to 1:1,
- set scaling to 1:1, set scaling to 1:1. Then the second
- byte of the mouse status bytes is the number of available
- buttons. */
- if (!set_mouse_resolution(port,25))
- return c;
- if (set_mouse_scaling(port) && set_mouse_scaling(port)
- && set_mouse_scaling(port) && get_mouse_status(port,status)) {
- if (verbose) {
- log(LOG_DEBUG, "psm: status %02x %02x %02x (get_mouse_buttons)\n",
- status[0],status[1],status[2]);
- }
- if (status[1] == 3)
- return 3;
- }
- return c;
+ int c = 2; /* assume two buttons by default */
+ int status[3];
+
+ /*
+ * NOTE: a special sequence to obtain Logitech-Mouse-specific
+ * information: set resolution to 25 ppi, set scaling to 1:1, set
+ * scaling to 1:1, set scaling to 1:1. Then the second byte of the
+ * mouse status bytes is the number of available buttons.
+ */
+ if (!set_mouse_resolution(port, 25))
+ return c;
+ if (set_mouse_scaling(port) && set_mouse_scaling(port)
+ && set_mouse_scaling(port) && get_mouse_status(port, status)) {
+ if (verbose) {
+ log(LOG_DEBUG, "psm: status %02x %02x %02x (get_mouse_buttons)\n",
+ status[0], status[1], status[2]);
+ }
+ if (status[1] == 3)
+ return 3;
+ }
+ return c;
}
-/* FIXME: someday, I will get the list of valid pointing devices and
- their IDs... */
+/*
+ * FIXME:XXX
+ * someday, I will get the list of valid pointing devices and
+ * their IDs...
+ */
static int
is_a_mouse(int id)
{
- static int valid_ids[] = {
- PSM_MOUSE_ID, /* mouse */
- PSM_BALLPOINT_ID, /* ballpoint device */
- -1 /* end of table */
- };
- /*
- int i;
-
- for(i = 0; valid_ids[i] >= 0; ++i) {
- if (valid_ids[i] == id)
- return TRUE;
- }
- return FALSE;
- */
- return TRUE;
+ static int valid_ids[] = {
+ PSM_MOUSE_ID, /* mouse */
+ PSM_BALLPOINT_ID, /* ballpoint device */
+ -1 /* end of table */
+ };
+#if 0
+ int i;
+
+ for(i = 0; valid_ids[i] >= 0; ++i)
+ if (valid_ids[i] == id)
+ return TRUE;
+ return FALSE;
+#endif
+ return TRUE;
}
static void
recover_from_error(int port)
{
- /* discard anything left in the output buffer */
- empty_both_buffers(port);
-
- /* NOTE: KBDC_RESET_KBD may not restore the communication between
- the keyboard and the controller. */
- /* reset_kbd(port); */
- /* NOTE: somehow diagnostic and keyboard port test commands bring
- the keyboard back. */
- test_controller(port);
- test_kbd_port(port);
+ /* discard anything left in the output buffer */
+ empty_both_buffers(port);
+
+#if 0
+ /*
+ * NOTE: KBDC_RESET_KBD may not restore the communication between the
+ * keyboard and the controller.
+ */
+ reset_kbd(port);
+#else
+ /*
+ * NOTE: somehow diagnostic and keyboard port test commands bring the
+ * keyboard back.
+ */
+ test_controller(port);
+ test_kbd_port(port);
+#endif
}
static void
restore_controller(int port, int command_byte)
{
- set_controller_command_byte(port,command_byte,0);
+ set_controller_command_byte(port, command_byte, 0);
}
/* psm driver entry points */
@@ -414,756 +422,773 @@ restore_controller(int port, int command_byte)
static int
psmprobe(struct isa_device *dvp)
{
- int unit = dvp->id_unit;
- int ioport = dvp->id_iobase;
- struct psm_softc *sc;
- int stat[3];
- int i;
-
- /* validate unit number */
- if (unit >= NPSM)
- return (0);
-
- sc = &psm_softc[unit];
- sc->addr = ioport;
- if (bootverbose)
- ++verbose;
-
- /* FIXME: the keyboard interrupt should be disabled while
- probing a mouse? */
-
- /* NOTE: two bits in the command byte controls the operation of
- the aux port (mouse port): the aux port disable bit (bit 5) and
- the aux port interrupt (IRQ 12) enable bit (bit 2).
- When this probe routine is called, there are following possibilities
- about the presence of the aux port and the PS/2 mouse.
-
- Case 1: aux port disabled (bit 5:1), aux int. disabled (bit 2:0)
- The aux port most certainly exists. A device may or may not be
- connected to the port. No driver is probably installed yet.
-
- Case 2: aux port enabled (bit 5:0), aux int. disabled (bit 2:0)
- Three possibile situations here:
-
- Case 2a:
- The aux port does not exist, therefore, is not explicitly disabled.
- Case 2b:
- The aux port exists. A device and a driver may exist,
- using the device in the polling(remote) mode.
- Case 2c:
- The aux port exists. A device may exist, but someone who knows
- nothing about the aux port has set the command byte this way
- (this is the case with `syscons').
-
- Case 3: aux port disabled (bit 5:1), aux int. enabled (bit 2:1)
- The aux port exists, but someone is controlloing the device and
- temporalily disabled the port.
-
- Case 4: aux port enabled (bit 5:0), aux int. enabled (bit 2:1)
- The aux port exists, a device is attached to the port, and
- someone is controlling the device. Some BIOS set the bits this
- way after boot.
-
- All in all, it is no use examing the bits for detecting
- the presence of the port and the mouse device.
- */
-
- /* save the current command byte; it will be used later */
- write_controller_command(ioport,KBDC_GET_COMMAND_BYTE);
- sc->command_byte = read_controller_data(ioport);
- if (verbose) {
- printf("psm%d: current command byte:%04x\n",
- unit,sc->command_byte);
- }
- if (sc->command_byte == -1) {
- printf("psm%d: unable to get the current command byte value.\n",
- unit);
- return (0);
- }
-
- /* disable the keyboard port while probing the aux port, which
- must be enabled during this routine */
- write_controller_command(ioport,KBDC_DISABLE_KBD_PORT);
- set_controller_command_byte(ioport,
- sc->command_byte
- & ~(KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS),
- KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
- | KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
-
- /* NOTE: `test_aux_port()' is designed to return with zero
- if the aux port exists and is functioning. However, some
- controllers appears to respond with zero even when the aux port
- doesn't exist. (It may be that this is only the case when the
- controller DOES have the aux port but the port is not wired
- on the motherboard.) The keyboard controllers without the port,
- such as the original AT, are supporsed to return with
- an error code or simply time out. In any case, we have to
- continue probing the port even when the controller passes
- this test.
- */
- switch((i = test_aux_port(ioport))) {
- case 0: /* no error */
- break;
- case -1: /* time out */
- default: /* error */
- recover_from_error(ioport);
- restore_controller(ioport,sc->command_byte);
- if (verbose)
- printf("psm%d: the aux port is not functioning (%d).\n",
- unit,i);
- if (bootverbose)
- --verbose;
- return (0);
- }
-
- /* NOTE: some controllers appears to hang the `keyboard' when
- the aux port doesn't exist and `PSMC_RESET_DEV' is issued. */
- if (!reset_aux_dev(ioport)) {
- recover_from_error(ioport);
- restore_controller(ioport,sc->command_byte);
- if (verbose)
- printf("psm%d: failed to reset the aux device.\n",unit);
- return (0);
- }
-
- /* both the aux port and the aux device is functioning, see
- if the device can be enabled.
- NOTE: when enabled, the device will start sending data;
- we shall immediately disable the device once we know
- the device can be enabled. */
- if (!enable_aux_dev(ioport) || !disable_aux_dev(ioport)) {
- restore_controller(ioport,sc->command_byte);
- if (verbose)
- printf("psm%d: failed to enable the aux device.\n",unit);
- if (bootverbose)
- --verbose;
- return (0);
- }
- empty_both_buffers(ioport); /* remove stray data if any */
-
- /* hardware information */
- sc->hw.iftype = MOUSE_IF_PS2;
-
- /* verify the device is a mouse */
- sc->hw.hwid = get_aux_id(ioport);
- if (!is_a_mouse(sc->hw.hwid)) {
- restore_controller(ioport,sc->command_byte);
- if (verbose)
- printf("psm%d: unknown device type (%d).\n",unit,sc->hw.hwid);
- if (bootverbose)
- --verbose;
- return (0);
- }
- switch (sc->hw.hwid) {
- case PSM_BALLPOINT_ID:
- sc->hw.type = MOUSE_TRACKBALL;
- break;
- case PSM_MOUSE_ID:
- sc->hw.type = MOUSE_MOUSE;
- break;
- default:
- sc->hw.type = MOUSE_UNKNOWN;
- break;
- }
-
- /* # of buttons */
- sc->hw.buttons = get_mouse_buttons(ioport);
-
- /* set mouse parameters */
- /* FIXME: I don't know if these parameters are reasonable */
- /* FIXME: should we set them in `psmattach()' rather than here? */
- sc->mode.rate = set_mouse_sampling_rate(ioport,PSMD_DEFAULT_RATE);
- sc->mode.resolution =
- set_mouse_resolution(ioport,PSMD_DEFAULT_RESOLUTION);
- set_mouse_scaling(ioport); /* 1:1 scaling */
- set_mouse_mode(ioport); /* stream mode */
-
- /* just check the status of the mouse */
- if (verbose) {
- get_mouse_status(ioport,stat);
- log(LOG_DEBUG, "psm%d: status %02x %02x %02x\n",
- unit,stat[0],stat[1],stat[2]);
- }
-
- /* disable the aux port for now... */
- /* WARNING: we save the controller command byte and use it later
- during `psmopen()' and `psmclose()'. This will be OK, so long
- as the keyboard/console device driver won't change the command
- byte in the course of its operation (this is the case with
- `syscons'). If not,... */
- sc->command_byte &= ~KBD_AUX_CONTROL_BITS;
- set_controller_command_byte(ioport,sc->command_byte,
- KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
-
- /* done */
- return (IO_PSMSIZE);
+ int unit = dvp->id_unit;
+ int ioport = dvp->id_iobase;
+ struct psm_softc *sc;
+ int stat[3];
+ int i;
+
+ /* validate unit number */
+ if (unit >= NPSM)
+ return (0);
+
+ sc = &psm_softc[unit];
+ sc->addr = ioport;
+ if (bootverbose)
+ ++verbose;
+
+ /*
+ * FIXME:XXX
+ * the keyboard interrupt should be disabled while probing a
+ * mouse?
+ */
+
+ /*
+ * NOTE: two bits in the command byte controls the operation of the
+ * aux port (mouse port): the aux port disable bit (bit 5) and the aux
+ * port interrupt (IRQ 12) enable bit (bit 2). When this probe routine
+ * is called, there are following possibilities about the presence of
+ * the aux port and the PS/2 mouse.
+ *
+ * Case 1: aux port disabled (bit 5:1), aux int. disabled (bit 2:0) The
+ * aux port most certainly exists. A device may or may not be
+ * connected to the port. No driver is probably installed yet.
+ *
+ * Case 2: aux port enabled (bit 5:0), aux int. disabled (bit 2:0) Three
+ * possibile situations here:
+ *
+ * Case 2a: The aux port does not exist, therefore, is not explicitly
+ * disabled. Case 2b: The aux port exists. A device and a driver may
+ * exist, using the device in the polling(remote) mode. Case 2c: The
+ * aux port exists. A device may exist, but someone who knows nothing
+ * about the aux port has set the command byte this way (this is the
+ * case with `syscons').
+ *
+ * Case 3: aux port disabled (bit 5:1), aux int. enabled (bit 2:1) The
+ * aux port exists, but someone is controlloing the device and
+ * temporalily disabled the port.
+ *
+ * Case 4: aux port enabled (bit 5:0), aux int. enabled (bit 2:1) The aux
+ * port exists, a device is attached to the port, and someone is
+ * controlling the device. Some BIOS set the bits this way after boot.
+ *
+ * All in all, it is no use examing the bits for detecting the presence
+ * of the port and the mouse device.
+ */
+
+ /* save the current command byte; it will be used later */
+ write_controller_command(ioport, KBDC_GET_COMMAND_BYTE);
+ sc->command_byte = read_controller_data(ioport);
+ if (verbose) {
+ printf("psm%d: current command byte:%04x\n",
+ unit, sc->command_byte);
+ }
+ if (sc->command_byte == -1) {
+ printf("psm%d: unable to get the current command byte value.\n",
+ unit);
+ return (0);
+ }
+
+ /*
+ * disable the keyboard port while probing the aux port, which must be
+ * enabled during this routine
+ */
+ write_controller_command(ioport, KBDC_DISABLE_KBD_PORT);
+ set_controller_command_byte(ioport,
+ sc->command_byte
+ & ~(KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS),
+ KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
+ | KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+
+ /*
+ * NOTE: `test_aux_port()' is designed to return with zero if the aux
+ * port exists and is functioning. However, some controllers appears
+ * to respond with zero even when the aux port doesn't exist. (It may
+ * be that this is only the case when the controller DOES have the aux
+ * port but the port is not wired on the motherboard.) The keyboard
+ * controllers without the port, such as the original AT, are
+ * supporsed to return with an error code or simply time out. In any
+ * case, we have to continue probing the port even when the controller
+ * passes this test.
+ */
+ switch ((i = test_aux_port(ioport))) {
+ case 0: /* no error */
+ break;
+ case -1: /* time out */
+ default: /* error */
+ recover_from_error(ioport);
+ restore_controller(ioport, sc->command_byte);
+ if (verbose)
+ printf("psm%d: the aux port is not functioning (%d).\n",
+ unit, i);
+ if (bootverbose)
+ --verbose;
+ return (0);
+ }
+
+ /*
+ * NOTE: some controllers appears to hang the `keyboard' when the aux
+ * port doesn't exist and `PSMC_RESET_DEV' is issued.
+ */
+ if (!reset_aux_dev(ioport)) {
+ recover_from_error(ioport);
+ restore_controller(ioport, sc->command_byte);
+ if (verbose)
+ printf("psm%d: failed to reset the aux device.\n", unit);
+ return (0);
+ }
+ /*
+ * both the aux port and the aux device is functioning, see if the
+ * device can be enabled. NOTE: when enabled, the device will start
+ * sending data; we shall immediately disable the device once we know
+ * the device can be enabled.
+ */
+ if (!enable_aux_dev(ioport) || !disable_aux_dev(ioport)) {
+ restore_controller(ioport, sc->command_byte);
+ if (verbose)
+ printf("psm%d: failed to enable the aux device.\n", unit);
+ if (bootverbose)
+ --verbose;
+ return (0);
+ }
+ empty_both_buffers(ioport); /* remove stray data if any */
+
+ /* hardware information */
+ sc->hw.iftype = MOUSE_IF_PS2;
+
+ /* verify the device is a mouse */
+ sc->hw.hwid = get_aux_id(ioport);
+ if (!is_a_mouse(sc->hw.hwid)) {
+ restore_controller(ioport, sc->command_byte);
+ if (verbose)
+ printf("psm%d: unknown device type (%d).\n", unit, sc->hw.hwid);
+ if (bootverbose)
+ --verbose;
+ return (0);
+ }
+ switch (sc->hw.hwid) {
+ case PSM_BALLPOINT_ID:
+ sc->hw.type = MOUSE_TRACKBALL;
+ break;
+ case PSM_MOUSE_ID:
+ sc->hw.type = MOUSE_MOUSE;
+ break;
+ default:
+ sc->hw.type = MOUSE_UNKNOWN;
+ break;
+ }
+
+ /* # of buttons */
+ sc->hw.buttons = get_mouse_buttons(ioport);
+
+ /* set mouse parameters */
+
+ /* FIXME:XXX I don't know if these parameters are reasonable */
+ /* FIXME:XXX should we set them in `psmattach()' rather than here? */
+ sc->mode.rate = set_mouse_sampling_rate(ioport, PSMD_DEFAULT_RATE);
+ sc->mode.resolution =
+ set_mouse_resolution(ioport, PSMD_DEFAULT_RESOLUTION);
+ set_mouse_scaling(ioport); /* 1:1 scaling */
+ set_mouse_mode(ioport); /* stream mode */
+
+ /* just check the status of the mouse */
+ if (verbose) {
+ get_mouse_status(ioport, stat);
+ log(LOG_DEBUG, "psm%d: status %02x %02x %02x\n",
+ unit, stat[0], stat[1], stat[2]);
+ }
+
+ /* disable the aux port for now... */
+
+ /*
+ * WARNING: we save the controller command byte and use it later
+ * during `psmopen()' and `psmclose()'. This will be OK, so long as
+ * the keyboard/console device driver won't change the command byte in
+ * the course of its operation (this is the case with `syscons'). If
+ * not,...
+ */
+ sc->command_byte &= ~KBD_AUX_CONTROL_BITS;
+ set_controller_command_byte(ioport, sc->command_byte,
+ KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+
+ /* done */
+ return (IO_PSMSIZE);
}
static int
psmattach(struct isa_device *dvp)
{
- int unit = dvp->id_unit;
- struct psm_softc *sc = &psm_softc[unit];
-
- /* initial operation mode */
- sc->mode.accelfactor = PSM_ACCEL;
- sc->mode.protocol = MOUSE_PROTO_PS2;
- sc->mkpacket = mkps2;
-
- /* Setup initial state */
- sc->state = PSM_VALID;
-
- /* Done */
-#ifdef DEVFS
- sc->devfs_token =
- devfs_add_devswf(&psm_cdevsw, PSM_MKMINOR(unit,TRUE),
- DV_CHR, 0, 0, 0666, "psm%d", unit);
- sc->n_devfs_token =
- devfs_add_devswf(&psm_cdevsw, PSM_MKMINOR(unit,FALSE),
- DV_CHR,0, 0, 0666, "npsm%d", unit);
+ int unit = dvp->id_unit;
+ struct psm_softc *sc = &psm_softc[unit];
+
+ /* initial operation mode */
+ sc->mode.accelfactor = PSM_ACCEL;
+ sc->mode.protocol = MOUSE_PROTO_PS2;
+ sc->mkpacket = mkps2;
+
+ /* Setup initial state */
+ sc->state = PSM_VALID;
+
+ /* Done */
+#ifdef DEVFS
+ sc->devfs_token =
+ devfs_add_devswf(&psm_cdevsw, PSM_MKMINOR(unit, TRUE),
+ DV_CHR, 0, 0, 0666, "psm%d", unit);
+ sc->n_devfs_token =
+ devfs_add_devswf(&psm_cdevsw, PSM_MKMINOR(unit, FALSE),
+ DV_CHR, 0, 0, 0666, "npsm%d", unit);
#endif
- printf("psm%d: device ID %d, %d buttons?\n",
- unit,sc->hw.hwid,sc->hw.buttons);
+ printf("psm%d: device ID %d, %d buttons?\n",
+ unit, sc->hw.hwid, sc->hw.buttons);
- if (bootverbose)
- --verbose;
+ if (bootverbose)
+ --verbose;
- return (1);
- /* return (0); XXX eh? usually 1 indicates success */
+ return (1);
}
static int
psmopen(dev_t dev, int flag, int fmt, struct proc *p)
{
- int unit = PSM_UNIT(dev);
- int ioport;
- struct psm_softc *sc;
- int stat[3];
-
- /* Validate unit number */
- if (unit >= NPSM)
- return (ENXIO);
-
- /* Get device data */
- sc = &psm_softc[unit];
- if ((sc->state & PSM_VALID) == 0)
- return (ENXIO);
- ioport = sc->addr;
-
- /* Disallow multiple opens */
- if (sc->state & PSM_OPEN)
- return (EBUSY);
-
- /* Initialize state */
- sc->state |= PSM_OPEN;
- sc->rsel.si_flags = 0;
- sc->rsel.si_pid = 0;
-
- /* flush the event queue */
- sc->queue.count = 0;
- sc->queue.head = 0;
- sc->queue.tail = 0;
- sc->button = 0;
-
- /* empty input/output buffers */
- sc->inputbytes = 0;
- sc->outputbytes = 0;
- sc->outputhead = 0;
-
- /* enable the aux port and temporalily disable the keyboard */
- write_controller_command(ioport,KBDC_DISABLE_KBD_PORT);
- set_controller_command_byte(ioport,
- sc->command_byte & ~KBD_KBD_CONTROL_BITS,
- KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
- | KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
-
- /* enable the mouse device */
- if (!enable_aux_dev(ioport)) {
- set_controller_command_byte(ioport,sc->command_byte,
- KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
- log(LOG_ERR, "psm%d: unable to enable the pointing device.\n",unit);
- return (EIO);
- }
-
- if (verbose >= 2) {
- get_mouse_status(ioport,stat);
- log(LOG_DEBUG,"psm%d: status %02x %02x %02x\n",
- unit,stat[0],stat[1],stat[2]);
- }
-
- /* enable the aux port and interrupt */
- set_controller_command_byte(ioport,sc->command_byte,
- KBD_ENABLE_AUX_PORT | KBD_ENABLE_AUX_INT);
-
- /* done */
- return (0);
+ int unit = PSM_UNIT(dev);
+ int ioport;
+ struct psm_softc *sc;
+ int stat[3];
+
+ /* Validate unit number */
+ if (unit >= NPSM)
+ return (ENXIO);
+
+ /* Get device data */
+ sc = &psm_softc[unit];
+ if ((sc->state & PSM_VALID) == 0)
+ return (ENXIO);
+ ioport = sc->addr;
+
+ /* Disallow multiple opens */
+ if (sc->state & PSM_OPEN)
+ return (EBUSY);
+
+ /* Initialize state */
+ sc->state |= PSM_OPEN;
+ sc->rsel.si_flags = 0;
+ sc->rsel.si_pid = 0;
+
+ /* flush the event queue */
+ sc->queue.count = 0;
+ sc->queue.head = 0;
+ sc->queue.tail = 0;
+ sc->button = 0;
+
+ /* empty input/output buffers */
+ sc->inputbytes = 0;
+ sc->outputbytes = 0;
+ sc->outputhead = 0;
+
+ /* enable the aux port and temporalily disable the keyboard */
+ write_controller_command(ioport, KBDC_DISABLE_KBD_PORT);
+ set_controller_command_byte(ioport,
+ sc->command_byte & ~KBD_KBD_CONTROL_BITS,
+ KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
+ | KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+
+ /* enable the mouse device */
+ if (!enable_aux_dev(ioport)) {
+ set_controller_command_byte(ioport, sc->command_byte,
+ KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+ log(LOG_ERR, "psm%d: unable to enable the pointing device.\n", unit);
+ return (EIO);
+ }
+ if (verbose >= 2) {
+ get_mouse_status(ioport, stat);
+ log(LOG_DEBUG, "psm%d: status %02x %02x %02x\n",
+ unit, stat[0], stat[1], stat[2]);
+ }
+ /* enable the aux port and interrupt */
+ set_controller_command_byte(ioport, sc->command_byte,
+ KBD_ENABLE_AUX_PORT | KBD_ENABLE_AUX_INT);
+
+ /* done */
+ return (0);
}
static int
psmclose(dev_t dev, int flag, int fmt, struct proc *p)
{
- struct psm_softc *sc = &psm_softc[PSM_UNIT(dev)];
- int ioport = sc->addr;
+ struct psm_softc *sc = &psm_softc[PSM_UNIT(dev)];
+ int ioport = sc->addr;
- /* disable the aux interrupt */
- set_controller_command_byte(ioport,sc->command_byte,
- KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+ /* disable the aux interrupt */
+ set_controller_command_byte(ioport, sc->command_byte,
+ KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
- /* remove anything left in the output buffer */
- empty_aux_buffer(ioport);
+ /* remove anything left in the output buffer */
+ empty_aux_buffer(ioport);
- /* disable the aux device, port and interrupt */
- disable_aux_dev(ioport);
- set_controller_command_byte(ioport,sc->command_byte,
- KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+ /* disable the aux device, port and interrupt */
+ disable_aux_dev(ioport);
+ set_controller_command_byte(ioport, sc->command_byte,
+ KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
- /* remove anything left in the output buffer */
- empty_aux_buffer(ioport);
+ /* remove anything left in the output buffer */
+ empty_aux_buffer(ioport);
- /* Complete the close */
- sc->state &= ~PSM_OPEN;
+ /* Complete the close */
+ sc->state &= ~PSM_OPEN;
- /* close is almost always successful */
- return (0);
+ /* close is almost always successful */
+ return (0);
}
static int
mkms(unsigned char *buf, int *len, int maxlen, register mousestatus_t *status)
{
- static int butmap[] = {
- 0, MOUSE_MSS_BUTTON3DOWN, MOUSE_MSS_BUTTON2DOWN,
- MOUSE_MSS_BUTTON3DOWN | MOUSE_MSS_BUTTON2DOWN,
- MOUSE_MSS_BUTTON1DOWN,
- MOUSE_MSS_BUTTON3DOWN | MOUSE_MSS_BUTTON1DOWN,
- MOUSE_MSS_BUTTON2DOWN | MOUSE_MSS_BUTTON1DOWN,
- MOUSE_MSS_BUTTON3DOWN | MOUSE_MSS_BUTTON2DOWN | MOUSE_MSS_BUTTON1DOWN,
- };
- unsigned char delta;
-
- if (maxlen - *len < MOUSE_MSS_PACKETSIZE)
- return FALSE;
-
- buf[0] = MOUSE_MSS_SYNC;
- buf[0] |= butmap[status->button & BUTSTATMASK];
-
- if (status->dx < -128)
- delta = 0x80; /* -128 */
- else if (status->dx > 127)
- delta = 0x7f; /* 127 */
- else
- delta = (unsigned char)status->dx;
- buf[0] |= (delta & 0xc0) >> 6; /* bit 6-7 */
- buf[1] = delta & 0x3f; /* bit 0-5 */
-
- if (status->dy < -128)
- delta = 0x80; /* -128 */
- else if (status->dy > 127)
- delta = 0x7f; /* 127 */
- else
- delta = (unsigned char)status->dy;
- buf[0] |= (delta & 0xc0) >> 4; /* bit 6-7 */
- buf[2] = delta & 0x3f; /* bit 0-5 */
-
- *len += MOUSE_MSS_PACKETSIZE;
-
- return TRUE;
+ static int butmap[] = {
+ 0,
+ MOUSE_MSS_BUTTON3DOWN, MOUSE_MSS_BUTTON2DOWN,
+ MOUSE_MSS_BUTTON3DOWN | MOUSE_MSS_BUTTON2DOWN,
+ MOUSE_MSS_BUTTON1DOWN,
+ MOUSE_MSS_BUTTON3DOWN | MOUSE_MSS_BUTTON1DOWN,
+ MOUSE_MSS_BUTTON2DOWN | MOUSE_MSS_BUTTON1DOWN,
+ MOUSE_MSS_BUTTON3DOWN | MOUSE_MSS_BUTTON2DOWN | MOUSE_MSS_BUTTON1DOWN,
+ };
+ unsigned char delta;
+
+ if (maxlen - *len < MOUSE_MSS_PACKETSIZE)
+ return FALSE;
+
+ buf[0] = MOUSE_MSS_SYNC;
+ buf[0] |= butmap[status->button & BUTSTATMASK];
+
+ if (status->dx < -128)
+ delta = 0x80; /* -128 */
+ else
+ if (status->dx > 127)
+ delta = 0x7f; /* 127 */
+ else
+ delta = (unsigned char) status->dx;
+ buf[0] |= (delta & 0xc0) >> 6; /* bit 6-7 */
+ buf[1] = delta & 0x3f; /* bit 0-5 */
+
+ if (status->dy < -128)
+ delta = 0x80; /* -128 */
+ else
+ if (status->dy > 127)
+ delta = 0x7f; /* 127 */
+ else
+ delta = (unsigned char) status->dy;
+ buf[0] |= (delta & 0xc0) >> 4; /* bit 6-7 */
+ buf[2] = delta & 0x3f; /* bit 0-5 */
+
+ *len += MOUSE_MSS_PACKETSIZE;
+
+ return TRUE;
}
static int
mkmsc(unsigned char *buf, int *len, int maxlen, register mousestatus_t *status)
{
- static int butmap[] = {
- 0, MOUSE_MSC_BUTTON3UP, MOUSE_MSC_BUTTON2UP,
- MOUSE_MSC_BUTTON3UP | MOUSE_MSC_BUTTON2UP,
- MOUSE_MSC_BUTTON1UP,
- MOUSE_MSC_BUTTON3UP | MOUSE_MSC_BUTTON1UP,
- MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON1UP,
- MOUSE_MSC_BUTTON3UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON1UP,
- };
- unsigned char delta;
-
- if (maxlen - *len < MOUSE_PS2_PACKETSIZE)
- return FALSE;
-
- buf[0] = MOUSE_MSC_SYNC;
- buf[0] |= ~butmap[status->button & BUTSTATMASK] & MOUSE_MSC_BUTTONS;
-
- if (status->dx < -128)
- delta = 0x80; /* -128 */
- else if (status->dx > 127)
- delta = 0x7f; /* 127 */
- else
- delta = (unsigned char)status->dx;
- buf[1] = delta >> 2;
- buf[3] = delta - buf[1];
-
- if (status->dy < -128)
- delta = 0x80; /* -128 */
- else if (status->dy > 127)
- delta = 0x7f; /* 127 */
- else
- delta = (unsigned char)status->dy;
- buf[2] = delta >> 2;
- buf[4] = delta - buf[2];
-
- *len += MOUSE_MSC_PACKETSIZE;
-
- return TRUE;
+ static int butmap[] = {
+ 0,
+ MOUSE_MSC_BUTTON3UP, MOUSE_MSC_BUTTON2UP,
+ MOUSE_MSC_BUTTON3UP | MOUSE_MSC_BUTTON2UP,
+ MOUSE_MSC_BUTTON1UP,
+ MOUSE_MSC_BUTTON3UP | MOUSE_MSC_BUTTON1UP,
+ MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON1UP,
+ MOUSE_MSC_BUTTON3UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON1UP,
+ };
+ unsigned char delta;
+
+ if (maxlen - *len < MOUSE_PS2_PACKETSIZE)
+ return FALSE;
+
+ buf[0] = MOUSE_MSC_SYNC;
+ buf[0] |= ~butmap[status->button & BUTSTATMASK] & MOUSE_MSC_BUTTONS;
+
+ if (status->dx < -128)
+ delta = 0x80; /* -128 */
+ else
+ if (status->dx > 127)
+ delta = 0x7f; /* 127 */
+ else
+ delta = (unsigned char) status->dx;
+ buf[1] = delta >> 2;
+ buf[3] = delta - buf[1];
+
+ if (status->dy < -128)
+ delta = 0x80; /* -128 */
+ else
+ if (status->dy > 127)
+ delta = 0x7f; /* 127 */
+ else
+ delta = (unsigned char) status->dy;
+ buf[2] = delta >> 2;
+ buf[4] = delta - buf[2];
+
+ *len += MOUSE_MSC_PACKETSIZE;
+
+ return TRUE;
}
static int
-mkps2(unsigned char *buf, int *len, int maxlen,r egister mousestatus_t *status)
+mkps2(unsigned char *buf, int *len, int maxlen, register mousestatus_t *status)
{
- static int butmap[] = {
- 0, MOUSE_PS2_BUTTON3DOWN, MOUSE_PS2_BUTTON2DOWN,
- MOUSE_PS2_BUTTON3DOWN | MOUSE_PS2_BUTTON2DOWN,
- MOUSE_PS2_BUTTON1DOWN,
- MOUSE_PS2_BUTTON3DOWN | MOUSE_PS2_BUTTON1DOWN,
- MOUSE_PS2_BUTTON2DOWN | MOUSE_PS2_BUTTON1DOWN,
- MOUSE_PS2_BUTTON3DOWN | MOUSE_PS2_BUTTON2DOWN | MOUSE_PS2_BUTTON1DOWN,
- };
- register int delta;
-
- if (maxlen - *len < MOUSE_PS2_PACKETSIZE)
- return FALSE;
-
- buf[0] = MOUSE_PS2_SYNC;
- buf[0] |= butmap[status->button & BUTSTATMASK];
-
- if (status->dx < -128)
- delta = -128;
- else if (status->dx > 127)
- delta = 127;
- else
- delta = status->dx;
- if (delta < 0)
- buf[0] |= MOUSE_PS2_XNEG;
- buf[1] = delta;
-
- if (status->dy < -128)
- delta = -128;
- else if (status->dy > 127)
- delta = 127;
- else
- delta = status->dy;
- if (delta < 0)
- buf[0] |= MOUSE_PS2_YNEG;
- buf[2] = delta;
-
- *len += MOUSE_PS2_PACKETSIZE;
-
- return TRUE;
+ static int butmap[] = {
+ 0,
+ MOUSE_PS2_BUTTON3DOWN, MOUSE_PS2_BUTTON2DOWN,
+ MOUSE_PS2_BUTTON3DOWN | MOUSE_PS2_BUTTON2DOWN,
+ MOUSE_PS2_BUTTON1DOWN,
+ MOUSE_PS2_BUTTON3DOWN | MOUSE_PS2_BUTTON1DOWN,
+ MOUSE_PS2_BUTTON2DOWN | MOUSE_PS2_BUTTON1DOWN,
+ MOUSE_PS2_BUTTON3DOWN | MOUSE_PS2_BUTTON2DOWN | MOUSE_PS2_BUTTON1DOWN,
+ };
+ register int delta;
+
+ if (maxlen - *len < MOUSE_PS2_PACKETSIZE)
+ return FALSE;
+
+ buf[0] = MOUSE_PS2_SYNC;
+ buf[0] |= butmap[status->button & BUTSTATMASK];
+
+ if (status->dx < -128)
+ delta = -128;
+ else
+ if (status->dx > 127)
+ delta = 127;
+ else
+ delta = status->dx;
+ if (delta < 0)
+ buf[0] |= MOUSE_PS2_XNEG;
+ buf[1] = delta;
+
+ if (status->dy < -128)
+ delta = -128;
+ else
+ if (status->dy > 127)
+ delta = 127;
+ else
+ delta = status->dy;
+ if (delta < 0)
+ buf[0] |= MOUSE_PS2_YNEG;
+ buf[2] = delta;
+
+ *len += MOUSE_PS2_PACKETSIZE;
+
+ return TRUE;
}
static int
psmread(dev_t dev, struct uio *uio, int flag)
{
- register struct psm_softc *sc = &psm_softc[PSM_UNIT(dev)];
- unsigned int length;
- int error;
- int s;
- int i;
-
- /* block until mouse activity occured */
- s = spltty();
- if ((sc->outputbytes <= 0) && (sc->queue.count <= 0)) {
- while (sc->queue.count <= 0) {
- if (PSM_NBLOCKIO(dev)) {
- splx(s);
- return (EWOULDBLOCK);
- }
- sc->state |= PSM_ASLP;
- error = tsleep((caddr_t)sc, PZERO | PCATCH,
- "psmread", 0);
- if (error) {
- splx(s);
- return (error);
- }
- }
- }
-
- if (sc->outputbytes >= uio->uio_resid) {
- /* nothing to be done */
- } else {
- if (sc->outputbytes > 0) {
- bcopy(&sc->opacket[sc->outputhead],sc->opacket,
- sc->outputbytes);
- }
- sc->outputhead = 0;
- for(i = sc->queue.head; sc->queue.count > 0;
- i = (i + 1) % PSM_BUFSIZE, --sc->queue.count) {
- if (!(*sc->mkpacket)(&sc->opacket[sc->outputbytes],
- &sc->outputbytes,PSM_BUFSIZE,&sc->queue.buf[i]))
- break;
- }
- sc->queue.head = i;
- }
-
- /* allow interrupts again */
- splx(s);
-
- /* copy data to user process */
- length = min(sc->outputbytes,uio->uio_resid);
- error = uiomove(&sc->opacket[sc->outputhead], length, uio);
- if (error)
- return (error);
- sc->outputhead += length;
- sc->outputbytes -= length;
-
- return (error);
+ register struct psm_softc *sc = &psm_softc[PSM_UNIT(dev)];
+ unsigned int length;
+ int error;
+ int s;
+ int i;
+
+ /* block until mouse activity occured */
+ s = spltty();
+ if ((sc->outputbytes <= 0) && (sc->queue.count <= 0)) {
+ while (sc->queue.count <= 0) {
+ if (PSM_NBLOCKIO(dev)) {
+ splx(s);
+ return (EWOULDBLOCK);
+ }
+ sc->state |= PSM_ASLP;
+ error = tsleep((caddr_t) sc, PZERO | PCATCH,
+ "psmread", 0);
+ if (error) {
+ splx(s);
+ return (error);
+ }
+ }
+ }
+ if (sc->outputbytes >= uio->uio_resid) {
+ /* nothing to be done */
+ } else {
+ if (sc->outputbytes > 0) {
+ bcopy(&sc->opacket[sc->outputhead], sc->opacket,
+ sc->outputbytes);
+ }
+ sc->outputhead = 0;
+ for (i = sc->queue.head; sc->queue.count > 0;
+ i = (i + 1) % PSM_BUFSIZE, --sc->queue.count) {
+ if (!(*sc->mkpacket) (&sc->opacket[sc->outputbytes],
+ &sc->outputbytes, PSM_BUFSIZE, &sc->queue.buf[i]))
+ break;
+ }
+ sc->queue.head = i;
+ }
+
+ /* allow interrupts again */
+ splx(s);
+
+ /* copy data to user process */
+ length = min(sc->outputbytes, uio->uio_resid);
+ error = uiomove(&sc->opacket[sc->outputhead], length, uio);
+ if (error)
+ return (error);
+ sc->outputhead += length;
+ sc->outputbytes -= length;
+
+ return (error);
}
static int
psmioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
{
- struct psm_softc *sc = &psm_softc[PSM_UNIT(dev)];
- mouseinfo_t info;
- mousestatus_t *ms;
- packetfunc_t func;
- int error = 0;
- int s;
-
- /* Perform IOCTL command */
- switch (cmd) {
-
- case MOUSE_GETINFO:
- *(mousehw_t *)addr = sc->hw;
- break;
-
- case MOUSE_GETMODE:
- *(mousemode_t *)addr = sc->mode;
- break;
-
- case MOUSE_SETMODE:
- if (((mousemode_t *)addr)->rate < 0) {
- error = EINVAL;
- break;
- }
- if (((mousemode_t *)addr)->resolution < 0) {
- error = EINVAL;
- break;
- }
+ struct psm_softc *sc = &psm_softc[PSM_UNIT(dev)];
+ mouseinfo_t info;
+ mousestatus_t *ms;
+ packetfunc_t func;
+ int error = 0;
+ int s;
+
+ /* Perform IOCTL command */
+ switch (cmd) {
+
+ case MOUSE_GETINFO:
+ *(mousehw_t *) addr = sc->hw;
+ break;
+
+ case MOUSE_GETMODE:
+ *(mousemode_t *) addr = sc->mode;
+ break;
+
+ case MOUSE_SETMODE:
+ if (((mousemode_t *) addr)->rate < 0) {
+ error = EINVAL;
+ break;
+ }
+ if (((mousemode_t *) addr)->resolution < 0) {
+ error = EINVAL;
+ break;
+ }
#ifndef PSM_NOEMULATION
- switch (((mousemode_t *)addr)->protocol) {
- case MOUSE_PROTO_MS:
- func = mkms;
- break;
- case MOUSE_PROTO_MSC:
- func = mkmsc;
- break;
- case MOUSE_PROTO_PS2:
- func = mkps2;
- break;
- default:
- error = EINVAL;
- func = (packetfunc_t)NULL;
- break;
- }
- if (error)
- break;
-#endif /* PSM_NOEMULATION */
- if (((mousemode_t *)addr)->accelfactor < 0) {
- error = EINVAL;
- break;
- }
-
- s = spltty(); /* disable interrupt while updating */
- sc->mode.rate = (((mousemode_t *)addr)->rate == 0) ?
- PSMD_DEFAULT_RATE :
- min(((mousemode_t *)addr)->rate,PSMD_MAX_RATE);
- sc->mode.resolution = (((mousemode_t *)addr)->resolution == 0) ?
- PSMD_DEFAULT_RESOLUTION :
- ((mousemode_t *)addr)->resolution;
-
- /* temporalily disable the keyboard */
- write_controller_command(sc->addr,KBDC_DISABLE_KBD_PORT);
- set_controller_command_byte(sc->addr,
- sc->command_byte & ~KBD_KBD_CONTROL_BITS,
- KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
- | KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
-
- /* program the mouse */
- sc->mode.rate = set_mouse_sampling_rate(sc->addr,sc->mode.rate);
- sc->mode.resolution =
- set_mouse_resolution(sc->addr,sc->mode.resolution);
-
- /* enable the aux port and interrupt */
- set_controller_command_byte(sc->addr,sc->command_byte,
- KBD_ENABLE_AUX_PORT | KBD_ENABLE_AUX_INT);
+ switch (((mousemode_t *) addr)->protocol) {
+ case MOUSE_PROTO_MS:
+ func = mkms;
+ break;
+ case MOUSE_PROTO_MSC:
+ func = mkmsc;
+ break;
+ case MOUSE_PROTO_PS2:
+ func = mkps2;
+ break;
+ default:
+ error = EINVAL;
+ func = (packetfunc_t) NULL;
+ break;
+ }
+ if (error)
+ break;
+#endif /* PSM_NOEMULATION */
+ if (((mousemode_t *) addr)->accelfactor < 0) {
+ error = EINVAL;
+ break;
+ }
+ s = spltty(); /* disable interrupt while updating */
+ sc->mode.rate = (((mousemode_t *) addr)->rate == 0) ?
+ PSMD_DEFAULT_RATE :
+ min(((mousemode_t *) addr)->rate, PSMD_MAX_RATE);
+ sc->mode.resolution = (((mousemode_t *) addr)->resolution == 0) ?
+ PSMD_DEFAULT_RESOLUTION :
+ ((mousemode_t *) addr)->resolution;
+
+ /* temporalily disable the keyboard */
+ write_controller_command(sc->addr, KBDC_DISABLE_KBD_PORT);
+ set_controller_command_byte(sc->addr,
+ sc->command_byte & ~KBD_KBD_CONTROL_BITS,
+ KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
+ | KBD_ENABLE_AUX_PORT | KBD_DISABLE_AUX_INT);
+
+ /* program the mouse */
+ sc->mode.rate = set_mouse_sampling_rate(sc->addr, sc->mode.rate);
+ sc->mode.resolution =
+ set_mouse_resolution(sc->addr, sc->mode.resolution);
+
+ /* enable the aux port and interrupt */
+ set_controller_command_byte(sc->addr, sc->command_byte,
+ KBD_ENABLE_AUX_PORT | KBD_ENABLE_AUX_INT);
#ifndef PSM_NOEMULATION
- sc->mode.protocol = ((mousemode_t *)addr)->protocol;
- sc->mkpacket = func;
- sc->outputbytes = 0;
- sc->outputhead = 0;
-#endif /* PSM_NOEMULATION */
- sc->mode.accelfactor = ((mousemode_t *)addr)->accelfactor;
-
- splx(s);
- break;
-
- case MOUSEIOCREAD: /* FIXME: this should go... */
- error = EINVAL;
- break;
-
- case MOUSE_GETSTATE:
- info.status = 0;
- info.xmotion = 0;
- info.ymotion = 0;
-
- s = spltty();
- if (sc->queue.count > 0) {
- ms = &sc->queue.buf[sc->queue.head];
-
- /* button status */
- info.status = ms->button; /* BUT?STAT bits */
- info.status |= /* BUT?CHNG bits */
- ((ms->button ^ ms->obutton) << 3);
- /* mouse motion */
- info.xmotion = ms->dx;
- info.ymotion = ms->dy;
- if ((info.xmotion != 0) || (info.ymotion != 0))
- info.status |= MOVEMENT;
-
- sc->queue.head = (sc->queue.head + 1) % PSM_BUFSIZE;
- --sc->queue.count;
- }
- splx(s);
-
- *(mouseinfo_t *)addr = info;
- break;
-
- default:
- error = EINVAL;
- break;
- }
-
- /* Return error code */
- return (error);
+ sc->mode.protocol = ((mousemode_t *) addr)->protocol;
+ sc->mkpacket = func;
+ sc->outputbytes = 0;
+ sc->outputhead = 0;
+#endif /* PSM_NOEMULATION */
+ sc->mode.accelfactor = ((mousemode_t *) addr)->accelfactor;
+
+ splx(s);
+ break;
+
+ case MOUSEIOCREAD: /* FIXME:XXX this should go... */
+ error = EINVAL;
+ break;
+
+ case MOUSE_GETSTATE:
+ info.status = 0;
+ info.xmotion = 0;
+ info.ymotion = 0;
+
+ s = spltty();
+ if (sc->queue.count > 0) {
+ ms = &sc->queue.buf[sc->queue.head];
+
+ /* button status */
+ info.status = ms->button; /* BUT?STAT bits */
+ info.status |= /* BUT?CHNG bits */
+ ((ms->button ^ ms->obutton) << 3);
+ /* mouse motion */
+ info.xmotion = ms->dx;
+ info.ymotion = ms->dy;
+ if ((info.xmotion != 0) || (info.ymotion != 0))
+ info.status |= MOVEMENT;
+
+ sc->queue.head = (sc->queue.head + 1) % PSM_BUFSIZE;
+ --sc->queue.count;
+ }
+ splx(s);
+
+ *(mouseinfo_t *) addr = info;
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+
+ /* Return error code */
+ return (error);
}
void
psmintr(int unit)
{
- /* the table to turn PS/2 mouse button bits (MOUSE_PS2_BUTTON?DOWN)
- into `mouseinfo' button bits (BUT?STAT). */
- static butmap[8] = {
- 0, BUT1STAT, BUT3STAT, BUT1STAT | BUT3STAT,
- BUT2STAT, BUT1STAT | BUT2STAT, BUT2STAT | BUT3STAT,
- BUT1STAT | BUT2STAT | BUT3STAT
- };
- register struct psm_softc *sc = &psm_softc[unit];
- int ioport = sc->addr;
- mousestatus_t *ms;
- unsigned char c;
- int x, y;
-
- /* is this really for us? */
- if ((inb(ioport + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
- != KBDS_AUX_BUFFER_FULL)
- return;
-
- /* read a byte */
- c = inb(ioport + KBD_DATA_PORT);
-
- /* discard the byte if the device is not open */
- if ((sc->state & PSM_OPEN) == 0)
- return;
-
- /* interpret data bytes
- FIXME: there seems no way to reliably re-synchronize with
- the PS/2 mouse once we are out of sync. Sure, there is
- sync bits in the first data byte, but the second and the
- third bytes may have these bits on (they are not functioning
- as sync bits then!). There need to be two consequtive
- bytes with these bits off to re-sync. (This can be done
- if the user clicks buttons without moving the mouse?)
- */
- if (sc->inputbytes == 0) {
+ /*
+ * the table to turn PS/2 mouse button bits (MOUSE_PS2_BUTTON?DOWN)
+ * into `mouseinfo' button bits (BUT?STAT).
+ */
+ static butmap[8] = {
+ 0, BUT1STAT, BUT3STAT, BUT1STAT | BUT3STAT,
+ BUT2STAT, BUT1STAT | BUT2STAT, BUT2STAT | BUT3STAT,
+ BUT1STAT | BUT2STAT | BUT3STAT
+ };
+ register struct psm_softc *sc = &psm_softc[unit];
+ int ioport = sc->addr;
+ mousestatus_t *ms;
+ unsigned char c;
+ int x, y;
+
+ /* is this really for us? */
+ if ((inb(ioport + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
+ != KBDS_AUX_BUFFER_FULL)
+ return;
+
+ /* read a byte */
+ c = inb(ioport + KBD_DATA_PORT);
+
+ /* discard the byte if the device is not open */
+ if ((sc->state & PSM_OPEN) == 0)
+ return;
+
+ /*
+ * interpret data bytes FIXME: there seems no way to reliably
+ * re-synchronize with the PS/2 mouse once we are out of sync. Sure,
+ * there is sync bits in the first data byte, but the second and the
+ * third bytes may have these bits on (they are not functioning as
+ * sync bits then!). There need to be two consequtive bytes with these
+ * bits off to re-sync. (This can be done if the user clicks buttons
+ * without moving the mouse?)
+ */
+ if (sc->inputbytes == 0) {
#ifndef PSM_NOCHECKSYNC
- if ((c & MOUSE_PS2_SYNCMASK) == MOUSE_PS2_SYNC)
-#endif /* PSM_NOCHECKSYNC */
- sc->ipacket[sc->inputbytes++] = c;
- } else {
- sc->ipacket[sc->inputbytes++] = c;
- if (sc->inputbytes >= MOUSE_PS2_PACKETSIZE) {
- if (sc->queue.count >= PSM_BUFSIZE) {
- /* no room in the queue */
- sc->inputbytes = 0;
- return;
- }
- if (sc->mode.accelfactor >= 1) {
- x = (sc->ipacket[0] & MOUSE_PS2_XOVERFLOW) ?
- 128 : sc->ipacket[1];
- if (x != 0) {
- x = x*x/sc->mode.accelfactor;
- if (x == 0)
- x = 1;
- if (sc->ipacket[0] & MOUSE_PS2_XNEG)
- x = -x;
- }
- y = (sc->ipacket[0] & MOUSE_PS2_YOVERFLOW) ?
- 128 : sc->ipacket[2];
- if (y != 0) {
- y = y*y/sc->mode.accelfactor;
- if (y == 0)
- y = 1;
- if (sc->ipacket[0] & MOUSE_PS2_YNEG)
- y = -y;
- }
- } else { /* sc->mode.accelfactor <= 0 */
- x = (sc->ipacket[0] & MOUSE_PS2_XOVERFLOW) ?
- ((sc->ipacket[0] & MOUSE_PS2_XNEG) ?
- -128 : 127) : sc->ipacket[1];
- y = (sc->ipacket[0] & MOUSE_PS2_YOVERFLOW) ?
- ((sc->ipacket[0] & MOUSE_PS2_YNEG) ?
- -128 : 127) : sc->ipacket[2];
- }
-
- /* FIXME: we shouldn't store data if no movement
- and no button status change is detected? */
- ms = &sc->queue.buf[sc->queue.tail];
- ms->dx = x;
- ms->dy = y;
- ms->obutton = sc->button; /* previous button state */
- sc->button = ms->button = /* latest button state */
- butmap[sc->ipacket[0] & MOUSE_PS2_BUTTONS];
- sc->queue.tail =
- (sc->queue.tail + 1) % PSM_BUFSIZE;
- ++sc->queue.count;
- sc->inputbytes = 0;
- }
- }
-
- if (sc->state & PSM_ASLP) {
- sc->state &= ~PSM_ASLP;
- wakeup((caddr_t)sc);
- }
- selwakeup(&sc->rsel);
+ if ((c & MOUSE_PS2_SYNCMASK) == MOUSE_PS2_SYNC)
+#endif /* PSM_NOCHECKSYNC */
+ sc->ipacket[sc->inputbytes++] = c;
+ } else {
+ sc->ipacket[sc->inputbytes++] = c;
+ if (sc->inputbytes >= MOUSE_PS2_PACKETSIZE) {
+ if (sc->queue.count >= PSM_BUFSIZE) {
+ /* no room in the queue */
+ sc->inputbytes = 0;
+ return;
+ }
+ if (sc->mode.accelfactor >= 1) {
+ x = (sc->ipacket[0] & MOUSE_PS2_XOVERFLOW) ?
+ 128 : sc->ipacket[1];
+ if (x != 0) {
+ x = x * x / sc->mode.accelfactor;
+ if (x == 0)
+ x = 1;
+ if (sc->ipacket[0] & MOUSE_PS2_XNEG)
+ x = -x;
+ }
+ y = (sc->ipacket[0] & MOUSE_PS2_YOVERFLOW) ?
+ 128 : sc->ipacket[2];
+ if (y != 0) {
+ y = y * y / sc->mode.accelfactor;
+ if (y == 0)
+ y = 1;
+ if (sc->ipacket[0] & MOUSE_PS2_YNEG)
+ y = -y;
+ }
+ } else {/* sc->mode.accelfactor <= 0 */
+ x = (sc->ipacket[0] & MOUSE_PS2_XOVERFLOW) ?
+ ((sc->ipacket[0] & MOUSE_PS2_XNEG) ?
+ -128 : 127) : sc->ipacket[1];
+ y = (sc->ipacket[0] & MOUSE_PS2_YOVERFLOW) ?
+ ((sc->ipacket[0] & MOUSE_PS2_YNEG) ?
+ -128 : 127) : sc->ipacket[2];
+ }
+
+ /*
+ * FIXME:XXX
+ * we shouldn't store data if no movement and
+ * no button status change is detected?
+ */
+ ms = &sc->queue.buf[sc->queue.tail];
+ ms->dx = x;
+ ms->dy = y;
+ ms->obutton = sc->button; /* previous button state */
+ sc->button = ms->button = /* latest button state */
+ butmap[sc->ipacket[0] & MOUSE_PS2_BUTTONS];
+ sc->queue.tail =
+ (sc->queue.tail + 1) % PSM_BUFSIZE;
+ ++sc->queue.count;
+ sc->inputbytes = 0;
+ }
+ }
+
+ if (sc->state & PSM_ASLP) {
+ sc->state &= ~PSM_ASLP;
+ wakeup((caddr_t) sc);
+ }
+ selwakeup(&sc->rsel);
}
static int
psmselect(dev_t dev, int rw, struct proc *p)
{
- struct psm_softc *sc = &psm_softc[PSM_UNIT(dev)];
- int s, ret;
-
- /* Silly to select for output */
- if (rw == FWRITE)
- return (0);
-
- /* Return true if a mouse event available */
- s = spltty();
- if ((sc->outputbytes > 0) || (sc->queue.count > 0)) {
- ret = 1;
- } else {
- selrecord(p, &sc->rsel);
- ret = 0;
- }
- splx(s);
-
- return (ret);
+ struct psm_softc *sc = &psm_softc[PSM_UNIT(dev)];
+ int s, ret;
+
+ /* Silly to select for output */
+ if (rw == FWRITE)
+ return (0);
+
+ /* Return true if a mouse event available */
+ s = spltty();
+ if ((sc->outputbytes > 0) || (sc->queue.count > 0)) {
+ ret = 1;
+ } else {
+ selrecord(p, &sc->rsel);
+ ret = 0;
+ }
+ splx(s);
+
+ return (ret);
}
static int psm_devsw_installed = FALSE;
@@ -1171,15 +1196,15 @@ static int psm_devsw_installed = FALSE;
static void
psm_drvinit(void *unused)
{
- dev_t dev;
+ dev_t dev;
- if (!psm_devsw_installed) {
- dev = makedev(CDEV_MAJOR, 0);
- cdevsw_add(&dev,&psm_cdevsw, NULL);
- psm_devsw_installed = TRUE;
- }
+ if (!psm_devsw_installed) {
+ dev = makedev(CDEV_MAJOR, 0);
+ cdevsw_add(&dev, &psm_cdevsw, NULL);
+ psm_devsw_installed = TRUE;
+ }
}
-SYSINIT(psmdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE + CDEV_MAJOR,psm_drvinit,NULL)
+SYSINIT(psmdev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE + CDEV_MAJOR, psm_drvinit, NULL)
#endif /* NPSM > 0 */
OpenPOWER on IntegriCloud