ensure the device's UVM pager object is present before using uvm_pageratop
This commit is contained in:
parent
677a1b79fa
commit
aacc46c31c
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: ssdfb.c,v 1.2 2019/03/17 01:33:02 tnn Exp $ */
|
/* $NetBSD: ssdfb.c,v 1.3 2019/03/17 04:03:17 tnn Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 The NetBSD Foundation, Inc.
|
* Copyright (c) 2019 The NetBSD Foundation, Inc.
|
||||||
|
@ -30,13 +30,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: ssdfb.c,v 1.2 2019/03/17 01:33:02 tnn Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: ssdfb.c,v 1.3 2019/03/17 04:03:17 tnn Exp $");
|
||||||
|
|
||||||
#include "opt_ddb.h"
|
#include "opt_ddb.h"
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
|
#include <sys/conf.h>
|
||||||
#include <uvm/uvm_page.h>
|
#include <uvm/uvm_page.h>
|
||||||
|
#include <uvm/uvm_device.h>
|
||||||
#include <sys/condvar.h>
|
#include <sys/condvar.h>
|
||||||
#include <sys/kmem.h>
|
#include <sys/kmem.h>
|
||||||
#include <sys/kthread.h>
|
#include <sys/kthread.h>
|
||||||
|
@ -75,6 +77,7 @@ static int ssdfb_set_display_on(struct ssdfb_softc *, bool, bool);
|
||||||
static int ssdfb_set_mode(struct ssdfb_softc *, u_int);
|
static int ssdfb_set_mode(struct ssdfb_softc *, u_int);
|
||||||
|
|
||||||
/* frame buffer damage tracking and synchronization */
|
/* frame buffer damage tracking and synchronization */
|
||||||
|
static void ssdfb_udv_attach(struct ssdfb_softc *sc);
|
||||||
static bool ssdfb_is_modified(struct ssdfb_softc *sc);
|
static bool ssdfb_is_modified(struct ssdfb_softc *sc);
|
||||||
static bool ssdfb_clear_modify(struct ssdfb_softc *sc);
|
static bool ssdfb_clear_modify(struct ssdfb_softc *sc);
|
||||||
static void ssdfb_damage(struct ssdfb_softc *);
|
static void ssdfb_damage(struct ssdfb_softc *);
|
||||||
|
@ -189,7 +192,6 @@ static const struct wsdisplay_accessops ssdfb_accessops = {
|
||||||
|
|
||||||
#define SSDFB_CMD1(c) do { cmd[0] = (c); error = sc->sc_cmd(sc->sc_cookie, cmd, 1, usepoll); } while(0)
|
#define SSDFB_CMD1(c) do { cmd[0] = (c); error = sc->sc_cmd(sc->sc_cookie, cmd, 1, usepoll); } while(0)
|
||||||
#define SSDFB_CMD2(c, a) do { cmd[0] = (c); cmd[1] = (a); error = sc->sc_cmd(sc->sc_cookie, cmd, 2, usepoll); } while(0)
|
#define SSDFB_CMD2(c, a) do { cmd[0] = (c); cmd[1] = (a); error = sc->sc_cmd(sc->sc_cookie, cmd, 2, usepoll); } while(0)
|
||||||
#define SSDFB_CMD3(c, a, b) do { cmd[0] = (c); cmd[1] = (a); cmd[2] = (b); error = sc->sc_cmd(sc->sc_cookie, cmd, 3, usepoll); } while(0)
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ssdfb_attach(struct ssdfb_softc *sc, int flags)
|
ssdfb_attach(struct ssdfb_softc *sc, int flags)
|
||||||
|
@ -349,6 +351,11 @@ ssdfb_detach(struct ssdfb_softc *sc)
|
||||||
mutex_exit(&sc->sc_cond_mtx);
|
mutex_exit(&sc->sc_cond_mtx);
|
||||||
kthread_join(sc->sc_thread);
|
kthread_join(sc->sc_thread);
|
||||||
|
|
||||||
|
if (sc->sc_uobj != NULL) {
|
||||||
|
mutex_enter(sc->sc_uobj->vmobjlock);
|
||||||
|
sc->sc_uobj->uo_refs--;
|
||||||
|
mutex_exit(sc->sc_uobj->vmobjlock);
|
||||||
|
}
|
||||||
config_detach(sc->sc_wsdisplay, DETACH_FORCE);
|
config_detach(sc->sc_wsdisplay, DETACH_FORCE);
|
||||||
|
|
||||||
cv_destroy(&sc->sc_cond);
|
cv_destroy(&sc->sc_cond);
|
||||||
|
@ -441,7 +448,7 @@ ssdfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
|
||||||
case WSDISPLAYIO_GETCMAP:
|
case WSDISPLAYIO_GETCMAP:
|
||||||
wc = (struct wsdisplay_cmap *)data;
|
wc = (struct wsdisplay_cmap *)data;
|
||||||
if (wc->index >= __arraycount(cmap) ||
|
if (wc->index >= __arraycount(cmap) ||
|
||||||
wc->count >= __arraycount(cmap) - wc->index)
|
wc->count > __arraycount(cmap) - wc->index)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
error = copyout(&cmap[wc->index], wc->red, wc->count);
|
error = copyout(&cmap[wc->index], wc->red, wc->count);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -576,7 +583,7 @@ static int
|
||||||
ssdfb_init(struct ssdfb_softc *sc)
|
ssdfb_init(struct ssdfb_softc *sc)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
uint8_t cmd[3];
|
uint8_t cmd[2];
|
||||||
bool usepoll = true;
|
bool usepoll = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -745,6 +752,18 @@ ssdfb_damage(struct ssdfb_softc *sc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ssdfb_udv_attach(struct ssdfb_softc *sc)
|
||||||
|
{
|
||||||
|
extern const struct cdevsw wsdisplay_cdevsw;
|
||||||
|
dev_t dev;
|
||||||
|
#define WSDISPLAYMINOR(unit, screen) (((unit) << 8) | (screen))
|
||||||
|
dev = makedev(cdevsw_lookup_major(&wsdisplay_cdevsw),
|
||||||
|
WSDISPLAYMINOR(device_unit(sc->sc_wsdisplay), 0));
|
||||||
|
sc->sc_uobj = udv_attach(dev, VM_PROT_READ|VM_PROT_WRITE, 0,
|
||||||
|
sc->sc_ri_bits_len);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ssdfb_is_modified(struct ssdfb_softc *sc)
|
ssdfb_is_modified(struct ssdfb_softc *sc)
|
||||||
{
|
{
|
||||||
|
@ -753,6 +772,9 @@ ssdfb_is_modified(struct ssdfb_softc *sc)
|
||||||
if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)
|
if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)
|
||||||
return sc->sc_modified;
|
return sc->sc_modified;
|
||||||
|
|
||||||
|
if (sc->sc_uobj == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
va = (vaddr_t)sc->sc_ri.ri_bits;
|
va = (vaddr_t)sc->sc_ri.ri_bits;
|
||||||
va_end = va + sc->sc_ri_bits_len;
|
va_end = va + sc->sc_ri_bits_len;
|
||||||
while (va < va_end) {
|
while (va < va_end) {
|
||||||
|
@ -776,6 +798,9 @@ ssdfb_clear_modify(struct ssdfb_softc *sc)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sc->sc_uobj == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
va = (vaddr_t)sc->sc_ri.ri_bits;
|
va = (vaddr_t)sc->sc_ri.ri_bits;
|
||||||
va_end = va + sc->sc_ri_bits_len;
|
va_end = va + sc->sc_ri_bits_len;
|
||||||
ret = false;
|
ret = false;
|
||||||
|
@ -800,6 +825,12 @@ ssdfb_thread(void *arg)
|
||||||
ssdfb_set_usepoll(sc, false);
|
ssdfb_set_usepoll(sc, false);
|
||||||
|
|
||||||
while(!sc->sc_detaching) {
|
while(!sc->sc_detaching) {
|
||||||
|
if (sc->sc_mode == WSDISPLAYIO_MODE_DUMBFB &&
|
||||||
|
sc->sc_uobj == NULL) {
|
||||||
|
mutex_exit(&sc->sc_cond_mtx);
|
||||||
|
ssdfb_udv_attach(sc);
|
||||||
|
mutex_enter(&sc->sc_cond_mtx);
|
||||||
|
}
|
||||||
if (!ssdfb_is_modified(sc)) {
|
if (!ssdfb_is_modified(sc)) {
|
||||||
if (cv_timedwait(&sc->sc_cond, &sc->sc_cond_mtx,
|
if (cv_timedwait(&sc->sc_cond, &sc->sc_cond_mtx,
|
||||||
sc->sc_mode == WSDISPLAYIO_MODE_EMUL
|
sc->sc_mode == WSDISPLAYIO_MODE_EMUL
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: ssdfbvar.h,v 1.1 2019/03/17 00:57:15 tnn Exp $ */
|
/* $NetBSD: ssdfbvar.h,v 1.2 2019/03/17 04:03:17 tnn Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 The NetBSD Foundation, Inc.
|
* Copyright (c) 2019 The NetBSD Foundation, Inc.
|
||||||
|
@ -225,6 +225,7 @@ struct ssdfb_softc {
|
||||||
bool sc_detaching;
|
bool sc_detaching;
|
||||||
int sc_backoff;
|
int sc_backoff;
|
||||||
bool sc_modified;
|
bool sc_modified;
|
||||||
|
struct uvm_object *sc_uobj;
|
||||||
|
|
||||||
/* reference to bus-specific code */
|
/* reference to bus-specific code */
|
||||||
void *sc_cookie;
|
void *sc_cookie;
|
||||||
|
|
Loading…
Reference in New Issue