Looks and works fine for me, ok nicm
Cheers
On Tue, Nov 30, 2010 at 09:33:41PM +0500, Alexandr Shadchin wrote:
> On Mon, Nov 29, 2010 at 10:08:22PM +0000, Nicholas Marriott wrote:
> >
> > Well, I don't use it so I don't have strong feelings about it, but it
> > does work for PS/2 mice and it seems that it would be useful for anyone
> > using wsmoused (although there probably aren't many people).
> >
> > Would it be so hard to leave it, and if it is really not needed remove
> > it entirely as a separate change?
> >
> > Otherwise aside from the char -> signed char change I mentioned the diff
> > is fine with me.
> >
>
> 1) fix char -> signed char
> 2) Returned WSMOUSEIO_SRES
>
> --
> Alexandr Shadchin
>
> Index: pms.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pckbc/pms.c,v
> retrieving revision 1.14
> diff -u -p -r1.14 pms.c
> --- pms.c 15 Nov 2010 20:25:31 -0000 1.14
> +++ pms.c 30 Nov 2010 16:26:20 -0000
> @@ -40,6 +40,20 @@
>
> #define DEVNAME(sc) ((sc)->sc_dev.dv_xname)
>
> +struct pms_softc;
> +
> +struct pms_protocol {
> + int type;
> +#define PMS_STANDARD 0
> +#define PMS_INTELLI 1
> + int packetsize;
> + int (*enable)(struct pms_softc *);
> + int (*ioctl)(struct pms_softc *, u_long, caddr_t, int, struct proc *);
> + int (*sync)(struct pms_softc *, int);
> + void (*proc)(struct pms_softc *);
> + void (*disable)(struct pms_softc *);
> +};
> +
> struct pms_softc { /* driver status information */
> struct device sc_dev;
>
> @@ -52,14 +66,38 @@ struct pms_softc { /* driver status inf
> #define PMS_STATE_SUSPENDED 2
>
> int poll;
> - int intelli;
> int inputstate;
> - u_int buttons, oldbuttons; /* mouse button status */
> - signed char dx, dy;
> +
> + struct pms_protocol protocol;
> +
> + unsigned char packet[8];
>
> struct device *sc_wsmousedev;
> };
>
> +#define PMS_BUTTON1DOWN 0x0001 /* left */
> +#define PMS_BUTTON2DOWN 0x0002 /* middle */
> +#define PMS_BUTTON3DOWN 0x0004 /* right */
> +
> +static const u_int butmap[8] = {
> + 0,
> + PMS_BUTTON1DOWN,
> + PMS_BUTTON3DOWN,
> + PMS_BUTTON1DOWN | PMS_BUTTON3DOWN,
> + PMS_BUTTON2DOWN,
> + PMS_BUTTON1DOWN | PMS_BUTTON2DOWN,
> + PMS_BUTTON2DOWN | PMS_BUTTON3DOWN,
> + PMS_BUTTON1DOWN | PMS_BUTTON2DOWN | PMS_BUTTON3DOWN
> +};
> +
> +/* PS/2 mouse data packet */
> +#define PMS_PS2_BUTTONSMASK 0x07
> +#define PMS_PS2_BUTTON1 0x01 /* left */
> +#define PMS_PS2_BUTTON2 0x04 /* middle */
> +#define PMS_PS2_BUTTON3 0x02 /* right */
> +#define PMS_PS2_XNEG 0x10
> +#define PMS_PS2_YNEG 0x20
> +
> int pmsprobe(struct device *, void *, void *);
> void pmsattach(struct device *, struct device *, void *);
> int pmsactivate(struct device *, int);
> @@ -81,7 +119,11 @@ int pms_reset(struct pms_softc *);
> int pms_dev_enable(struct pms_softc *);
> int pms_dev_disable(struct pms_softc *);
>
> -int pms_setintellimode(struct pms_softc *sc);
> +int pms_enable_intelli(struct pms_softc *);
> +
> +int pms_ioctl_mouse(struct pms_softc *, u_long, caddr_t, int, struct proc
> *);
> +int pms_sync_mouse(struct pms_softc *, int);
> +void pms_proc_mouse(struct pms_softc *);
>
> struct cfattach pms_ca = {
> sizeof(struct pms_softc), pmsprobe, pmsattach, NULL,
> @@ -98,6 +140,27 @@ const struct wsmouse_accessops pms_acces
> pms_disable,
> };
>
> +const struct pms_protocol pms_mouse[] = {
> + /* Generic PS/2 mouse */
> + {
> + PMS_STANDARD, 3,
> + NULL,
> + pms_ioctl_mouse,
> + pms_sync_mouse,
> + pms_proc_mouse,
> + NULL
> + },
> + /* Microsoft IntelliMouse */
> + {
> + PMS_INTELLI, 4,
> + pms_enable_intelli,
> + pms_ioctl_mouse,
> + pms_sync_mouse,
> + pms_proc_mouse,
> + NULL
> + }
> +};
> +
> int
> pms_cmd(struct pms_softc *sc, u_char *cmd, int len, u_char *resp, int
> resplen)
> {
> @@ -208,7 +271,7 @@ pms_dev_disable(struct pms_softc *sc)
> }
>
> int
> -pms_setintellimode(struct pms_softc *sc)
> +pms_enable_intelli(struct pms_softc *sc)
> {
> static const int rates[] = {200, 100, 80};
> u_char resp;
> @@ -224,6 +287,78 @@ pms_setintellimode(struct pms_softc *sc)
> }
>
> int
> +pms_ioctl_mouse(struct pms_softc *sc, u_long cmd, caddr_t data, int flag,
> + struct proc *p)
> +{
> + int i;
> +
> + switch (cmd) {
> + case WSMOUSEIO_GTYPE:
> + *(u_int *)data = WSMOUSE_TYPE_PS2;
> + break;
> + case WSMOUSEIO_SRES:
> + i = ((int) *(u_int *)data - 12) / 25;
> + /* valid values are {0,1,2,3} */
> + if (i < 0)
> + i = 0;
> + if (i > 3)
> + i = 3;
> +
> + if (pms_set_resolution(sc, i))
> + printf("%s: SET_RES command error\n", DEVNAME(sc));
> + break;
> + default:
> + return (-1);
> + }
> + return (0);
> +}
> +
> +int
> +pms_sync_mouse(struct pms_softc *sc, int data)
> +{
> + if (sc->inputstate != 0)
> + return (0);
> +
> + switch (sc->protocol.type) {
> + case PMS_STANDARD:
> + if ((data & 0xc0) != 0)
> + return (-1);
> + break;
> + case PMS_INTELLI:
> + if ((data & 0x08) != 0x08)
> + return (-1);
> + break;
> + }
> +
> + return (0);
> +}
> +
> +void
> +pms_proc_mouse(struct pms_softc *sc)
> +{
> + u_int buttons;
> + int dx, dy, dz;
> +
> + buttons = butmap[sc->packet[0] & PMS_PS2_BUTTONSMASK];
> + dx = (sc->packet[0] & PMS_PS2_XNEG) ?
> + sc->packet[1] - 256 : sc->packet[1];
> + dy = (sc->packet[0] & PMS_PS2_YNEG) ?
> + sc->packet[2] - 256 : sc->packet[2];
> +
> + switch (sc->protocol.type) {
> + case PMS_STANDARD:
> + dz = 0;
> + break;
> + case PMS_INTELLI:
> + dz = (signed char)sc->packet[3];
> + break;
> + }
> +
> + wsmouse_input(sc->sc_wsmousedev,
> + buttons, dx, dy, dz, 0, WSMOUSE_INPUT_DELTA);
> +}
> +
> +int
> pmsprobe(struct device *parent, void *match, void *aux)
> {
> struct pckbc_attach_args *pa = aux;
> @@ -302,13 +437,14 @@ pmsactivate(struct device *self, int act
> int
> pms_change_state(struct pms_softc *sc, int newstate)
> {
> + int i;
> +
> switch (newstate) {
> case PMS_STATE_ENABLED:
> if (sc->sc_state == PMS_STATE_ENABLED)
> return (EBUSY);
>
> sc->inputstate = 0;
> - sc->oldbuttons = 0;
>
> pckbc_slot_enable(sc->sc_kbctag, sc->sc_kbcslot, 1);
>
> @@ -317,13 +453,24 @@ pms_change_state(struct pms_softc *sc, i
>
> pms_reset(sc);
>
> - sc->intelli = pms_setintellimode(sc);
> + sc->protocol = pms_mouse[0];
> + for (i = 1; i < nitems(pms_mouse); i++)
> + if (pms_mouse[i].enable(sc))
> + sc->protocol = pms_mouse[i];
> +
> +#ifdef DEBUG
> + printf("%s: protocol type %d\n", DEVNAME(sc),
> sc->protocol.type);
> +#endif
>
> pms_dev_enable(sc);
> break;
> case PMS_STATE_DISABLED:
> case PMS_STATE_SUSPENDED:
> pms_dev_disable(sc);
> +
> + if (sc->protocol.disable)
> + sc->protocol.disable(sc);
> +
> pckbc_slot_enable(sc->sc_kbctag, sc->sc_kbcslot, 0);
> break;
> }
> @@ -354,96 +501,30 @@ int
> pms_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
> {
> struct pms_softc *sc = v;
> - u_char kbcmd[2];
> - int i;
>
> - switch (cmd) {
> - case WSMOUSEIO_GTYPE:
> - *(u_int *)data = WSMOUSE_TYPE_PS2;
> - break;
> -
> - case WSMOUSEIO_SRES:
> - i = ((int) *(u_int *)data - 12) / 25;
> - /* valid values are {0,1,2,3} */
> - if (i < 0)
> - i = 0;
> - if (i > 3)
> - i = 3;
> -
> - kbcmd[0] = PMS_SET_RES;
> - kbcmd[1] = (unsigned char) i;
> - i = pckbc_enqueue_cmd(sc->sc_kbctag, sc->sc_kbcslot, kbcmd,
> - 2, 0, 1, 0);
> -
> - if (i)
> - printf("pms_ioctl: SET_RES command error\n");
> - break;
> -
> - default:
> - return (-1);
> - }
> - return (0);
> + return (sc->protocol.ioctl(sc, cmd, data, flag, p));
> }
>
> -/* Masks for the first byte of a packet */
> -#define PS2LBUTMASK 0x01
> -#define PS2RBUTMASK 0x02
> -#define PS2MBUTMASK 0x04
> -
> void
> pmsinput(void *vsc, int data)
> {
> struct pms_softc *sc = vsc;
> - signed char dz = 0;
> - u_int changed;
>
> if (sc->sc_state != PMS_STATE_ENABLED) {
> /* Interrupts are not expected. Discard the byte. */
> return;
> }
>
> - switch (sc->inputstate) {
> -
> - case 0:
> - if ((data & 0xc0) == 0) { /* no ovfl, bit 3 == 1 too? */
> - sc->buttons = ((data & PS2LBUTMASK) ? 0x1 : 0) |
> - ((data & PS2MBUTMASK) ? 0x2 : 0) |
> - ((data & PS2RBUTMASK) ? 0x4 : 0);
> - ++sc->inputstate;
> - }
> - break;
> -
> - case 1:
> - sc->dx = data;
> - /* Bounding at -127 avoids a bug in XFree86. */
> - sc->dx = (sc->dx == -128) ? -127 : sc->dx;
> - ++sc->inputstate;
> - break;
> -
> - case 2:
> - sc->dy = data;
> - sc->dy = (sc->dy == -128) ? -127 : sc->dy;
> - ++sc->inputstate;
> - break;
> -
> - case 3:
> - dz = data;
> - dz = (dz == -128) ? -127 : dz;
> - ++sc->inputstate;
> - break;
> - }
> -
> - if ((sc->inputstate == 3 && sc->intelli == 0) || sc->inputstate == 4) {
> + if (sc->protocol.sync(sc, data)) {
> + printf("%s: not in sync yet, discard input\n", DEVNAME(sc));
> sc->inputstate = 0;
> -
> - changed = (sc->buttons ^ sc->oldbuttons);
> - sc->oldbuttons = sc->buttons;
> -
> - if (sc->dx || sc->dy || dz || changed)
> - wsmouse_input(sc->sc_wsmousedev,
> - sc->buttons, sc->dx, sc->dy, dz, 0,
> - WSMOUSE_INPUT_DELTA);
> + return;
> }
>
> - return;
> + sc->packet[sc->inputstate++] = data;
> + if (sc->inputstate != sc->protocol.packetsize)
> + return;
> +
> + sc->protocol.proc(sc);
> + sc->inputstate = 0;
> }