diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c index e3c0f28417ea..561567d698b0 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 4a5342404575..0fe89d7f045e 100644 --- a/sys/dev/amr/amr_linux.c +++ b/sys/dev/amr/amr_linux.c @@ -33,7 +33,8 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include +#include #if defined(__amd64__) /* Assume amd64 wants 32 bit Linux */ #include @@ -44,14 +45,6 @@ __FBSDID("$FreeBSD$"); #endif #include -#include -#include - -#include - -#include -#include - /* 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); } diff --git a/sys/dev/amr/amrvar.h b/sys/dev/amr/amrvar.h index 2f9a72837831..1fd78fd97746 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.