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.
This commit is contained in:
ambrisko 2006-05-03 16:45:15 +00:00
parent bc8c6150b8
commit 5ac8fc29a5
3 changed files with 41 additions and 127 deletions

View File

@ -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);

View File

@ -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;
struct file *fp;
int error;
devclass = devclass_find("amr");
if (devclass == NULL)
return (ENOENT);
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);
}

View File

@ -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.