Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/riastradh-drm2]: src/sys/external/bsd/drm2/drm Manage an opencount for e...
details: https://anonhg.NetBSD.org/src/rev/58c165710d73
branches: riastradh-drm2
changeset: 788462:58c165710d73
user: riastradh <riastradh%NetBSD.org@localhost>
date: Wed Jul 24 03:55:17 2013 +0000
description:
Manage an opencount for each drm device to block drm_detach.
diffstat:
sys/external/bsd/drm2/drm/drm_drv.c | 31 +++++++++++++++++++++++++------
1 files changed, 25 insertions(+), 6 deletions(-)
diffs (102 lines):
diff -r 0250d42f5aab -r 58c165710d73 sys/external/bsd/drm2/drm/drm_drv.c
--- a/sys/external/bsd/drm2/drm/drm_drv.c Wed Jul 24 03:55:00 2013 +0000
+++ b/sys/external/bsd/drm2/drm/drm_drv.c Wed Jul 24 03:55:17 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: drm_drv.c,v 1.1.2.14 2013/07/24 03:55:00 riastradh Exp $ */
+/* $NetBSD: drm_drv.c,v 1.1.2.15 2013/07/24 03:55:17 riastradh Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_drv.c,v 1.1.2.14 2013/07/24 03:55:00 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_drv.c,v 1.1.2.15 2013/07/24 03:55:17 riastradh Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -58,6 +58,7 @@
struct drm_softc {
struct drm_device *sc_drm_dev;
struct drm_minor sc_minor[__arraycount(drm_minor_types)];
+ unsigned int sc_opencount;
};
static int drm_match(device_t, cfdata_t, void *);
@@ -259,6 +260,7 @@
aprint_normal("\n");
sc->sc_drm_dev = dev;
+ sc->sc_opencount = 0;
if (device_unit(self) >= 64) { /* XXX Need to do something here! */
aprint_error_dev(self, "can't handle >=64 drm devices!");
@@ -305,6 +307,9 @@
const struct drm_driver *const driver = dev->driver;
KASSERT(driver != NULL);
+ if (sc->sc_opencount != 0)
+ return EBUSY;
+
/*
* XXX Synchronize with drm_fill_in_dev, perhaps with reference
* to drm_put_dev.
@@ -359,9 +364,11 @@
static int
drm_open(dev_t d, int flags, int fmt, struct lwp *l)
{
+ struct drm_softc *const sc = drm_dev_softc(d);
struct drm_minor *const dminor = drm_dev_minor(d);
int fd;
struct file *fp;
+ unsigned int opencount;
int error;
if (dminor == NULL) {
@@ -379,16 +386,25 @@
goto fail0;
}
+ do {
+ opencount = sc->sc_opencount;
+ if (opencount == UINT_MAX) {
+ error = EBUSY;
+ goto fail0;
+ }
+ } while (atomic_cas_uint(&sc->sc_opencount, opencount, (opencount + 1))
+ != opencount);
+
error = fd_allocfile(&fp, &fd);
if (error)
- goto fail0;
+ goto fail1;
struct drm_file *const file = kmem_zalloc(sizeof(*file), KM_SLEEP);
/* XXX errno Linux->NetBSD */
error = -drm_open_file(file, fp, dminor);
if (error)
- goto fail2;
+ goto fail3;
error = fd_clone(fp, fd, flags, &drm_fileops, file);
KASSERT(error == EMOVEFD); /* XXX */
@@ -396,12 +412,15 @@
/* Success! (But error has to be EMOVEFD, not 0.) */
return error;
-fail2:
+fail3:
kmem_free(file, sizeof(*file));
-fail1: __unused
+fail2: __unused
fd_abort(curproc, fp, fd);
+fail1:
+ atomic_dec_uint(&sc->sc_opencount);
+
fail0:
return error;
}
Home |
Main Index |
Thread Index |
Old Index