diff options
author | n_hibma <n_hibma@FreeBSD.org> | 2000-04-08 17:02:13 +0000 |
---|---|---|
committer | n_hibma <n_hibma@FreeBSD.org> | 2000-04-08 17:02:13 +0000 |
commit | f6ef29acc9d18c7e9ef00e56c5b2e7c52ba66880 (patch) | |
tree | 5649bf536956d0bd77d9a4c3e136d1c0334ac160 /sys | |
parent | f073f6ac22aead5b58e40d498a72c280b2d65643 (diff) | |
download | FreeBSD-src-f6ef29acc9d18c7e9ef00e56c5b2e7c52ba66880.zip FreeBSD-src-f6ef29acc9d18c7e9ef00e56c5b2e7c52ba66880.tar.gz |
Update the urio driver. It now works on NetBSD and OpenBSD as well.
Update the license in the rio_usb.h (now rio500_usb.h) to not be GPL.
Sorry for committing that file in the first place. The change of license
was agreed to by the original author.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/rio500_usb.h (renamed from sys/dev/usb/rio_usb.h) | 31 | ||||
-rw-r--r-- | sys/dev/usb/urio.c | 309 |
2 files changed, 243 insertions, 97 deletions
diff --git a/sys/dev/usb/rio_usb.h b/sys/dev/usb/rio500_usb.h index 56c8ebb..c2da72e 100644 --- a/sys/dev/usb/rio_usb.h +++ b/sys/dev/usb/rio500_usb.h @@ -2,27 +2,26 @@ Copyright (C) 2000 Cesar Miquel (miquel@df.uba.ar) - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + Redistribution and use in source and binary forms, with or without + modification, are permitted under any licence of your choise which + meets the open source licence definiton + http://www.opensource.org/opd.html such as the GNU licence or the + BSD licence. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License or the BSD license for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ---------------------------------------------------------------------- - ---------------------------------------------------------------------- */ + Modified for FreeBSD by Iwasa Kazmi <kzmi@ca2.so-net.ne.jp> -/* modified for FreeBSD by Iwasa Kazmi <kzmi@ca2.so-net.ne.jp> */ + ---------------------------------------------------------------------- */ -/* $FreeBSD$ */ +/* $FreeBSD$ */ -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #include <sys/ioccom.h> #ifndef USB_VENDOR_DIAMOND #define USB_VENDOR_DIAMOND 0x841 @@ -34,7 +33,7 @@ struct RioCommand { -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) u_int16_t length; #else short length; @@ -47,7 +46,7 @@ struct RioCommand int timeout; }; -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #define RIO_SEND_COMMAND _IOWR('U', 200, struct RioCommand) #define RIO_RECV_COMMAND _IOWR('U', 201, struct RioCommand) #else @@ -57,5 +56,3 @@ struct RioCommand #define RIO_DIR_OUT 0x0 #define RIO_DIR_IN 0x1 - - diff --git a/sys/dev/usb/urio.c b/sys/dev/usb/urio.c index 120befd..fc3890a 100644 --- a/sys/dev/usb/urio.c +++ b/sys/dev/usb/urio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Iwasa Kazmi <kzmi@ca2.so-net.ne.jp> + * Copyright (c) 2000 Iwasa Kazmi * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +30,18 @@ /* $FreeBSD$ */ +/* + * 2000/3/24 added NetBSD/OpenBSD support (from Alex Nemirovsky) + * 2000/3/07 use two bulk-pipe handles for read and write (Dirk) + * 2000/3/06 change major number(143), and copyright header + * some fix for 4.0 (Dirk) + * 2000/3/05 codes for FreeBSD 4.x - CURRENT (Thanks to Dirk-Willem van Gulik) + * 2000/3/01 remove retry code from urioioctl() + * change method of bulk transfer (no interrupt) + * 2000/2/28 small fixes for new rio_usb.h + * 2000/2/24 first version. + */ + #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -41,10 +53,11 @@ #include <sys/module.h> #include <sys/bus.h> #include <sys/ioccom.h> -#include <sys/conf.h> +#endif #include <sys/fcntl.h> #include <sys/filio.h> -#endif +#include <sys/conf.h> +#include <sys/uio.h> #include <sys/tty.h> #include <sys/file.h> #include <sys/select.h> @@ -57,7 +70,7 @@ #include <dev/usb/usbdi_util.h> #include <dev/usb/usbdevs.h> -#include <dev/usb/rio_usb.h> +#include <dev/usb/rio500_usb.h> #ifdef URIO_DEBUG #define DPRINTF(x) if (uriodebug) logprintf x @@ -68,6 +81,20 @@ int uriodebug = 100; #define DPRINTFN(n,x) #endif +/* difference of usbd interface */ +#if defined(__FreeBSD__) +#if (__FreeBSD__ >= 4) + #define USBDI 1 +#else + #define USBDI 0 +#endif +#elif defined(__NetBSD__) || defined(__OpenBSD__) + #define USBDI 1 +#endif + +#define RIO_OUT 0 +#define RIO_IN 1 +#define RIO_NODIR 2 #if defined(__NetBSD__) int urioopen __P((dev_t, int, int, struct proc *)); @@ -75,6 +102,11 @@ int urioclose __P((dev_t, int, int, struct proc *p)); int urioread __P((dev_t, struct uio *uio, int)); int uriowrite __P((dev_t, struct uio *uio, int)); int urioioctl __P((dev_t, u_long, caddr_t, int, struct proc *)); + +cdev_decl(urio); +#define RIO_UE_GET_DIR(p) ((UE_GET_DIR(p) == UE_DIR_IN) ? RIO_IN :\ + ((UE_GET_DIR(p) == UE_DIR_OUT) ? RIO_OUT :\ + RIO_NODIR)) #elif defined(__FreeBSD__) d_open_t urioopen; d_close_t urioclose; @@ -82,14 +114,10 @@ d_read_t urioread; d_write_t uriowrite; d_ioctl_t urioioctl; -#define URIO_CDEV_MAJOR 143 - -#define RIO_OUT 0 -#define RIO_IN 1 -#define RIO_NODIR 2 +#define URIO_CDEV_MAJOR 143 #if (__FreeBSD__ >= 4) -Static struct cdevsw urio_cdevsw = { +static struct cdevsw urio_cdevsw = { urioopen, urioclose, urioread, uriowrite, urioioctl, nopoll, nommap, nostrategy, "urio", URIO_CDEV_MAJOR,nodump, nopsize, @@ -99,7 +127,7 @@ Static struct cdevsw urio_cdevsw = { ((UE_GET_DIR(p) == UE_DIR_OUT) ? RIO_OUT :\ RIO_NODIR)) #else -Static struct cdevsw urio_cdevsw = { +static struct cdevsw urio_cdevsw = { urioopen, urioclose, urioread, uriowrite, urioioctl, nostop, nullreset, nodevtotty, seltrue, nommap, nostrat, @@ -119,10 +147,14 @@ struct urio_softc { usbd_interface_handle sc_iface; int sc_opened; - usbd_pipe_handle sc_pipeh; - int sc_dir; - + usbd_pipe_handle sc_pipeh_in; + usbd_pipe_handle sc_pipeh_out; int sc_epaddr[2]; + + int sc_refcnt; +#if defined(__NetBSD__) || defined(__OpenBSD__) + u_char sc_dying; +#endif }; #define URIOUNIT(n) (minor(n)) @@ -154,8 +186,12 @@ USB_ATTACH(urio) { USB_ATTACH_START(urio, sc, uaa); char devinfo[1024]; - usb_endpoint_descriptor_t *edesc; + usbd_device_handle udev; + usbd_interface_handle iface; u_int8_t epcount; +#if defined(__NetBSD__) || defined(__OpenBSD__) + u_int8_t niface; +#endif usbd_status r; char * ermsg = "<none>"; int i; @@ -165,16 +201,37 @@ USB_ATTACH(urio) USB_ATTACH_SETUP; printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo); - sc->sc_udev = uaa->device; + sc->sc_udev = udev = uaa->device; + +#if defined(__FreeBSD__) if ((!uaa->device) || (!uaa->iface)) { ermsg = "device or iface"; goto nobulk; } - - sc->sc_iface = uaa->iface; + sc->sc_iface = iface = uaa->iface; +#elif defined(__NetBSD__) || defined(__OpenBSD__) + if (!udev) { + ermsg = "device"; + goto nobulk; + } + r = usbd_interface_count(udev, &niface); + if (r) { + ermsg = "iface"; + goto nobulk; + } + r = usbd_device2interface_handle(udev, 0, &iface); + if (r) { + ermsg = "iface"; + goto nobulk; + } + sc->sc_iface = iface; +#endif sc->sc_opened = 0; + sc->sc_pipeh_in = 0; + sc->sc_pipeh_out = 0; + sc->sc_refcnt = 0; - r = usbd_endpoint_count(uaa->iface, &epcount); + r = usbd_endpoint_count(iface, &epcount); if (r != USBD_NORMAL_COMPLETION) { ermsg = "endpoints"; goto nobulk; @@ -182,14 +239,20 @@ USB_ATTACH(urio) sc->sc_epaddr[RIO_OUT] = 0xff; sc->sc_epaddr[RIO_IN] = 0x00; + for (i = 0; i < epcount; i++) { - edesc = usbd_interface2endpoint_descriptor(uaa->iface, i); + usb_endpoint_descriptor_t *edesc = + usbd_interface2endpoint_descriptor(iface, i); + int d; + if (!edesc) { ermsg = "interface endpoint"; goto nobulk; } - sc->sc_epaddr[RIO_UE_GET_DIR(edesc->bEndpointAddress)] - = edesc->bEndpointAddress; + + d = RIO_UE_GET_DIR(edesc->bEndpointAddress); + if (d != RIO_NODIR) + sc->sc_epaddr[d] = edesc->bEndpointAddress; } if ( sc->sc_epaddr[RIO_OUT] == 0xff || sc->sc_epaddr[RIO_IN] == 0x00) { @@ -197,11 +260,16 @@ USB_ATTACH(urio) goto nobulk; } -#if (__FreeBSD__ >= 4) +#if defined(__FreeBSD__) + #if (__FreeBSD__ >= 4) /* XXX no error trapping, no storing of dev_t */ (void) make_dev(&urio_cdevsw, device_get_unit(self), UID_ROOT, GID_OPERATOR, 0644, "urio%d", device_get_unit(self)); + #endif +#elif defined(__NetBSD__) || defined(__OpenBSD__) + usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, + USBDEV(sc->sc_dev)); #endif DPRINTFN(10, ("urio_attach: %p\n", sc->sc_udev)); @@ -221,7 +289,7 @@ urioopen(dev, flag, mode, p) int mode; struct proc *p; { -#if (__FreeBSD__ >= 4) +#if (USBDI >= 1) struct urio_softc * sc; #endif int unit = URIOUNIT(dev); @@ -237,8 +305,24 @@ urioopen(dev, flag, mode, p) return EACCES; sc->sc_opened = 1; - sc->sc_pipeh = 0; - sc->sc_dir = RIO_NODIR; + sc->sc_pipeh_in = 0; + sc->sc_pipeh_out = 0; + if (usbd_open_pipe(sc->sc_iface, + sc->sc_epaddr[RIO_IN], 0, &sc->sc_pipeh_in) + != USBD_NORMAL_COMPLETION) + { + sc->sc_pipeh_in = 0; + return EIO; + }; + if (usbd_open_pipe(sc->sc_iface, + sc->sc_epaddr[RIO_OUT], 0, &sc->sc_pipeh_out) + != USBD_NORMAL_COMPLETION) + { + usbd_close_pipe(sc->sc_pipeh_in); + sc->sc_pipeh_in = 0; + sc->sc_pipeh_out = 0; + return EIO; + }; return 0; } @@ -249,19 +333,23 @@ urioclose(dev, flag, mode, p) int mode; struct proc *p; { -#if (__FreeBSD__ >= 4) +#if (USBDI >= 1) struct urio_softc * sc; #endif int unit = URIOUNIT(dev); USB_GET_SC(urio, unit, sc); DPRINTFN(5, ("urioclose: flag=%d, mode=%d, unit=%d\n", flag, mode, unit)); - if (sc->sc_pipeh) { - /*usbd_abort_pipe(sc->sc_pipeh);*/ - usbd_close_pipe(sc->sc_pipeh); - } - sc->sc_opened = 0; + if (sc->sc_pipeh_in) + usbd_close_pipe(sc->sc_pipeh_in); + + if (sc->sc_pipeh_out) + usbd_close_pipe(sc->sc_pipeh_out); + sc->sc_pipeh_in = 0; + sc->sc_pipeh_out = 0; + sc->sc_opened = 0; + sc->sc_refcnt = 0; return 0; } @@ -271,7 +359,7 @@ urioread(dev, uio, flag) struct uio *uio; int flag; { -#if (__FreeBSD__ >= 4) +#if (USBDI >= 1) struct urio_softc * sc; usbd_xfer_handle reqh; #else @@ -292,22 +380,8 @@ urioread(dev, uio, flag) if (!sc->sc_opened) return EIO; - if (sc->sc_dir != RIO_IN) { - if (sc->sc_pipeh) { - /*usbd_abort_pipe(sc->sc_pipeh);*/ - usbd_close_pipe(sc->sc_pipeh); - } - sc->sc_pipeh = 0; - sc->sc_dir = RIO_NODIR; - r = usbd_open_pipe(sc->sc_iface, - sc->sc_epaddr[RIO_IN], 0, - &sc->sc_pipeh); - if (r != USBD_NORMAL_COMPLETION) - return EIO; - sc->sc_dir = RIO_IN; - } - -#if (__FreeBSD__ >= 4) +#if (USBDI >= 1) + sc->sc_refcnt++; reqh = usbd_alloc_xfer(sc->sc_udev); #else reqh = usbd_alloc_request(); @@ -317,11 +391,11 @@ urioread(dev, uio, flag) while ((n = min(URIO_BBSIZE, uio->uio_resid)) != 0) { DPRINTFN(1, ("urioread: start transfer %d bytes\n", n)); tn = n; -#if (__FreeBSD__ >= 4) - usbd_setup_xfer(reqh, sc->sc_pipeh, 0, buf, tn, +#if (USBDI >= 1) + usbd_setup_xfer(reqh, sc->sc_pipeh_in, 0, buf, tn, 0, RIO_RW_TIMEOUT, 0); #else - r = usbd_setup_request(reqh, sc->sc_pipeh, 0, buf, tn, + r = usbd_setup_request(reqh, sc->sc_pipeh_in, 0, buf, tn, 0, RIO_RW_TIMEOUT, 0); if (r != USBD_NORMAL_COMPLETION) { error = EIO; @@ -331,12 +405,12 @@ urioread(dev, uio, flag) r = usbd_sync_transfer(reqh); if (r != USBD_NORMAL_COMPLETION) { DPRINTFN(1, ("urioread: error=%d\n", r)); - usbd_clear_endpoint_stall(sc->sc_pipeh); + usbd_clear_endpoint_stall(sc->sc_pipeh_in); tn = 0; error = EIO; break; } -#if (__FreeBSD__ >= 4) +#if (USBDI >= 1) usbd_get_xfer_status(reqh, 0, 0, &tn, 0); #else usbd_get_request_status(reqh, &r_priv, &r_buff, &tn, &r_status); @@ -347,7 +421,7 @@ urioread(dev, uio, flag) if (error || tn < n) break; } -#if (__FreeBSD__ >= 4) +#if (USBDI >= 1) usbd_free_xfer(reqh); #else usbd_free_request(reqh); @@ -362,7 +436,7 @@ uriowrite(dev, uio, flag) struct uio *uio; int flag; { -#if (__FreeBSD__ >= 4) +#if (USBDI >= 1) struct urio_softc * sc; usbd_xfer_handle reqh; #else @@ -380,22 +454,8 @@ uriowrite(dev, uio, flag) if (!sc->sc_opened) return EIO; - if (sc->sc_dir != RIO_OUT) { - if (sc->sc_pipeh) { - /*usbd_abort_pipe(sc->sc_pipeh);*/ - usbd_close_pipe(sc->sc_pipeh); - } - sc->sc_pipeh = 0; - sc->sc_dir = RIO_NODIR; - r = usbd_open_pipe(sc->sc_iface, - sc->sc_epaddr[RIO_OUT], 0, - &sc->sc_pipeh); - if (r != USBD_NORMAL_COMPLETION) - return EIO; - sc->sc_dir = RIO_OUT; - } - -#if (__FreeBSD__ >= 4) +#if (USBDI >= 1) + sc->sc_refcnt++; reqh = usbd_alloc_xfer(sc->sc_udev); #else reqh = usbd_alloc_request(); @@ -407,11 +467,11 @@ uriowrite(dev, uio, flag) if (error) break; DPRINTFN(1, ("uriowrite: transfer %d bytes\n", n)); -#if (__FreeBSD__ >= 4) - usbd_setup_xfer(reqh, sc->sc_pipeh, 0, buf, n, +#if (USBDI >= 1) + usbd_setup_xfer(reqh, sc->sc_pipeh_out, 0, buf, n, 0, RIO_RW_TIMEOUT, 0); #else - r = usbd_setup_request(reqh, sc->sc_pipeh, 0, buf, n, + r = usbd_setup_request(reqh, sc->sc_pipeh_out, 0, buf, n, 0, RIO_RW_TIMEOUT, 0); if (r != USBD_NORMAL_COMPLETION) { error = EIO; @@ -421,16 +481,16 @@ uriowrite(dev, uio, flag) r = usbd_sync_transfer(reqh); if (r != USBD_NORMAL_COMPLETION) { DPRINTFN(1, ("uriowrite: error=%d\n", r)); - usbd_clear_endpoint_stall(sc->sc_pipeh); + usbd_clear_endpoint_stall(sc->sc_pipeh_out); error = EIO; break; } -#if (__FreeBSD__ >= 4) +#if (USBDI >= 1) usbd_get_xfer_status(reqh, 0, 0, 0, 0); #endif } -#if (__FreeBSD__ >= 4) +#if (USBDI >= 1) usbd_free_xfer(reqh); #else usbd_free_request(reqh); @@ -448,7 +508,7 @@ urioioctl(dev, cmd, addr, flag, p) int flag; struct proc *p; { -#if (__FreeBSD__ >= 4) +#if (USBDI >= 1) struct urio_softc * sc; #endif int unit = URIOUNIT(dev); @@ -545,8 +605,97 @@ ret: } +#if defined(__NetBSD__) || defined(__OpenBSD__) +int +urio_activate(self, act) + device_ptr_t self; + enum devact act; +{ + struct urio_softc *sc = (struct urio_softc *)self; + + switch (act) { + case DVACT_ACTIVATE: + return (EOPNOTSUPP); + break; + + case DVACT_DEACTIVATE: + sc->sc_dying = 1; + break; + } + return (0); +} + +USB_DETACH(urio) +{ + USB_DETACH_START(urio, sc); + struct urio_endpoint *sce; + int i, dir; + int s; +#if defined(__NetBSD__) || defined(__OpenBSD__) + int maj, mn; + + DPRINTF(("urio_detach: sc=%p flags=%d\n", sc, flags)); +#elif defined(__FreeBSD__) + DPRINTF(("urio_detach: sc=%p\n", sc)); +#endif + + sc->sc_dying = 1; + /* Abort all pipes. Causes processes waiting for transfer to wake. */ +#if 0 + for (i = 0; i < USB_MAX_ENDPOINTS; i++) { + for (dir = OUT; dir <= IN; dir++) { + sce = &sc->sc_endpoints[i][dir]; + if (sce && sce->pipeh) + usbd_abort_pipe(sce->pipeh); + } + } + + s = splusb(); + if (--sc->sc_refcnt >= 0) { + /* Wake everyone */ + for (i = 0; i < USB_MAX_ENDPOINTS; i++) + wakeup(&sc->sc_endpoints[i][IN]); + /* Wait for processes to go away. */ + usb_detach_wait(USBDEV(sc->sc_dev)); + } + splx(s); +#else + if (sc->sc_pipeh_in) + usbd_abort_pipe(sc->sc_pipeh_in); + + if (sc->sc_pipeh_out) + usbd_abort_pipe(sc->sc_pipeh_out); + + s = splusb(); + if (--sc->sc_refcnt >= 0) { + /* Wait for processes to go away. */ + usb_detach_wait(USBDEV(sc->sc_dev)); + } + splx(s); +#endif + +#if defined(__NetBSD__) || defined(__OpenBSD__) + /* locate the major number */ + for (maj = 0; maj < nchrdev; maj++) + if (cdevsw[maj].d_open == urioopen) + break; + + /* Nuke the vnodes for any open instances (calls close). */ + mn = self->dv_unit * USB_MAX_ENDPOINTS; + vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR); +#elif defined(__FreeBSD__) + /* XXX not implemented yet */ +#endif + + usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, + USBDEV(sc->sc_dev)); + + return (0); +} +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ + #if defined(__FreeBSD__) -Static int +static int urio_detach(device_t self) { DPRINTF(("%s: disconnected\n", USBDEVNAME(self))); |