Subject: port-i386/5130: PS/2 mouse isn't
To: None <gnats-bugs@gnats.netbsd.org>
From: Lennart Augustsson <augustss@cs.chalmers.se>
List: netbsd-bugs
Date: 03/07/1998 20:16:37
>Number:         5130
>Category:       port-i386
>Synopsis:       PS/2 mouse isn't
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Mar  7 11:20:01 1998
>Last-Modified:
>Originator:     Lennart Augustsson
>Organization:
Chalmers University
>Release:        NetBSD-current 980306
>Environment:
System: NetBSD dogbert.cs.chalmers.se 1.3E NetBSD 1.3E (DOGBERT) #2: Thu Mar 5 16:46:04 CET 1998 augustss@dogbert.cs.chalmers.se:/usr/src/sys/arch/i386/compile/DOGBERT i386


>Description:
	Why does our PS/2 mouse driver emulate BusMouse?
	It's counter-intuitive and it also precludes using more
	modern mice such as the IntelliMouse that looks like
	a PS/2 mouse initially, but can be programmed to do
	other things.
	I suggest that we change the PS/2 driver so that it supports
	the "native" PS/2 protocol as well as writes to the mouse
	device so it can be reprogrammed.
	To maintain backwards compatibility we may want to do what
	my patch below does, namely use the minor device number
	to determine if we should be BusMouse or PS/2 compatible.

>How-To-Repeat:
	Nothing to repeat really...

>Fix:
	This patch make the pms driver use the native protocol if
	minor >= 128 and it also implements write() in native mode.
	I've been using this with no problem with an IntelliMouse
	(the one with a little wheel) for some time now.

*** /calvin/sys/arch/i386/isa/pms.c	Wed Feb 11 20:51:57 1998
--- /sys/arch/i386/isa/pms.c	Fri Feb 13 14:34:00 1998
***************
*** 99,104 ****
--- 99,105 ----
  #define	PMS_ASLP	0x02	/* waiting for mouse data */
  	u_char sc_status;	/* mouse button status */
  	int sc_x, sc_y;		/* accumulated motion in the X,Y axis */
+ 	u_char sc_native;	/* return native events */
  };
  
  int pmsprobe __P((struct device *, void *, void *));
***************
*** 111,117 ****
  
  extern struct cfdriver pms_cd;
  
! #define	PMSUNIT(dev)	(minor(dev))
  
  static __inline int pms_wait_output __P((void));
  static __inline int pms_wait_input __P((void));
--- 112,119 ----
  
  extern struct cfdriver pms_cd;
  
! #define	PMSUNIT(dev)	(minor(dev) & 0x7f)
! #define	PMSNATIVE(dev)	(minor(dev) & 0x80)
  
  static __inline int pms_wait_output __P((void));
  static __inline int pms_wait_input __P((void));
***************
*** 296,301 ****
--- 298,304 ----
  	sc->sc_state |= PMS_OPEN;
  	sc->sc_status = 0;
  	sc->sc_x = sc->sc_y = 0;
+ 	sc->sc_native = PMSNATIVE(dev);
  
  	/* Enable interrupts. */
  	pms_aux_cmd(PMS_AUX_ENABLE);
***************
*** 388,393 ****
--- 391,425 ----
  }
  
  int
+ pmswrite(dev, uio, flag)
+ 	dev_t dev;
+ 	struct uio *uio;
+ 	int flag;
+ {
+ 	struct pms_softc *sc = pms_cd.cd_devs[PMSUNIT(dev)];
+ 	int i, n;
+ 	int error;
+ 	int s;
+ 	u_char wrbuf[32];
+ 
+ 	if (!sc->sc_native)
+ 		return ENODEV;
+ 
+ 	error = 0;
+ 	/* Only allow a small number of bytes per write. */
+ 	n = min(sizeof(wrbuf), uio->uio_resid);
+ 	error = uiomove(wrbuf, n, uio);
+ 	if (error)
+ 		return error;
+ 	s = spltty();
+ 	for(i = 0; i < n; i++)
+ 		pms_dev_cmd(wrbuf[i]);
+ 	splx(s);
+ 
+ 	return error;
+ }
+ 
+ int
  pmsioctl(dev, cmd, addr, flag, p)
  	dev_t dev;
  	u_long cmd;
***************
*** 402,407 ****
--- 434,441 ----
  
  	switch (cmd) {
  	case MOUSEIOCREAD:
+ 		if (sc->sc_native)
+ 			return EINVAL;
  		s = spltty();
  
  		info.status = sc->sc_status;
***************
*** 431,437 ****
  		splx(s);
  		error = copyout(&info, addr, sizeof(struct mouseinfo));
  		break;
- 
  	default:
  		error = EINVAL;
  		break;
--- 465,470 ----
***************
*** 461,466 ****
--- 494,511 ----
  		/* Interrupts are not expected.  Discard the byte. */
  		pms_flush_input();
  		return 0;
+ 	}
+ 
+ 	if (sc->sc_native) {
+ 		buffer[0] = inb(PMS_DATA);
+ 		(void) b_to_q(buffer, 1, &sc->sc_q);
+ 
+ 		if (sc->sc_state & PMS_ASLP) {
+ 			sc->sc_state &= ~PMS_ASLP;
+ 			wakeup((caddr_t)sc);
+ 		}
+ 		selwakeup(&sc->sc_rsel);
+ 		return -1;
  	}
  
  	switch (state) {
*** /calvin/sys/arch/i386/i386/conf.c	Mon Oct 13 14:23:32 1997
--- /sys/arch/i386/i386/conf.c	Thu Feb 12 17:45:25 1998
***************
*** 124,129 ****
--- 124,136 ----
  	(dev_type_stop((*))) enodev, 0, dev_init(c,n,poll), \
  	(dev_type_mmap((*))) enodev }
  
+ /* open, close, read, write, ioctl, poll */
+ #define	cdev_mousewr_init(c,n) { \
+ 	dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
+ 	dev_init(c,n,write), dev_init(c,n,ioctl), \
+ 	(dev_type_stop((*))) enodev, 0, dev_init(c,n,poll), \
+ 	(dev_type_mmap((*))) enodev }
+ 
  cdev_decl(cn);
  cdev_decl(ctty);
  #define	mmread	mmrw
***************
*** 230,236 ****
  	cdev_lkm_dummy(),		/* 34 */
  	cdev_mouse_init(NMMS,mms),	/* 35: Microsoft mouse */
  	cdev_mouse_init(NLMS,lms),	/* 36: Logitech mouse */
! 	cdev_mouse_init(NPMS,pms),	/* 37: PS/2 mouse */
  	cdev_tty_init(NCY,cy),		/* 38: Cyclom serial port */
  	cdev_disk_init(NMCD,mcd),	/* 39: Mitsumi CD-ROM */
  	cdev_bpftun_init(NTUN,tun),	/* 40: network tunnel */
--- 237,243 ----
  	cdev_lkm_dummy(),		/* 34 */
  	cdev_mouse_init(NMMS,mms),	/* 35: Microsoft mouse */
  	cdev_mouse_init(NLMS,lms),	/* 36: Logitech mouse */
! 	cdev_mousewr_init(NPMS,pms),	/* 37: PS/2 mouse */
  	cdev_tty_init(NCY,cy),		/* 38: Cyclom serial port */
  	cdev_disk_init(NMCD,mcd),	/* 39: Mitsumi CD-ROM */
  	cdev_bpftun_init(NTUN,tun),	/* 40: network tunnel */
>Audit-Trail:
>Unformatted: