summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorambrisko <ambrisko@FreeBSD.org>2006-05-03 16:45:15 +0000
committerambrisko <ambrisko@FreeBSD.org>2006-05-03 16:45:15 +0000
commit5ac8fc29a50d17243ef3f7f055a226f1a2aba36f (patch)
tree0f74a33e8aae35668c42ade681ef8971900a6268 /sys
parentbc8c6150b8b8bcf7f4d87cd487737add8f446366 (diff)
downloadFreeBSD-src-5ac8fc29a50d17243ef3f7f055a226f1a2aba36f.zip
FreeBSD-src-5ac8fc29a50d17243ef3f7f055a226f1a2aba36f.tar.gz
Make amr_linux work as a module by avoiding calling amr_linux_ioctl_int
from the amr_linux. This simplifies the amr_linux shim and puts the smarts into amr.c. I tested this with 2 amr controllers in one box. It seems to work okay with them.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/amr/amr.c37
-rw-r--r--sys/dev/amr/amr_linux.c129
-rw-r--r--sys/dev/amr/amrvar.h2
3 files changed, 41 insertions, 127 deletions
diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c
index e3c0f28..561567d 100644
--- a/sys/dev/amr/amr.c
+++ b/sys/dev/amr/amr.c
@@ -110,6 +110,7 @@ static struct cdevsw amr_cdevsw = {
.d_name = "amr",
};
+int linux_no_adapter = 0;
/*
* Initialisation, bus interface.
*/
@@ -177,6 +178,8 @@ static void amr_printcommand(struct amr_command *ac);
#endif
static void amr_init_sysctl(struct amr_softc *sc);
+static int amr_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t addr,
+ int32_t flag, d_thread_t *td);
/********************************************************************************
********************************************************************************
@@ -258,6 +261,9 @@ amr_attach(struct amr_softc *sc)
sc->amr_dev_t = make_dev(&amr_cdevsw, device_get_unit(sc->amr_dev), UID_ROOT, GID_OPERATOR,
S_IRUSR | S_IWUSR, "amr%d", device_get_unit(sc->amr_dev));
sc->amr_dev_t->si_drv1 = sc;
+ linux_no_adapter++;
+ if (device_get_unit(sc->amr_dev) == 0)
+ make_dev_alias(sc->amr_dev_t, "megadev0");
/*
* Schedule ourselves to bring the controller up once interrupts are
@@ -542,9 +548,9 @@ amr_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag,
break;
case 'm':
- copyout(&sc->amr_linux_no_adapters, (void *)(uintptr_t)ali.data,
- sizeof(sc->amr_linux_no_adapters));
- td->td_retval[0] = sc->amr_linux_no_adapters;
+ copyout(&linux_no_adapter, (void *)(uintptr_t)ali.data,
+ sizeof(linux_no_adapter));
+ td->td_retval[0] = linux_no_adapter;
error = 0;
break;
@@ -768,9 +774,30 @@ amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *
case 0xc0046d00:
case 0xc06e6d00: /* Linux emulation */
- return amr_linux_ioctl_int(dev, cmd, addr, flag, td);
- break;
+ {
+ devclass_t devclass;
+ struct amr_linux_ioctl ali;
+ int adapter, error;
+
+ devclass = devclass_find("amr");
+ if (devclass == NULL)
+ return (ENOENT);
+ error = copyin(addr, &ali, sizeof(ali));
+ if (error)
+ return (error);
+ if (ali.ui.fcs.opcode == 0x82)
+ adapter = 0;
+ else
+ adapter = (ali.ui.fcs.adapno) ^ 'm' << 8;
+
+ sc = devclass_get_softc(devclass, adapter);
+ if (sc == NULL)
+ return (ENOENT);
+
+ return (amr_linux_ioctl_int(sc->amr_dev_t, cmd,
+ addr, 0, td));
+ }
default:
debug(1, "unknown ioctl 0x%lx", cmd);
return(ENOIOCTL);
diff --git a/sys/dev/amr/amr_linux.c b/sys/dev/amr/amr_linux.c
index 4a53424..0fe89d7 100644
--- a/sys/dev/amr/amr_linux.c
+++ b/sys/dev/amr/amr_linux.c
@@ -33,7 +33,8 @@ __FBSDID("$FreeBSD$");
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/module.h>
-#include <sys/bio.h>
+#include <sys/file.h>
+#include <sys/proc.h>
#if defined(__amd64__) /* Assume amd64 wants 32 bit Linux */
#include <machine/../linux32/linux.h>
@@ -44,14 +45,6 @@ __FBSDID("$FreeBSD$");
#endif
#include <compat/linux/linux_ioctl.h>
-#include <sys/bus.h>
-#include <sys/stat.h>
-
-#include <machine/bus.h>
-
-#include <dev/amr/amrreg.h>
-#include <dev/amr/amrvar.h>
-
/* There are multiple ioctl number ranges that need to be handled */
#define AMR_LINUX_IOCTL_MIN 0x6d00
#define AMR_LINUX_IOCTL_MAX 0x6d01
@@ -66,128 +59,24 @@ SYSINIT (amr_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
SYSUNINIT(amr_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
linux_ioctl_unregister_handler, &amr_linux_handler);
-static d_open_t amr_linux_open;
-static d_close_t amr_linux_close;
-
-static int amr_linux_isopen;
-static struct cdev * amr_linux_dev_t;
-
-static struct cdevsw megadev_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = amr_linux_open,
- .d_close = amr_linux_close,
- .d_name = "megadev",
-};
-
-
-static int
-amr_linux_open(struct cdev * dev, int flags, int fmt, d_thread_t *td)
-{
-
- amr_linux_isopen++;
- return (0);
-};
-
-static int
-amr_linux_close(struct cdev * dev, int flags, int fmt, d_thread_t *td)
-{
-
- amr_linux_isopen--;
- return (0);
-};
-
-static int
-amr_linux_init(void)
-{
- devclass_t devclass;
- struct amr_softc *sc;
- int i, linux_no_adapters, max_unit;
-
- devclass = devclass_find("amr");
- if (devclass == NULL)
- return (0);
-
- max_unit = devclass_get_maxunit(devclass);
- if (max_unit == 0)
- return (0);
-
- for (i = 0; i < max_unit; i++) {
- sc = devclass_get_softc(devclass, i);
- if (sc == NULL)
- break;
- }
-
- linux_no_adapters = i;
- for (i = 0; i < linux_no_adapters; i++) {
- sc = devclass_get_softc(devclass, i);
- if (sc == NULL)
- break;
- sc->amr_linux_no_adapters = linux_no_adapters;
- }
-
- return (linux_no_adapters);
-}
-
static int
amr_linux_modevent(module_t mod, int cmd, void *data)
{
-
- switch (cmd) {
- case MOD_LOAD:
- if (amr_linux_init() == 0)
- return (ENXIO);
-
- if (amr_linux_dev_t)
- return (EEXIST);
-
- amr_linux_dev_t = make_dev(&megadev_cdevsw, 0, UID_ROOT,
- GID_OPERATOR, S_IRUSR | S_IWUSR, "megadev%d", 0);
- if (amr_linux_dev_t == NULL)
- return (ENXIO);
- break;
-
- case MOD_UNLOAD:
- if (amr_linux_isopen)
- return (EBUSY);
- if (amr_linux_dev_t)
- destroy_dev(amr_linux_dev_t);
- break;
-
- default:
- return (EINVAL);
- }
return (0);
}
-static moduledata_t amr_linux_mod = {"amr_linux", amr_linux_modevent, NULL};
-DECLARE_MODULE(amr_linux, amr_linux_mod, SI_SUB_PSEUDO, SI_ORDER_MIDDLE);
+DEV_MODULE(amr_linux, amr_linux_modevent, NULL);
MODULE_DEPEND(amr, linux, 1, 1, 1);
static int
amr_linux_ioctl(d_thread_t *p, struct linux_ioctl_args *args)
{
- devclass_t devclass;
- struct amr_softc *sc;
- struct amr_linux_ioctl ali;
- int adapter, error;
-
- devclass = devclass_find("amr");
- if (devclass == NULL)
- return (ENOENT);
+ struct file *fp;
+ int error;
- error = copyin((caddr_t)args->arg, &ali, sizeof(ali));
- if (error)
+ if ((error = fget(p, args->fd, &fp)) != 0)
return (error);
- if (ali.ui.fcs.opcode == 0x82)
- adapter = 0;
- else
- adapter = (ali.ui.fcs.adapno) ^ 'm' << 8;
-
- sc = devclass_get_softc(devclass, adapter);
- if (sc == NULL)
- return (ENOENT);
-
- return (amr_linux_ioctl_int(sc->amr_dev_t, args->cmd,
- (caddr_t)args->arg, 0, p));
+ error = fo_ioctl(fp, args->cmd, (caddr_t)args->arg, p->td_ucred, p);
+ fdrop(fp, p);
+ return (error);
}
diff --git a/sys/dev/amr/amrvar.h b/sys/dev/amr/amrvar.h
index 2f9a728..1fd78fd 100644
--- a/sys/dev/amr/amrvar.h
+++ b/sys/dev/amr/amrvar.h
@@ -254,8 +254,6 @@ extern void amr_free(struct amr_softc *sc);
extern int amr_flush(struct amr_softc *sc);
extern int amr_done(struct amr_softc *sc);
extern void amr_startio(struct amr_softc *sc);
-extern int amr_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t addr,
- int32_t flag, d_thread_t *td);
/*
* Command buffer allocation.
OpenPOWER on IntegriCloud