Return to BSD News archive
Path: sserve!manuel.anu.edu.au!munnari.oz.au!spool.mu.edu!sdd.hp.com!zaphod.mps.ohio-state.edu!rpi!usenet.coe.montana.edu!news.u.washington.edu!ogicse!psgrain!hippo!shrike.und.ac.za!casper.cs.uct.ac.za!uctcs!sandi
From: sandi@uctcs.cs.uct.ac.za (Sandi Donno)
Newsgroups: comp.unix.bsd
Subject: [386bsd] A working Microsoft bus mouse driver
Message-ID: <sandi.719335445@uctcs>
Date: 17 Oct 92 15:24:05 GMT
Article-I.D.: uctcs.sandi.719335445
Sender: news@casper.cs.uct.ac.za (news)
Organization: Computer Science Department, University of Cape Town
Lines: 526
Dear 386bsd'ers,
Need a Microsoft bus mouse driver for X386 under 386bsd?
Here are my patches to Erik Forsberg's bus mouse driver for BSD/386
to make it work under 386bsd.
Sandi Donno
P.S. Now that I have a working mouse driver, I have discovered that X is
unbearably slow on my 16MHz 386SX with 4MB - not that I didn't
expect this :-(. As I result, I have not been able to fully test this
driver. Any feedback on performance etc. would thus be appreciated.
----------------------------------------------------------------------------
# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# README.386bsd
# bms.c.diff
# conf.c.diff
# files.i386.diff
#
echo x - README.386bsd
sed 's/^X//' >README.386bsd << 'END-of-README.386bsd'
XThese patches, when applied to the Microsoft busmouse driver for BSD/386
Xby Erik Forsberg (busmouse.v3), result in a port of this driver to 386bsd.
XI have not ported the Logitech driver included in this package.
X
XThe patched bms.c should be placed in /sys/sys/i386/isa
XThe unchanged mouse.h should be placed in /sys/sys
XThe unchanged isa.h.diff patch should be applied to /sys/i386/isa/isa.h
X
XThe following patches REPLACE the patches supplied with busmouse.v3:
XThe conf.c.diff patch should be applied to /sys/i386/i386/conf.c
XThe files.i386.diff patch should be applied to /sys/i386/conf/files.i386
X
XThe following is an example of a suitable line to add in your
Xkernel configuration file:
X
Xdevice bms0 at isa? port "IO_BMS1" tty irq 5 vector bmsintr
X
XThe testmse program from the 386bsd busmouse package by Rick Macklem,
Xrick@snowhite.cis.uoguelph.ca, is useful for testing the mouse in
Xblocking mode. To use this program, first mknod /dev/mouse c 14 0.
X
XIf this works, then
X1) rm /dev/mouse
X2) mknod /dev/mouse c 14 1
Xto create a non-blocking device suitable for use with X386.
X
Xbusmouse.v3 can be obtained from physics.su.oz.au, in /XFree86
X386bsd-busmouse.tar.Z can be obtained from athene.uni-paderborn.de,
Xin /uninstalled/386BSD/386bsd-0.1/unofficial
X
X -- Sandi Donno (sandi@cs.uct.ac.za)
X
END-of-README.386bsd
echo x - bms.c.diff
sed 's/^X//' >bms.c.diff << 'END-of-bms.c.diff'
X*** bms.c.orig Sat Oct 17 15:00:04 1992
X--- bms.c Sat Oct 17 16:56:01 1992
X***************
X*** 41,46 ****
X--- 41,59 ----
X * Copyright 1992, Erik Forsberg.
X */
X
X+ /*
X+ * Ported to 386bsd Oct 17, 1992
X+ * Sandi Donno, Computer Science, University of Cape Town, South Africa
X+ * Please send bug reports to sandi@cs.uct.ac.za
X+ *
X+ * Thanks are also due to Rick Macklem, rick@snowhite.cis.uoguelph.ca -
X+ * although I was only partially successful in getting the alpha release
X+ * of his "driver for the Logitech and ATI Inport Bus mice for use with
X+ * 386bsd and the X386 port" to work with my Microsoft mouse, I nevertheless
X+ * found his code to be an invaluable reference when porting this driver
X+ * to 386bsd.
X+ */
X+
X #include "bms.h"
X
X #if NBMS > 0
X***************
X*** 49,55 ****
X #include "kernel.h"
X #include "systm.h"
X #include "buf.h"
X- #include "device.h"
X #include "malloc.h"
X #include "ioctl.h"
X #include "tty.h"
X--- 62,67 ----
X***************
X*** 64,84 ****
X #define DATA 1 /* Offset for InPort data */
X #define IDENT 2 /* Offset for identification register */
X
X! #define BMSUNIT(dev) (minor(dev) & 1)
X
X! extern int bmsprobe __P((struct isa_device *));
X! extern int bmsattach __P((struct isa_device *));
X! extern int bmsopen __P((int, int, int, struct proc *));
X! extern int bmsclose __P((int, int, int, struct proc *));
X! extern int bmsread __P((int, struct uio *, int));
X! extern int bmsioctl __P((int, int, caddr_t, int, struct proc *));
X! extern int bmsselect __P((int, int));
X! extern void bmsintr __P((int));
X
X static int bmsaddr[NBMS]; /* Base I/O port addresses per unit */
X
X static struct bms_softc { /* Driver status information */
X! struct clist inq; /* Input queue */
X struct proc *rsel; /* Process selecting for Input */
X unsigned char state; /* Mouse driver state */
X unsigned char status; /* Mouse button status */
X--- 76,97 ----
X #define DATA 1 /* Offset for InPort data */
X #define IDENT 2 /* Offset for identification register */
X
X! #define BMSUNIT(dev) (minor(dev) >> 1)
X
X! int bmsprobe();
X! int bmsattach();
X
X static int bmsaddr[NBMS]; /* Base I/O port addresses per unit */
X
X+ #define MSBSZ 1020 /* Output queue size (multiple of 5 please) */
X+
X+ struct ringbuf {
X+ int count, first, last;
X+ char queue[MSBSZ];
X+ };
X+
X static struct bms_softc { /* Driver status information */
X! struct ringbuf inq; /* Input queue */
X struct proc *rsel; /* Process selecting for Input */
X unsigned char state; /* Mouse driver state */
X unsigned char status; /* Mouse button status */
X***************
X*** 85,92 ****
X int x, y; /* accumulated motion in the X,Y axis */
X } bms_softc[NBMS];
X
X- #define MSBSZ 1020 /* Output queue size (multiple of 5 please) */
X-
X #define OPEN 1 /* Device is open */
X #define ASLP 2 /* Waiting for mouse data */
X
X--- 98,103 ----
X***************
X*** 129,138 ****
X return(0);
X }
X
X! int bmsopen(dev, flag, fmt, p)
X dev_t dev;
X! int flag, fmt;
X! struct proc *p;
X {
X int unit = BMSUNIT(dev);
X struct bms_softc *sc;
X--- 140,148 ----
X return(0);
X }
X
X! int bmsopen(dev, flag)
X dev_t dev;
X! int flag;
X {
X int unit = BMSUNIT(dev);
X struct bms_softc *sc;
X***************
X*** 166,180 ****
X sc->x = 0;
X sc->y = 0;
X
X! /* Allocate and initialize a clist buffer */
X
X! sc->inq.c_cc = 0;
X! sc->inq.c_cf = sc->inq.c_cl = NULL;
X! sc->inq.c_cq = (char *) malloc(MSBSZ, M_CLIST, M_WAITOK);
X! sc->inq.c_ct = (char *) malloc(MSBSZ/NBBY, M_CLIST, M_WAITOK);
X! bzero(sc->inq.c_ct, MSBSZ/NBBY);
X! sc->inq.c_ce = (char *) (sc->inq.c_cq + MSBSZ - 1);
X! sc->inq.c_cs = MSBSZ;
X
X /* Setup Bus Mouse */
X
X--- 176,184 ----
X sc->x = 0;
X sc->y = 0;
X
X! /* Allocate and initialize a ring buffer */
X
X! sc->inq.count = sc->inq.first = sc->inq.last = 0;
X
X /* Setup Bus Mouse */
X
X***************
X*** 186,195 ****
X return(0);
X }
X
X! int bmsclose(dev, flag, fmt, p)
X dev_t dev;
X! int flag, fmt;
X! struct proc *p;
X {
X int unit, ioport;
X struct bms_softc *sc;
X--- 190,198 ----
X return(0);
X }
X
X! int bmsclose(dev, flag)
X dev_t dev;
X! int flag;
X {
X int unit, ioport;
X struct bms_softc *sc;
X***************
X*** 208,227 ****
X
X sc->state &= ~OPEN;
X
X- /* Release memory held by clist buffer */
X-
X- free(sc->inq.c_cq, M_CLIST);
X- free(sc->inq.c_ct, M_CLIST);
X-
X /* close is almost always successful */
X
X return(0);
X }
X
X! int bmsread(dev, uio, flag)
X dev_t dev;
X struct uio *uio;
X- int flag;
X {
X int s, error;
X unsigned length;
X--- 211,224 ----
X
X sc->state &= ~OPEN;
X
X /* close is almost always successful */
X
X return(0);
X }
X
X! int bmsread(dev, uio)
X dev_t dev;
X struct uio *uio;
X {
X int s, error;
X unsigned length;
X***************
X*** 235,243 ****
X /* Block until mouse activity occured */
X
X s = spltty();
X! while (sc->inq.c_cc == 0)
X {
X! if (flag & IO_NDELAY)
X {
X splx(s);
X return(EWOULDBLOCK);
X--- 232,240 ----
X /* Block until mouse activity occured */
X
X s = spltty();
X! while (sc->inq.count == 0)
X {
X! if (minor(dev) & 0x1)
X {
X splx(s);
X return(EWOULDBLOCK);
X***************
X*** 253,267 ****
X
X /* Transfer as many chunks as possible */
X
X! while (sc->inq.c_cc > 0 && uio->uio_resid > 0)
X {
X! length = min(sc->inq.c_cc, uio->uio_resid);
X if (length > sizeof(buffer))
X length = sizeof(buffer);
X
X /* Remove a small chunk from input queue */
X
X! (void) q_to_b(&sc->inq, buffer, length);
X
X /* Copy data to user process */
X
X--- 250,276 ----
X
X /* Transfer as many chunks as possible */
X
X! while (sc->inq.count > 0 && uio->uio_resid > 0)
X {
X! length = min(sc->inq.count, uio->uio_resid);
X if (length > sizeof(buffer))
X length = sizeof(buffer);
X
X /* Remove a small chunk from input queue */
X
X! if (sc->inq.first + length >= MSBSZ)
X! {
X! bcopy(&sc->inq.queue[sc->inq.first],
X! buffer, MSBSZ - sc->inq.first);
X! bcopy(sc->inq.queue, &buffer[MSBSZ-sc->inq.first],
X! length - (MSBSZ - sc->inq.first));
X! }
X! else
X! bcopy(&sc->inq.queue[sc->inq.first], buffer, length);
X!
X! sc->inq.first = (sc->inq.first + length) % MSBSZ;
X! sc->inq.count -= length;
X!
X
X /* Copy data to user process */
X
X***************
X*** 270,275 ****
X--- 279,286 ----
X break;
X }
X
X+ sc->x = sc->y = 0;
X+
X /* Allow interrupts again */
X
X splx(s);
X***************
X*** 276,286 ****
X return(error);
X }
X
X! int bmsioctl(dev, cmd, addr, flag, p)
X dev_t dev;
X caddr_t addr;
X int cmd, flag;
X- struct proc *p;
X {
X struct bms_softc *sc;
X struct mouseinfo info;
X--- 287,296 ----
X return(error);
X }
X
X! int bmsioctl(dev, cmd, addr, flag)
X dev_t dev;
X caddr_t addr;
X int cmd, flag;
X {
X struct bms_softc *sc;
X struct mouseinfo info;
X***************
X*** 350,356 ****
X {
X struct bms_softc *sc = &bms_softc[unit];
X int ioport = bmsaddr[unit];
X- char buffer[5];
X char x, y, sts;
X
X /* Freeze InPort registers */
X--- 360,365 ----
X***************
X*** 399,413 ****
X
X /* If device in use and any change occurred ... */
X
X! if (sc->state & OPEN && sts & 0x78)
X {
X sts &= BUTSTATMASK;
X! buffer[0] = 0x80 | (sts ^ BUTSTATMASK);
X! buffer[1] = x;
X! buffer[2] = y;
X! buffer[3] = 0;
X! buffer[4] = 0;
X! (void) b_to_q(buffer, 5, &sc->inq);
X if (sc->state & ASLP)
X {
X sc->state &= ~ASLP;
X--- 408,424 ----
X
X /* If device in use and any change occurred ... */
X
X! if (sc->state & OPEN && sts & 0x78 && sc->inq.count < MSBSZ)
X {
X sts &= BUTSTATMASK;
X! sc->inq.queue[sc->inq.last++] = 0x80 | (sts ^ BUTSTATMASK);
X! sc->inq.queue[sc->inq.last++ % MSBSZ] = x;
X! sc->inq.queue[sc->inq.last++ % MSBSZ] = y;
X! sc->inq.queue[sc->inq.last++ % MSBSZ] = 0;
X! sc->inq.queue[sc->inq.last++ % MSBSZ] = 0;
X! sc->inq.last = sc->inq.last % MSBSZ;
X! sc->inq.count +=5;
X!
X if (sc->state & ASLP)
X {
X sc->state &= ~ASLP;
X***************
X*** 421,429 ****
X }
X }
X
X! int bmsselect(dev, rw)
X dev_t dev;
X int rw;
X {
X int s, ret;
X struct bms_softc *sc = &bms_softc[BMSUNIT(dev)];
X--- 432,441 ----
X }
X }
X
X! int bmsselect(dev, rw, p)
X dev_t dev;
X int rw;
X+ struct proc *p;
X {
X int s, ret;
X struct bms_softc *sc = &bms_softc[BMSUNIT(dev)];
X***************
X*** 436,447 ****
X /* Return true if a mouse event available */
X
X s = spltty();
X! if (sc->inq.c_cc != 0)
X ret = 1;
X else
X {
X ret = 0;
X! sc->rsel = curproc;
X }
X
X splx(s);
X--- 448,459 ----
X /* Return true if a mouse event available */
X
X s = spltty();
X! if (sc->inq.count != 0)
X ret = 1;
X else
X {
X ret = 0;
X! sc->rsel = p;
X }
X
X splx(s);
END-of-bms.c.diff
echo x - conf.c.diff
sed 's/^X//' >conf.c.diff << 'END-of-conf.c.diff'
X*** conf.c.orig Sat Oct 17 15:30:58 1992
X--- conf.c Sat Oct 17 15:34:45 1992
X***************
X*** 165,175 ****
X #define com_tty NULL
X #endif
X
X int logopen(),logclose(),logread(),logioctl(),logselect();
X
X int ttselect(), seltrue();
X
X-
X struct cdevsw cdevsw[] =
X {
X { cnopen, cnclose, cnread, cnwrite, /*0*/
X--- 165,185 ----
X #define com_tty NULL
X #endif
X
X+ #include "bms.h"
X+ #if NBMS > 0
X+ int bmsopen(),bmsclose(),bmsread(),bmsselect(),bmsioctl();
X+ #else
X+ #define bmsopen enxio
X+ #define bmsclose enxio
X+ #define bmsread enxio
X+ #define bmsselect enxio
X+ #define bmsioctl enxio
X+ #endif
X+
X int logopen(),logclose(),logread(),logioctl(),logselect();
X
X int ttselect(), seltrue();
X
X struct cdevsw cdevsw[] =
X {
X { cnopen, cnclose, cnread, cnwrite, /*0*/
X***************
X*** 214,219 ****
X--- 224,232 ----
X { asopen, asclose, rawread, rawwrite, /*D*/
X asioctl, enodev, nullop, NULL,
X seltrue, enodev, asstrategy },
X+ { bmsopen, bmsclose, bmsread, nullop, /*E*/
X+ bmsioctl, enodev, nullop, NULL,
X+ bmsselect, enodev, NULL },
X };
X int nchrdev = sizeof (cdevsw) / sizeof (cdevsw[0]);
END-of-conf.c.diff
echo x - files.i386.diff
sed 's/^X//' >files.i386.diff << 'END-of-files.i386.diff'
X*** files.i386.orig Sat Oct 17 15:40:39 1992
X--- files.i386 Sat Oct 17 15:40:57 1992
X***************
X*** 21,26 ****
X--- 21,27 ----
X i386/isa/isa.c optional isa device-driver
X i386/isa/com.c optional com device-driver
X i386/isa/npx.c optional npx device-driver
X+ i386/isa/bms.c optional bms device-driver
X i386/isa/as.c optional as device-driver
X i386/i386/db_disasm.c optional ddb
X i386/i386/db_interface.c optional ddb
END-of-files.i386.diff
exit