Allow shared open of /dev/fwmem* for read-only.
This commit is contained in:
parent
8c5c585444
commit
78a182b242
@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/signal.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
#include <dev/firewire/firewire.h>
|
||||
#include <dev/firewire/firewirereg.h>
|
||||
@ -77,6 +78,11 @@ SYSCTL_INT(_debug, OID_AUTO, fwmem_debug, CTLFLAG_RW, &fwmem_debug, 0,
|
||||
|
||||
#define MAXLEN (512 << fwmem_speed)
|
||||
|
||||
struct fwmem_softc {
|
||||
struct fw_eui64 eui;
|
||||
int refcount;
|
||||
};
|
||||
|
||||
static struct fw_xfer *
|
||||
fwmem_xfer_req(
|
||||
struct fw_device *fwdev,
|
||||
@ -260,18 +266,25 @@ fwmem_write_block(
|
||||
int
|
||||
fwmem_open (dev_t dev, int flags, int fmt, fw_proc *td)
|
||||
{
|
||||
struct fw_eui64 *eui;
|
||||
struct fwmem_softc *fms;
|
||||
|
||||
if (dev->si_drv1 != NULL)
|
||||
return (EBUSY);
|
||||
|
||||
eui = (struct fw_eui64 *)malloc(sizeof(struct fw_eui64),
|
||||
if (dev->si_drv1 != NULL) {
|
||||
if ((flags & FWRITE) != 0)
|
||||
return (EBUSY);
|
||||
fms = (struct fwmem_softc *)dev->si_drv1;
|
||||
fms->refcount ++;
|
||||
} else {
|
||||
fms = (struct fwmem_softc *)malloc(sizeof(struct fwmem_softc),
|
||||
M_FW, M_WAITOK);
|
||||
if (eui == NULL)
|
||||
return ENOMEM;
|
||||
bcopy(&fwmem_eui64, eui, sizeof(struct fw_eui64));
|
||||
dev->si_drv1 = (void *)eui;
|
||||
dev->si_iosize_max = DFLTPHYS;
|
||||
if (fms == NULL)
|
||||
return ENOMEM;
|
||||
bcopy(&fwmem_eui64, &fms->eui, sizeof(struct fw_eui64));
|
||||
dev->si_drv1 = (void *)fms;
|
||||
dev->si_iosize_max = DFLTPHYS;
|
||||
fms->refcount = 1;
|
||||
}
|
||||
if (fwmem_debug)
|
||||
printf("%s: refcount=%d\n", __FUNCTION__, fms->refcount);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -279,8 +292,16 @@ fwmem_open (dev_t dev, int flags, int fmt, fw_proc *td)
|
||||
int
|
||||
fwmem_close (dev_t dev, int flags, int fmt, fw_proc *td)
|
||||
{
|
||||
free(dev->si_drv1, M_FW);
|
||||
dev->si_drv1 = NULL;
|
||||
struct fwmem_softc *fms;
|
||||
|
||||
fms = (struct fwmem_softc *)dev->si_drv1;
|
||||
fms->refcount --;
|
||||
if (fwmem_debug)
|
||||
printf("%s: refcount=%d\n", __FUNCTION__, fms->refcount);
|
||||
if (fms->refcount < 1) {
|
||||
free(dev->si_drv1, M_FW);
|
||||
dev->si_drv1 = NULL;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -309,6 +330,7 @@ void
|
||||
fwmem_strategy(struct bio *bp)
|
||||
{
|
||||
struct firewire_softc *sc;
|
||||
struct fwmem_softc *fms;
|
||||
struct fw_device *fwdev;
|
||||
struct fw_xfer *xfer;
|
||||
dev_t dev;
|
||||
@ -321,11 +343,12 @@ fwmem_strategy(struct bio *bp)
|
||||
sc = devclass_get_softc(firewire_devclass, unit);
|
||||
|
||||
s = splfw();
|
||||
fwdev = fw_noderesolve_eui64(sc->fc, (struct fw_eui64 *)dev->si_drv1);
|
||||
fms = (struct fwmem_softc *)dev->si_drv1;
|
||||
fwdev = fw_noderesolve_eui64(sc->fc, &fms->eui);
|
||||
if (fwdev == NULL) {
|
||||
if (fwmem_debug)
|
||||
printf("fwmem: no such device ID:%08x%08x\n",
|
||||
fwmem_eui64.hi, fwmem_eui64.lo);
|
||||
fms->eui.hi, fms->eui.lo);
|
||||
err = EINVAL;
|
||||
goto error;
|
||||
}
|
||||
@ -375,13 +398,16 @@ fwmem_strategy(struct bio *bp)
|
||||
int
|
||||
fwmem_ioctl (dev_t dev, u_long cmd, caddr_t data, int flag, fw_proc *td)
|
||||
{
|
||||
struct fwmem_softc *fms;
|
||||
int err = 0;
|
||||
|
||||
fms = (struct fwmem_softc *)dev->si_drv1;
|
||||
switch (cmd) {
|
||||
case FW_SDEUI64:
|
||||
bcopy(data, dev->si_drv1, sizeof(struct fw_eui64));
|
||||
bcopy(data, &fms->eui, sizeof(struct fw_eui64));
|
||||
break;
|
||||
case FW_GDEUI64:
|
||||
bcopy(dev->si_drv1, data, sizeof(struct fw_eui64));
|
||||
bcopy(&fms->eui, data, sizeof(struct fw_eui64));
|
||||
break;
|
||||
default:
|
||||
err = EINVAL;
|
||||
|
Loading…
Reference in New Issue
Block a user