1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-24 11:29:10 +00:00

- Add write(2) support for psm(4) in native operation level. Now arbitrary

commands can be written to /dev/psm%d and status can be read back from it.
- Reflect the change in psm(4) and bump version for ports.

MFC after:	1 week
This commit is contained in:
Jung-uk Kim 2008-04-08 17:55:26 +00:00
parent 00c71fb7c3
commit ff0af72c39
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=178017
4 changed files with 65 additions and 10 deletions

View File

@ -22,6 +22,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW:
to maximize performance. (To disable malloc debugging, run
ln -s aj /etc/malloc.conf.)
20080408:
psm(4) has gained write(2) support in native operation level.
Arbitrary commands can be written to /dev/psm%d and status can
be read back from it. Therefore, an application is responsible
for status validation and error recovery. It is a no-op in
other operation levels.
20080312:
Support for KSE threading has been removed from the kernel. To
run legacy applications linked against KSE libmap.conf may

View File

@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd September 29, 2004
.Dd April 8, 2008
.Dt PSM 4
.Os
.Sh NAME
@ -110,7 +110,9 @@ The movement of the roller is reported as movement along the Z axis.
8 byte data packets are sent to the user program at this level.
.Pp
At the operation level two, data from the pointing device is passed to the
user program as is.
user program as is. Conversely, command from the user program is passed
to the pointing device as is and the user program is responsible for
status validation and error recovery.
Modern PS/2 type pointing devices often use proprietary data format.
Therefore, the user program is expected to have
intimate knowledge about the format from a particular device when operating

View File

@ -290,6 +290,7 @@ static int psmresume(device_t);
static d_open_t psmopen;
static d_close_t psmclose;
static d_read_t psmread;
static d_write_t psmwrite;
static d_ioctl_t psmioctl;
static d_poll_t psmpoll;
@ -397,6 +398,7 @@ static struct cdevsw psm_cdevsw = {
.d_open = psmopen,
.d_close = psmclose,
.d_read = psmread,
.d_write = psmwrite,
.d_ioctl = psmioctl,
.d_poll = psmpoll,
.d_name = PSM_DRIVER_NAME,
@ -1710,6 +1712,37 @@ unblock_mouse_data(struct psm_softc *sc, int c)
return error;
}
static int
psmwrite(struct cdev *dev, struct uio *uio, int flag)
{
register struct psm_softc *sc = PSM_SOFTC(PSM_UNIT(dev));
u_char buf[PSM_SMALLBUFSIZE];
int error = 0, i, l;
if ((sc->state & PSM_VALID) == 0)
return (EIO);
if (sc->mode.level < PSM_LEVEL_NATIVE)
return (ENODEV);
/* copy data from the user land */
while (uio->uio_resid > 0) {
l = imin(PSM_SMALLBUFSIZE, uio->uio_resid);
error = uiomove(buf, l, uio);
if (error)
break;
for (i = 0; i < l; i++) {
VLOG(4, (LOG_DEBUG, "psm: cmd 0x%x\n", buf[i]));
if (!write_aux_command(sc->kbdc, buf[i])) {
VLOG(2, (LOG_DEBUG, "psm: cmd 0x%x failed.\n", buf[i]));
return (reinitialize(sc, FALSE));
}
}
}
return (error);
}
static int
psmioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
{
@ -2092,12 +2125,20 @@ psmintr(void *arg)
timevaladd(&sc->inputtimeout, &now);
pb->ipacket[pb->inputbytes++] = c;
if (pb->inputbytes < sc->mode.packetsize)
continue;
VLOG(4, (LOG_DEBUG, "psmintr: %02x %02x %02x %02x %02x %02x\n",
pb->ipacket[0], pb->ipacket[1], pb->ipacket[2],
pb->ipacket[3], pb->ipacket[4], pb->ipacket[5]));
if (sc->mode.level == PSM_LEVEL_NATIVE) {
VLOG(4, (LOG_DEBUG, "psmintr: %02x\n", pb->ipacket[0]));
sc->syncerrors = 0;
sc->pkterrors = 0;
goto NEXT;
} else {
if (pb->inputbytes < sc->mode.packetsize)
continue;
VLOG(4, (LOG_DEBUG, "psmintr: %02x %02x %02x %02x %02x %02x\n",
pb->ipacket[0], pb->ipacket[1], pb->ipacket[2],
pb->ipacket[3], pb->ipacket[4], pb->ipacket[5]));
}
c = pb->ipacket[0];
@ -2180,6 +2221,7 @@ psmintr(void *arg)
sc->pkterrors = 0;
sc->cmdcount++;
NEXT:
if (++sc->pqueue_end >= PSM_PACKETQUEUE)
sc->pqueue_end = 0;
/*
@ -2246,6 +2288,10 @@ psmsoftintr(void *arg)
do {
pb = &sc->pqueue[sc->pqueue_start];
if (sc->mode.level == PSM_LEVEL_NATIVE)
goto NEXT_NATIVE;
c = pb->ipacket[0];
/*
* A kludge for Kensington device!
@ -2806,8 +2852,7 @@ psmsoftintr(void *arg)
ms.flags = ((x || y || z) ? MOUSE_POSCHANGED : 0)
| (ms.obutton ^ ms.button);
if (sc->mode.level < PSM_LEVEL_NATIVE)
pb->inputbytes = tame_mouse(sc, pb, &ms, pb->ipacket);
pb->inputbytes = tame_mouse(sc, pb, &ms, pb->ipacket);
sc->status.flags |= ms.flags;
sc->status.dx += ms.dx;
@ -2816,6 +2861,7 @@ psmsoftintr(void *arg)
sc->status.button = ms.button;
sc->button = ms.button;
NEXT_NATIVE:
sc->watchdog = FALSE;
/* queue data */

View File

@ -57,7 +57,7 @@
* is created, otherwise 1.
*/
#undef __FreeBSD_version
#define __FreeBSD_version 800032 /* Master, propagated to newvers */
#define __FreeBSD_version 800033 /* Master, propagated to newvers */
#ifndef LOCORE
#include <sys/types.h>