*BSD News Article 6671


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