Date: Sat, 11 Oct 2014 19:37:00 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r272956 - head/sys/dev/mse Message-ID: <201410111937.s9BJb0VC045249@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Sat Oct 11 19:36:59 2014 New Revision: 272956 URL: https://svnweb.freebsd.org/changeset/base/272956 Log: Add locking and mark MPSAFE. - Add a mutex to protect the softc. - Use callout(9) instead of timeout(9). - Consolidate duplicated detach routines into a bus-independent detach routine. - Add an extra sleep lock flag (MSESC_READING) to prevent other readers from reading while the first reader is copying data out of sc_bytes[] via uiomove(). - Use bus_*() instead of bus_space_*(). Tested by: nyan Modified: head/sys/dev/mse/mse.c head/sys/dev/mse/mse_cbus.c head/sys/dev/mse/mse_isa.c head/sys/dev/mse/msevar.h Modified: head/sys/dev/mse/mse.c ============================================================================== --- head/sys/dev/mse/mse.c Sat Oct 11 19:34:41 2014 (r272955) +++ head/sys/dev/mse/mse.c Sat Oct 11 19:36:59 2014 (r272956) @@ -99,7 +99,6 @@ static d_poll_t msepoll; static struct cdevsw mse_cdevsw = { .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, .d_open = mseopen, .d_close = mseclose, .d_read = mseread, @@ -109,9 +108,10 @@ static struct cdevsw mse_cdevsw = { }; static void mseintr(void *); -static timeout_t msetimeout; +static void mseintr_locked(mse_softc_t *sc); +static void msetimeout(void *); -#define MSE_NBLOCKIO(dev) dev2unit(dev) +#define MSE_NBLOCKIO(dev) (dev2unit(dev) != 0) #define MSEPRI (PZERO + 3) @@ -123,32 +123,68 @@ mse_common_attach(device_t dev) sc = device_get_softc(dev); unit = device_get_unit(dev); + mtx_init(&sc->sc_lock, "mse", NULL, MTX_DEF); + callout_init_mtx(&sc->sc_callout, &sc->sc_lock, 0); rid = 0; sc->sc_intr = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (sc->sc_intr == NULL) { bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port); + mtx_destroy(&sc->sc_lock); return ENXIO; } - if (bus_setup_intr(dev, sc->sc_intr, - INTR_TYPE_TTY, NULL, mseintr, sc, &sc->sc_ih)) { + if (bus_setup_intr(dev, sc->sc_intr, INTR_TYPE_TTY | INTR_MPSAFE, + NULL, mseintr, sc, &sc->sc_ih)) { bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port); bus_release_resource(dev, SYS_RES_IRQ, rid, sc->sc_intr); + mtx_destroy(&sc->sc_lock); return ENXIO; } flags = device_get_flags(dev); sc->mode.accelfactor = (flags & MSE_CONFIG_ACCEL) >> 4; - callout_handle_init(&sc->sc_callout); - sc->sc_dev = make_dev(&mse_cdevsw, 0, 0, 0, 0600, "mse%d", unit); + sc->sc_dev = make_dev(&mse_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, + "mse%d", unit); sc->sc_dev->si_drv1 = sc; - sc->sc_ndev = make_dev(&mse_cdevsw, 1, 0, 0, 0600, "nmse%d", unit); + sc->sc_ndev = make_dev(&mse_cdevsw, 1, UID_ROOT, GID_WHEEL, 0600, + "nmse%d", unit); sc->sc_ndev->si_drv1 = sc; return 0; } +int +mse_detach(device_t dev) +{ + mse_softc_t *sc; + int rid; + + sc = device_get_softc(dev); + MSE_LOCK(sc); + if (sc->sc_flags & MSESC_OPEN) { + MSE_UNLOCK(sc); + return EBUSY; + } + + /* Sabotage subsequent opens. */ + sc->sc_mousetype = MSE_NONE; + MSE_UNLOCK(sc); + + destroy_dev(sc->sc_dev); + destroy_dev(sc->sc_ndev); + + rid = 0; + bus_teardown_intr(dev, sc->sc_intr, sc->sc_ih); + bus_release_resource(dev, SYS_RES_IRQ, rid, sc->sc_intr); + bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port); + + callout_drain(&sc->sc_callout); + mtx_destroy(&sc->sc_lock); + + return 0; +} + /* * Exclusive open the mouse, initialize it and enable interrupts. */ @@ -156,18 +192,22 @@ static int mseopen(struct cdev *dev, int flags, int fmt, struct thread *td) { mse_softc_t *sc = dev->si_drv1; - int s; - if (sc->sc_mousetype == MSE_NONE) + MSE_LOCK(sc); + if (sc->sc_mousetype == MSE_NONE) { + MSE_UNLOCK(sc); return (ENXIO); - if (sc->sc_flags & MSESC_OPEN) + } + if (sc->sc_flags & MSESC_OPEN) { + MSE_UNLOCK(sc); return (EBUSY); + } sc->sc_flags |= MSESC_OPEN; sc->sc_obuttons = sc->sc_buttons = MOUSE_MSC_BUTTONS; sc->sc_deltax = sc->sc_deltay = 0; sc->sc_bytesread = sc->mode.packetsize = MOUSE_MSC_PACKETSIZE; sc->sc_watchdog = FALSE; - sc->sc_callout = timeout(msetimeout, dev, hz*2); + callout_reset(&sc->sc_callout, hz * 2, msetimeout, dev); sc->mode.level = 0; sc->status.flags = 0; sc->status.button = sc->status.obutton = 0; @@ -176,9 +216,8 @@ mseopen(struct cdev *dev, int flags, int /* * Initialize mouse interface and enable interrupts. */ - s = spltty(); - (*sc->sc_enablemouse)(sc->sc_iot, sc->sc_ioh); - splx(s); + (*sc->sc_enablemouse)(sc->sc_port); + MSE_UNLOCK(sc); return (0); } @@ -189,14 +228,12 @@ static int mseclose(struct cdev *dev, int flags, int fmt, struct thread *td) { mse_softc_t *sc = dev->si_drv1; - int s; - untimeout(msetimeout, dev, sc->sc_callout); - callout_handle_init(&sc->sc_callout); - s = spltty(); - (*sc->sc_disablemouse)(sc->sc_iot, sc->sc_ioh); + MSE_LOCK(sc); + callout_stop(&sc->sc_callout); + (*sc->sc_disablemouse)(sc->sc_port); sc->sc_flags &= ~MSESC_OPEN; - splx(s); + MSE_UNLOCK(sc); return(0); } @@ -209,27 +246,38 @@ static int mseread(struct cdev *dev, struct uio *uio, int ioflag) { mse_softc_t *sc = dev->si_drv1; - int xfer, s, error; + int xfer, error; /* * If there are no protocol bytes to be read, set up a new protocol * packet. */ - s = spltty(); /* XXX Should be its own spl, but where is imlXX() */ + MSE_LOCK(sc); + while (sc->sc_flags & MSESC_READING) { + if (MSE_NBLOCKIO(dev)) { + MSE_UNLOCK(sc); + return (0); + } + sc->sc_flags |= MSESC_WANT; + error = mtx_sleep(sc, &sc->sc_lock, MSEPRI | PCATCH, "mseread", + 0); + if (error) { + MSE_UNLOCK(sc); + return (error); + } + } + sc->sc_flags |= MSESC_READING; + xfer = 0; if (sc->sc_bytesread >= sc->mode.packetsize) { while (sc->sc_deltax == 0 && sc->sc_deltay == 0 && (sc->sc_obuttons ^ sc->sc_buttons) == 0) { - if (MSE_NBLOCKIO(dev)) { - splx(s); - return (0); - } + if (MSE_NBLOCKIO(dev)) + goto out; sc->sc_flags |= MSESC_WANT; - error = tsleep(sc, MSEPRI | PCATCH, + error = mtx_sleep(sc, &sc->sc_lock, MSEPRI | PCATCH, "mseread", 0); - if (error) { - splx(s); - return (error); - } + if (error) + goto out; } /* @@ -257,13 +305,21 @@ mseread(struct cdev *dev, struct uio *ui sc->sc_deltax = sc->sc_deltay = 0; sc->sc_bytesread = 0; } - splx(s); xfer = min(uio->uio_resid, sc->mode.packetsize - sc->sc_bytesread); + MSE_UNLOCK(sc); error = uiomove(&sc->sc_bytes[sc->sc_bytesread], xfer, uio); - if (error) - return (error); - sc->sc_bytesread += xfer; - return(0); + MSE_LOCK(sc); +out: + sc->sc_flags &= ~MSESC_READING; + if (error == 0) + sc->sc_bytesread += xfer; + if (sc->sc_flags & MSESC_WANT) { + sc->sc_flags &= ~MSESC_WANT; + MSE_UNLOCK(sc); + wakeup(sc); + } else + MSE_UNLOCK(sc); + return (error); } /* @@ -275,20 +331,19 @@ mseioctl(struct cdev *dev, u_long cmd, c mse_softc_t *sc = dev->si_drv1; mousestatus_t status; int err = 0; - int s; switch (cmd) { case MOUSE_GETHWINFO: - s = spltty(); + MSE_LOCK(sc); *(mousehw_t *)addr = sc->hw; if (sc->mode.level == 0) ((mousehw_t *)addr)->model = MOUSE_MODEL_GENERIC; - splx(s); + MSE_UNLOCK(sc); break; case MOUSE_GETMODE: - s = spltty(); + MSE_LOCK(sc); *(mousemode_t *)addr = sc->mode; switch (sc->mode.level) { case 0: @@ -299,7 +354,7 @@ mseioctl(struct cdev *dev, u_long cmd, c ((mousemode_t *)addr)->syncmask[1] = MOUSE_SYS_SYNC; break; } - splx(s); + MSE_UNLOCK(sc); break; case MOUSE_SETMODE: @@ -310,9 +365,11 @@ mseioctl(struct cdev *dev, u_long cmd, c default: return (EINVAL); } - if (((mousemode_t *)addr)->accelfactor < -1) + MSE_LOCK(sc); + if (((mousemode_t *)addr)->accelfactor < -1) { + MSE_UNLOCK(sc); return (EINVAL); - else if (((mousemode_t *)addr)->accelfactor >= 0) + } else if (((mousemode_t *)addr)->accelfactor >= 0) sc->mode.accelfactor = ((mousemode_t *)addr)->accelfactor; sc->mode.level = ((mousemode_t *)addr)->level; @@ -326,23 +383,30 @@ mseioctl(struct cdev *dev, u_long cmd, c = MOUSE_SYS_PACKETSIZE; break; } + MSE_UNLOCK(sc); break; case MOUSE_GETLEVEL: + MSE_LOCK(sc); *(int *)addr = sc->mode.level; + MSE_UNLOCK(sc); break; case MOUSE_SETLEVEL: switch (*(int *)addr) { case 0: + MSE_LOCK(sc); sc->mode.level = *(int *)addr; sc->sc_bytesread = sc->mode.packetsize = MOUSE_MSC_PACKETSIZE; + MSE_UNLOCK(sc); break; case 1: + MSE_LOCK(sc); sc->mode.level = *(int *)addr; sc->sc_bytesread = sc->mode.packetsize = MOUSE_SYS_PACKETSIZE; + MSE_UNLOCK(sc); break; default: return (EINVAL); @@ -350,7 +414,7 @@ mseioctl(struct cdev *dev, u_long cmd, c break; case MOUSE_GETSTATUS: - s = spltty(); + MSE_LOCK(sc); status = sc->status; sc->status.flags = 0; sc->status.obutton = sc->status.button; @@ -358,7 +422,7 @@ mseioctl(struct cdev *dev, u_long cmd, c sc->status.dx = 0; sc->status.dy = 0; sc->status.dz = 0; - splx(s); + MSE_UNLOCK(sc); *(mousestatus_t *)addr = status; break; @@ -385,24 +449,18 @@ static int msepoll(struct cdev *dev, int events, struct thread *td) { mse_softc_t *sc = dev->si_drv1; - int s; int revents = 0; - s = spltty(); + MSE_LOCK(sc); if (events & (POLLIN | POLLRDNORM)) { if (sc->sc_bytesread != sc->mode.packetsize || sc->sc_deltax != 0 || sc->sc_deltay != 0 || (sc->sc_obuttons ^ sc->sc_buttons) != 0) revents |= events & (POLLIN | POLLRDNORM); - else { - /* - * Since this is an exclusive open device, any previous - * proc pointer is trash now, so we can just assign it. - */ + else selrecord(td, &sc->sc_selp); - } } - splx(s); + MSE_UNLOCK(sc); return (revents); } @@ -417,13 +475,14 @@ msetimeout(void *arg) dev = (struct cdev *)arg; sc = dev->si_drv1; + MSE_ASSERT_LOCKED(sc); if (sc->sc_watchdog) { if (bootverbose) printf("%s: lost interrupt?\n", devtoname(dev)); - mseintr(sc); + mseintr_locked(sc); } sc->sc_watchdog = TRUE; - sc->sc_callout = timeout(msetimeout, dev, hz); + callout_schedule(&sc->sc_callout, hz); } /* @@ -432,6 +491,16 @@ msetimeout(void *arg) static void mseintr(void *arg) { + mse_softc_t *sc = arg; + + MSE_LOCK(sc); + mseintr_locked(sc); + MSE_UNLOCK(sc); +} + +static void +mseintr_locked(mse_softc_t *sc) +{ /* * the table to turn MouseSystem button bits (MOUSE_MSC_BUTTON?UP) * into `mousestatus' button bits (MOUSE_BUTTON?DOWN). @@ -446,7 +515,6 @@ mseintr(void *arg) MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN, MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN }; - mse_softc_t *sc = arg; int dx, dy, but; int sign; @@ -458,7 +526,7 @@ mseintr(void *arg) if ((sc->sc_flags & MSESC_OPEN) == 0) return; - (*sc->sc_getmouse)(sc->sc_iot, sc->sc_ioh, &dx, &dy, &but); + (*sc->sc_getmouse)(sc->sc_port, &dx, &dy, &but); if (sc->mode.accelfactor > 0) { sign = (dx < 0); dx = dx * dx / sc->mode.accelfactor; Modified: head/sys/dev/mse/mse_cbus.c ============================================================================== --- head/sys/dev/mse/mse_cbus.c Sat Oct 11 19:34:41 2014 (r272955) +++ head/sys/dev/mse/mse_cbus.c Sat Oct 11 19:36:59 2014 (r272956) @@ -91,12 +91,11 @@ static int mse_cbus_probe(device_t dev); static int mse_cbus_attach(device_t dev); -static int mse_cbus_detach(device_t dev); static device_method_t mse_methods[] = { DEVMETHOD(device_probe, mse_cbus_probe), DEVMETHOD(device_attach, mse_cbus_attach), - DEVMETHOD(device_detach, mse_cbus_detach), + DEVMETHOD(device_detach, mse_detach), { 0, 0 } }; @@ -136,10 +135,10 @@ static struct isa_pnp_id mse_ids[] = { static bus_addr_t mse_port[] = {0, 2, 4, 6}; static int mse_probe98m(device_t dev, mse_softc_t *sc); -static void mse_disable98m(bus_space_tag_t t, bus_space_handle_t h); -static void mse_get98m(bus_space_tag_t t, bus_space_handle_t h, +static void mse_disable98m(struct resource *port); +static void mse_get98m(struct resource *port, int *dx, int *dy, int *but); -static void mse_enable98m(bus_space_tag_t t, bus_space_handle_t h); +static void mse_enable98m(struct resource *port); static struct mse_types mse_types[] = { { MSE_98BUSMOUSE, @@ -173,8 +172,6 @@ mse_cbus_probe(device_t dev) bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port); return ENXIO; } - sc->sc_iot = rman_get_bustag(sc->sc_port); - sc->sc_ioh = rman_get_bushandle(sc->sc_port); /* * Check for each mouse type in the table. @@ -216,33 +213,10 @@ mse_cbus_attach(device_t dev) bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port); return ENXIO; } - sc->sc_iot = rman_get_bustag(sc->sc_port); - sc->sc_ioh = rman_get_bushandle(sc->sc_port); return (mse_common_attach(dev)); } -static int -mse_cbus_detach(device_t dev) -{ - mse_softc_t *sc; - int rid; - - sc = device_get_softc(dev); - if (sc->sc_flags & MSESC_OPEN) - return EBUSY; - - rid = 0; - BUS_TEARDOWN_INTR(device_get_parent(dev), dev, sc->sc_intr, sc->sc_ih); - bus_release_resource(dev, SYS_RES_IRQ, rid, sc->sc_intr); - bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port); - - destroy_dev(sc->sc_dev); - destroy_dev(sc->sc_ndev); - - return 0; -} - /* * Routines for the PC98 bus mouse. */ @@ -255,15 +229,15 @@ static int mse_probe98m(device_t dev, mse_softc_t *sc) { /* mode set */ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, MODE, 0x93); + bus_write_1(sc->sc_port, MODE, 0x93); /* initialize */ /* INT disable */ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, INT, INT_DISABLE); + bus_write_1(sc->sc_port, INT, INT_DISABLE); /* HC = 0 */ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, HC, HC_NO_CLEAR); + bus_write_1(sc->sc_port, HC, HC_NO_CLEAR); /* HC = 1 */ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, HC, HC_CLEAR); + bus_write_1(sc->sc_port, HC, HC_CLEAR); return (1); } @@ -272,57 +246,56 @@ mse_probe98m(device_t dev, mse_softc_t * * Initialize PC98 bus mouse and enable interrupts. */ static void -mse_enable98m(bus_space_tag_t tag, bus_space_handle_t handle) +mse_enable98m(struct resource *port) { - bus_space_write_1(tag, handle, INT, INT_ENABLE); /* INT enable */ - bus_space_write_1(tag, handle, HC, HC_NO_CLEAR); /* HC = 0 */ - bus_space_write_1(tag, handle, HC, HC_CLEAR); /* HC = 1 */ + bus_write_1(port, INT, INT_ENABLE); /* INT enable */ + bus_write_1(port, HC, HC_NO_CLEAR); /* HC = 0 */ + bus_write_1(port, HC, HC_CLEAR); /* HC = 1 */ } /* * Disable interrupts for PC98 Bus mouse. */ static void -mse_disable98m(bus_space_tag_t tag, bus_space_handle_t handle) +mse_disable98m(struct resource *port) { - bus_space_write_1(tag, handle, INT, INT_DISABLE); /* INT disable */ - bus_space_write_1(tag, handle, HC, HC_NO_CLEAR); /* HC = 0 */ - bus_space_write_1(tag, handle, HC, HC_CLEAR); /* HC = 1 */ + bus_write_1(port, INT, INT_DISABLE); /* INT disable */ + bus_write_1(port, HC, HC_NO_CLEAR); /* HC = 0 */ + bus_write_1(port, HC, HC_CLEAR); /* HC = 1 */ } /* * Get current dx, dy and up/down button state. */ static void -mse_get98m(bus_space_tag_t tag, bus_space_handle_t handle, int *dx, int *dy, - int *but) +mse_get98m(struct resource *port, int *dx, int *dy, int *but) { register char x, y; - bus_space_write_1(tag, handle, INT, INT_DISABLE); /* INT disable */ + bus_write_1(port, INT, INT_DISABLE); /* INT disable */ - bus_space_write_1(tag, handle, HC, HC_CLEAR); /* HC = 1 */ + bus_write_1(port, HC, HC_CLEAR); /* HC = 1 */ /* X low */ - bus_space_write_1(tag, handle, MSE_PORTC, 0x90 | XL); - x = bus_space_read_1(tag, handle, MSE_PORTA) & 0x0f; + bus_write_1(port, MSE_PORTC, 0x90 | XL); + x = bus_read_1(port, MSE_PORTA) & 0x0f; /* X high */ - bus_space_write_1(tag, handle, MSE_PORTC, 0x90 | XH); - x |= ((bus_space_read_1(tag, handle, MSE_PORTA) & 0x0f) << 4); + bus_write_1(port, MSE_PORTC, 0x90 | XH); + x |= ((bus_read_1(port, MSE_PORTA) & 0x0f) << 4); /* Y low */ - bus_space_write_1(tag, handle, MSE_PORTC, 0x90 | YL); - y = (bus_space_read_1(tag, handle, MSE_PORTA) & 0x0f); + bus_write_1(port, MSE_PORTC, 0x90 | YL); + y = (bus_read_1(port, MSE_PORTA) & 0x0f); /* Y high */ - bus_space_write_1(tag, handle, MSE_PORTC, 0x90 | YH); - y |= ((bus_space_read_1(tag, handle, MSE_PORTA) & 0x0f) << 4); + bus_write_1(port, MSE_PORTC, 0x90 | YH); + y |= ((bus_read_1(port, MSE_PORTA) & 0x0f) << 4); - *but = (bus_space_read_1(tag, handle, MSE_PORTA) >> 5) & 7; + *but = (bus_read_1(port, MSE_PORTA) >> 5) & 7; *dx = x; *dy = y; - bus_space_write_1(tag, handle, HC, HC_NO_CLEAR); /* HC = 0 */ + bus_write_1(port, HC, HC_NO_CLEAR); /* HC = 0 */ - bus_space_write_1(tag, handle, INT, INT_ENABLE); /* INT enable */ + bus_write_1(port, INT, INT_ENABLE); /* INT enable */ } Modified: head/sys/dev/mse/mse_isa.c ============================================================================== --- head/sys/dev/mse/mse_isa.c Sat Oct 11 19:34:41 2014 (r272955) +++ head/sys/dev/mse/mse_isa.c Sat Oct 11 19:36:59 2014 (r272956) @@ -91,12 +91,11 @@ static int mse_isa_probe(device_t dev); static int mse_isa_attach(device_t dev); -static int mse_isa_detach(device_t dev); static device_method_t mse_methods[] = { DEVMETHOD(device_probe, mse_isa_probe), DEVMETHOD(device_attach, mse_isa_attach), - DEVMETHOD(device_detach, mse_isa_detach), + DEVMETHOD(device_detach, mse_detach), { 0, 0 } }; @@ -156,12 +155,10 @@ static struct isa_pnp_id mse_ids[] = { #define MSE_INTREN 0x00 static int mse_probelogi(device_t dev, mse_softc_t *sc); -static void mse_disablelogi(bus_space_tag_t t, - bus_space_handle_t h); -static void mse_getlogi(bus_space_tag_t t, bus_space_handle_t h, - int *dx, int *dy, int *but); -static void mse_enablelogi(bus_space_tag_t t, - bus_space_handle_t h); +static void mse_disablelogi(struct resource *port); +static void mse_getlogi(struct resource *port, int *dx, int *dy, + int *but); +static void mse_enablelogi(struct resource *port); /* * ATI Inport mouse definitions @@ -175,10 +172,10 @@ static void mse_enablelogi(bus_space_ta #define MSE_INPORT_INTREN 0x09 static int mse_probeati(device_t dev, mse_softc_t *sc); -static void mse_enableati(bus_space_tag_t t, bus_space_handle_t h); -static void mse_disableati(bus_space_tag_t t, bus_space_handle_t h); -static void mse_getati(bus_space_tag_t t, bus_space_handle_t h, - int *dx, int *dy, int *but); +static void mse_enableati(struct resource *port); +static void mse_disableati(struct resource *port); +static void mse_getati(struct resource *port, int *dx, int *dy, + int *but); static struct mse_types mse_types[] = { { MSE_ATIINPORT, @@ -213,8 +210,6 @@ mse_isa_probe(device_t dev) MSE_IOSIZE, RF_ACTIVE); if (sc->sc_port == NULL) return ENXIO; - sc->sc_iot = rman_get_bustag(sc->sc_port); - sc->sc_ioh = rman_get_bushandle(sc->sc_port); /* * Check for each mouse type in the table. @@ -252,33 +247,10 @@ mse_isa_attach(device_t dev) MSE_IOSIZE, RF_ACTIVE); if (sc->sc_port == NULL) return ENXIO; - sc->sc_iot = rman_get_bustag(sc->sc_port); - sc->sc_ioh = rman_get_bushandle(sc->sc_port); return (mse_common_attach(dev)); } -static int -mse_isa_detach(device_t dev) -{ - mse_softc_t *sc; - int rid; - - sc = device_get_softc(dev); - if (sc->sc_flags & MSESC_OPEN) - return EBUSY; - - rid = 0; - BUS_TEARDOWN_INTR(device_get_parent(dev), dev, sc->sc_intr, sc->sc_ih); - bus_release_resource(dev, SYS_RES_IRQ, rid, sc->sc_intr); - bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->sc_port); - - destroy_dev(sc->sc_dev); - destroy_dev(sc->sc_ndev); - - return 0; -} - /* * Routines for the Logitech mouse. */ @@ -293,15 +265,14 @@ mse_probelogi(device_t dev, mse_softc_t int sig; - bus_space_write_1(sc->sc_iot, sc->sc_ioh, MSE_PORTD, MSE_SETUP); + bus_write_1(sc->sc_port, MSE_PORTD, MSE_SETUP); /* set the signature port */ - bus_space_write_1(sc->sc_iot, sc->sc_ioh, MSE_PORTB, MSE_LOGI_SIG); + bus_write_1(sc->sc_port, MSE_PORTB, MSE_LOGI_SIG); DELAY(30000); /* 30 ms delay */ - sig = bus_space_read_1(sc->sc_iot, sc->sc_ioh, MSE_PORTB) & 0xFF; + sig = bus_read_1(sc->sc_port, MSE_PORTB) & 0xFF; if (sig == MSE_LOGI_SIG) { - bus_space_write_1(sc->sc_iot, sc->sc_ioh, MSE_PORTC, - MSE_DISINTR); + bus_write_1(sc->sc_port, MSE_PORTC, MSE_DISINTR); return(1); } else { if (bootverbose) @@ -314,46 +285,45 @@ mse_probelogi(device_t dev, mse_softc_t * Initialize Logitech mouse and enable interrupts. */ static void -mse_enablelogi(bus_space_tag_t tag, bus_space_handle_t handle) +mse_enablelogi(struct resource *port) { int dx, dy, but; - bus_space_write_1(tag, handle, MSE_PORTD, MSE_SETUP); - mse_getlogi(tag, handle, &dx, &dy, &but); + bus_write_1(port, MSE_PORTD, MSE_SETUP); + mse_getlogi(port, &dx, &dy, &but); } /* * Disable interrupts for Logitech mouse. */ static void -mse_disablelogi(bus_space_tag_t tag, bus_space_handle_t handle) +mse_disablelogi(struct resource *port) { - bus_space_write_1(tag, handle, MSE_PORTC, MSE_DISINTR); + bus_write_1(port, MSE_PORTC, MSE_DISINTR); } /* * Get the current dx, dy and button up/down state. */ static void -mse_getlogi(bus_space_tag_t tag, bus_space_handle_t handle, int *dx, int *dy, - int *but) +mse_getlogi(struct resource *port, int *dx, int *dy, int *but) { register char x, y; - bus_space_write_1(tag, handle, MSE_PORTC, MSE_HOLD | MSE_RXLOW); - x = bus_space_read_1(tag, handle, MSE_PORTA); + bus_write_1(port, MSE_PORTC, MSE_HOLD | MSE_RXLOW); + x = bus_read_1(port, MSE_PORTA); *but = (x >> 5) & MOUSE_MSC_BUTTONS; x &= 0xf; - bus_space_write_1(tag, handle, MSE_PORTC, MSE_HOLD | MSE_RXHIGH); - x |= (bus_space_read_1(tag, handle, MSE_PORTA) << 4); - bus_space_write_1(tag, handle, MSE_PORTC, MSE_HOLD | MSE_RYLOW); - y = (bus_space_read_1(tag, handle, MSE_PORTA) & 0xf); - bus_space_write_1(tag, handle, MSE_PORTC, MSE_HOLD | MSE_RYHIGH); - y |= (bus_space_read_1(tag, handle, MSE_PORTA) << 4); + bus_write_1(port, MSE_PORTC, MSE_HOLD | MSE_RXHIGH); + x |= (bus_read_1(port, MSE_PORTA) << 4); + bus_write_1(port, MSE_PORTC, MSE_HOLD | MSE_RYLOW); + y = (bus_read_1(port, MSE_PORTA) & 0xf); + bus_write_1(port, MSE_PORTC, MSE_HOLD | MSE_RYHIGH); + y |= (bus_read_1(port, MSE_PORTA) << 4); *dx = x; *dy = y; - bus_space_write_1(tag, handle, MSE_PORTC, MSE_INTREN); + bus_write_1(port, MSE_PORTC, MSE_INTREN); } /* @@ -369,7 +339,7 @@ mse_probeati(device_t dev, mse_softc_t * int i; for (i = 0; i < 2; i++) - if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, MSE_PORTC) == 0xde) + if (bus_read_1(sc->sc_port, MSE_PORTC) == 0xde) return (1); return (0); } @@ -378,44 +348,43 @@ mse_probeati(device_t dev, mse_softc_t * * Initialize ATI Inport mouse and enable interrupts. */ static void -mse_enableati(bus_space_tag_t tag, bus_space_handle_t handle) +mse_enableati(struct resource *port) { - bus_space_write_1(tag, handle, MSE_PORTA, MSE_INPORT_RESET); - bus_space_write_1(tag, handle, MSE_PORTA, MSE_INPORT_MODE); - bus_space_write_1(tag, handle, MSE_PORTB, MSE_INPORT_INTREN); + bus_write_1(port, MSE_PORTA, MSE_INPORT_RESET); + bus_write_1(port, MSE_PORTA, MSE_INPORT_MODE); + bus_write_1(port, MSE_PORTB, MSE_INPORT_INTREN); } /* * Disable interrupts for ATI Inport mouse. */ static void -mse_disableati(bus_space_tag_t tag, bus_space_handle_t handle) +mse_disableati(struct resource *port) { - bus_space_write_1(tag, handle, MSE_PORTA, MSE_INPORT_MODE); - bus_space_write_1(tag, handle, MSE_PORTB, 0); + bus_write_1(port, MSE_PORTA, MSE_INPORT_MODE); + bus_write_1(port, MSE_PORTB, 0); } /* * Get current dx, dy and up/down button state. */ static void -mse_getati(bus_space_tag_t tag, bus_space_handle_t handle, int *dx, int *dy, - int *but) +mse_getati(struct resource *port, int *dx, int *dy, int *but) { char byte; - bus_space_write_1(tag, handle, MSE_PORTA, MSE_INPORT_MODE); - bus_space_write_1(tag, handle, MSE_PORTB, MSE_INPORT_HOLD); - bus_space_write_1(tag, handle, MSE_PORTA, MSE_INPORT_STATUS); - *but = ~bus_space_read_1(tag, handle, MSE_PORTB) & MOUSE_MSC_BUTTONS; - bus_space_write_1(tag, handle, MSE_PORTA, MSE_INPORT_DX); - byte = bus_space_read_1(tag, handle, MSE_PORTB); + bus_write_1(port, MSE_PORTA, MSE_INPORT_MODE); + bus_write_1(port, MSE_PORTB, MSE_INPORT_HOLD); + bus_write_1(port, MSE_PORTA, MSE_INPORT_STATUS); + *but = ~bus_read_1(port, MSE_PORTB) & MOUSE_MSC_BUTTONS; + bus_write_1(port, MSE_PORTA, MSE_INPORT_DX); + byte = bus_read_1(port, MSE_PORTB); *dx = byte; - bus_space_write_1(tag, handle, MSE_PORTA, MSE_INPORT_DY); - byte = bus_space_read_1(tag, handle, MSE_PORTB); + bus_write_1(port, MSE_PORTA, MSE_INPORT_DY); + byte = bus_read_1(port, MSE_PORTB); *dy = byte; - bus_space_write_1(tag, handle, MSE_PORTA, MSE_INPORT_MODE); - bus_space_write_1(tag, handle, MSE_PORTB, MSE_INPORT_INTREN); + bus_write_1(port, MSE_PORTA, MSE_INPORT_MODE); + bus_write_1(port, MSE_PORTB, MSE_INPORT_INTREN); } Modified: head/sys/dev/mse/msevar.h ============================================================================== --- head/sys/dev/mse/msevar.h Sat Oct 11 19:34:41 2014 (r272955) +++ head/sys/dev/mse/msevar.h Sat Oct 11 19:36:59 2014 (r272956) @@ -46,7 +46,7 @@ /* * Software control structure for mouse. The sc_enablemouse(), - * sc_disablemouse() and sc_getmouse() routines must be called spl'd(). + * sc_disablemouse() and sc_getmouse() routines must be called locked. */ typedef struct mse_softc { int sc_flags; @@ -54,22 +54,19 @@ typedef struct mse_softc { struct selinfo sc_selp; struct resource *sc_port; struct resource *sc_intr; - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; void *sc_ih; - void (*sc_enablemouse)(bus_space_tag_t t, - bus_space_handle_t h); - void (*sc_disablemouse)(bus_space_tag_t t, - bus_space_handle_t h); - void (*sc_getmouse)(bus_space_tag_t t, bus_space_handle_t h, - int *dx, int *dy, int *but); + void (*sc_enablemouse)(struct resource *port); + void (*sc_disablemouse)(struct resource *port); + void (*sc_getmouse)(struct resource *port, int *dx, int *dy, + int *but); int sc_deltax; int sc_deltay; int sc_obuttons; int sc_buttons; int sc_bytesread; u_char sc_bytes[MOUSE_SYS_PACKETSIZE]; - struct callout_handle sc_callout; + struct callout sc_callout; + struct mtx sc_lock; int sc_watchdog; struct cdev *sc_dev; struct cdev *sc_ndev; @@ -78,9 +75,14 @@ typedef struct mse_softc { mousestatus_t status; } mse_softc_t; +#define MSE_LOCK(sc) mtx_lock(&(sc)->sc_lock) +#define MSE_UNLOCK(sc) mtx_unlock(&(sc)->sc_lock) +#define MSE_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_lock, MA_OWNED) + /* Flags */ #define MSESC_OPEN 0x1 #define MSESC_WANT 0x2 +#define MSESC_READING 0x4 /* and Mouse Types */ #define MSE_NONE 0 /* don't move this! */ @@ -110,12 +112,11 @@ struct mse_types { int m_type; /* Type of bus mouse */ int (*m_probe)(device_t dev, mse_softc_t *sc); /* Probe routine to test for it */ - void (*m_enable)(bus_space_tag_t t, bus_space_handle_t h); + void (*m_enable)(struct resource *port); /* Start routine */ - void (*m_disable)(bus_space_tag_t t, bus_space_handle_t h); + void (*m_disable)(struct resource *port); /* Disable interrupts routine */ - void (*m_get)(bus_space_tag_t t, bus_space_handle_t h, int *dx, - int *dy, int *but); + void (*m_get)(struct resource *port, int *dx, int *dy, int *but); /* and get mouse status */ mousehw_t m_hw; /* buttons iftype type model hwid */ mousemode_t m_mode; /* proto rate res accel level size mask */ @@ -123,3 +124,4 @@ struct mse_types { extern devclass_t mse_devclass; int mse_common_attach(device_t); +int mse_detach(device_t);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201410111937.s9BJb0VC045249>