Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147525159
D20733.1783669826.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D20733.1783669826.diff
View Options
Index: sys/dev/proto/proto.h
===================================================================
--- sys/dev/proto/proto.h
+++ sys/dev/proto/proto.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014, 2015 Marcel Moolenaar
+ * Copyright (c) 2014, 2015, 2019 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,8 @@
#define PROTO_RES_BUSDMA 11
struct proto_res {
- int r_type;
+ u_int r_type:8;
+ u_int r_opened:1;
int r_rid;
union {
struct resource *res;
@@ -47,13 +48,14 @@
void *cookie;
struct cdev *cdev;
} r_u;
- uintptr_t r_opened;
};
struct proto_softc {
device_t sc_dev;
struct proto_res sc_res[PROTO_RES_MAX];
int sc_rescnt;
+ int sc_opencnt;
+ struct mtx sc_mtx;
};
extern devclass_t proto_devclass;
Index: sys/dev/proto/proto_busdma.h
===================================================================
--- sys/dev/proto/proto_busdma.h
+++ sys/dev/proto/proto_busdma.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Marcel Moolenaar
+ * Copyright (c) 2015, 2019 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -60,6 +60,7 @@
LIST_HEAD(,proto_tag) tags;
LIST_HEAD(,proto_md) mds;
bus_dma_tag_t bd_roottag;
+ struct sx sxlck;
};
struct proto_busdma *proto_busdma_attach(struct proto_softc *);
Index: sys/dev/proto/proto_busdma.c
===================================================================
--- sys/dev/proto/proto_busdma.c
+++ sys/dev/proto/proto_busdma.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Marcel Moolenaar
+ * Copyright (c) 2015, 2019 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,6 +40,7 @@
#include <sys/queue.h>
#include <sys/rman.h>
#include <sys/sbuf.h>
+#include <sys/sx.h>
#include <sys/uio.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@@ -355,6 +356,7 @@
struct proto_busdma *busdma;
busdma = malloc(sizeof(*busdma), M_PROTO_BUSDMA, M_WAITOK | M_ZERO);
+ sx_init(&busdma->sxlck, "proto-busdma");
return (busdma);
}
@@ -363,6 +365,7 @@
{
proto_busdma_cleanup(sc, busdma);
+ sx_destroy(&busdma->sxlck);
free(busdma, M_PROTO_BUSDMA);
return (0);
}
@@ -373,10 +376,12 @@
struct proto_md *md, *md1;
struct proto_tag *tag, *tag1;
+ sx_xlock(&busdma->sxlck);
LIST_FOREACH_SAFE(md, &busdma->mds, mds, md1)
proto_busdma_md_destroy_internal(busdma, md);
LIST_FOREACH_SAFE(tag, &busdma->tags, tags, tag1)
proto_busdma_tag_destroy(busdma, tag);
+ sx_xunlock(&busdma->sxlck);
return (0);
}
@@ -388,6 +393,8 @@
struct proto_md *md;
int error;
+ sx_xlock(&busdma->sxlck);
+
error = 0;
switch (ioc->request) {
case PROTO_IOC_BUSDMA_TAG_CREATE:
@@ -470,6 +477,9 @@
error = EINVAL;
break;
}
+
+ sx_xunlock(&busdma->sxlck);
+
return (error);
}
@@ -477,11 +487,20 @@
proto_busdma_mmap_allowed(struct proto_busdma *busdma, vm_paddr_t physaddr)
{
struct proto_md *md;
+ int result;
+ sx_xlock(&busdma->sxlck);
+
+ result = 0;
LIST_FOREACH(md, &busdma->mds, mds) {
if (physaddr >= trunc_page(md->physaddr) &&
- physaddr <= trunc_page(md->physaddr + md->tag->maxsz))
- return (1);
+ physaddr <= trunc_page(md->physaddr + md->tag->maxsz)) {
+ result = 1;
+ break;
+ }
}
- return (0);
+
+ sx_xunlock(&busdma->sxlck);
+
+ return (result);
}
Index: sys/dev/proto/proto_core.c
===================================================================
--- sys/dev/proto/proto_core.c
+++ sys/dev/proto/proto_core.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014, 2015 Marcel Moolenaar
+ * Copyright (c) 2014, 2015, 2019 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -184,6 +184,7 @@
sc = device_get_softc(dev);
sc->sc_dev = dev;
+ mtx_init(&sc->sc_mtx, "proto-softc", NULL, MTX_DEF);
for (res = 0; res < sc->sc_rescnt; res++) {
r = sc->sc_res + res;
@@ -231,15 +232,16 @@
sc = device_get_softc(dev);
- /* Don't detach if we have open device files. */
- for (res = 0; res < sc->sc_rescnt; res++) {
- r = sc->sc_res + res;
- if (r->r_opened)
- return (EBUSY);
- }
+ mtx_lock(&sc->sc_mtx);
+ if (sc->sc_opencnt == 0)
+ sc->sc_opencnt = -1;
+ mtx_unlock(&sc->sc_mtx);
+ if (sc->sc_opencnt > 0)
+ return (EBUSY);
for (res = 0; res < sc->sc_rescnt; res++) {
r = sc->sc_res + res;
+
switch (r->r_type) {
case SYS_RES_IRQ:
/* XXX TODO */
@@ -252,21 +254,25 @@
break;
case SYS_RES_MEMORY:
case SYS_RES_IOPORT:
+ destroy_dev(r->r_u.cdev);
bus_release_resource(dev, r->r_type, r->r_rid,
r->r_d.res);
- destroy_dev(r->r_u.cdev);
break;
case PROTO_RES_PCICFG:
destroy_dev(r->r_u.cdev);
break;
case PROTO_RES_BUSDMA:
- proto_busdma_detach(sc, r->r_d.busdma);
destroy_dev(r->r_u.cdev);
+ proto_busdma_detach(sc, r->r_d.busdma);
break;
}
r->r_type = PROTO_RES_UNUSED;
}
+ mtx_lock(&sc->sc_mtx);
sc->sc_rescnt = 0;
+ sc->sc_opencnt = 0;
+ mtx_unlock(&sc->sc_mtx);
+ mtx_destroy(&sc->sc_mtx);
return (0);
}
@@ -278,11 +284,23 @@
proto_open(struct cdev *cdev, int oflags, int devtype, struct thread *td)
{
struct proto_res *r;
+ struct proto_softc *sc;
+ int error;
- r = cdev->si_drv2;
- if (!atomic_cmpset_acq_ptr(&r->r_opened, 0UL, (uintptr_t)td->td_proc))
- return (EBUSY);
- return (0);
+ sc = cdev->si_drv1;
+ mtx_lock(&sc->sc_mtx);
+ if (sc->sc_opencnt >= 0) {
+ r = cdev->si_drv2;
+ if (!r->r_opened) {
+ r->r_opened = 1;
+ sc->sc_opencnt++;
+ error = 0;
+ } else
+ error = EBUSY;
+ } else
+ error = ENXIO;
+ mtx_unlock(&sc->sc_mtx);
+ return (error);
}
static int
@@ -290,14 +308,24 @@
{
struct proto_res *r;
struct proto_softc *sc;
+ int error;
sc = cdev->si_drv1;
- r = cdev->si_drv2;
- if (!atomic_cmpset_acq_ptr(&r->r_opened, (uintptr_t)td->td_proc, 0UL))
- return (ENXIO);
- if (r->r_type == PROTO_RES_BUSDMA)
- proto_busdma_cleanup(sc, r->r_d.busdma);
- return (0);
+ mtx_lock(&sc->sc_mtx);
+ if (sc->sc_opencnt > 0) {
+ r = cdev->si_drv2;
+ if (r->r_opened) {
+ if (r->r_type == PROTO_RES_BUSDMA)
+ proto_busdma_cleanup(sc, r->r_d.busdma);
+ r->r_opened = 0;
+ sc->sc_opencnt--;
+ error = 0;
+ } else
+ error = ENXIO;
+ } else
+ error = ENXIO;
+ mtx_unlock(&sc->sc_mtx);
+ return (error);
}
static int
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jul 10, 7:50 AM (13 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29054178
Default Alt Text
D20733.1783669826.diff (6 KB)
Attached To
Mode
D20733: Lock busdma operations and serialize detach with open/close
Attached
Detach File
Event Timeline
Log In to Comment