Change the kernel dev_t, representing a pointer to a specinfo structure,
[dragonfly.git] / sys / dev / serial / cy / cy.c
index 5bbfb0f..15ee4fd 100644 (file)
@@ -28,7 +28,7 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/isa/cy.c,v 1.97.2.2 2001/08/22 13:04:58 bde Exp $
- * $DragonFly: src/sys/dev/serial/cy/cy.c,v 1.11 2004/05/19 22:52:48 dillon Exp $
+ * $DragonFly: src/sys/dev/serial/cy/cy.c,v 1.22 2006/09/10 01:26:36 dillon Exp $
  */
 
 #include "opt_compat.h"
@@ -79,6 +79,7 @@
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/syslog.h>
+#include <sys/thread2.h>
 #include <machine/clock.h>
 #include <machine/ipl.h>
 #ifndef SMP
@@ -257,6 +258,7 @@ struct com_s {
 #endif
        int     unit;           /* unit number */
        int     dtr_wait;       /* time to hold DTR down on close (* 1/hz) */
+       struct callout dtr_ch;
 #if 0
        u_int   tx_fifo_size;
 #endif
@@ -329,7 +331,7 @@ struct com_s {
 
 /* PCI driver entry point. */
 int    cyattach_common         (cy_addr cy_iobase, int cy_align);
-ointhand2_t    siointr;
+void   siointr(void *);
 
 static int     cy_units        (cy_addr cy_iobase, int cy_align);
 static int     sioattach       (struct isa_device *dev);
@@ -378,24 +380,15 @@ static    d_write_t       siowrite;
 static d_ioctl_t       sioioctl;
 
 #define        CDEV_MAJOR      48
-static struct cdevsw sio_cdevsw = {
-       /* name */      driver_name,
-       /* maj */       CDEV_MAJOR,
-       /* flags */     D_TTY | D_KQFILTER,
-       /* port */      NULL,
-       /* clone */     NULL,
-
-       /* open */      sioopen,
-       /* close */     sioclose,
-       /* read */      ttyread,
-       /* write */     siowrite,
-       /* ioctl */     sioioctl,
-       /* poll */      ttypoll,
-       /* mmap */      nommap,
-       /* strategy */  nostrategy,
-       /* dump */      nodump,
-       /* psize */     nopsize,
-       /* kqfilter */  ttykqfilter
+static struct dev_ops sio_ops = {
+       { driver_name, CDEV_MAJOR, D_TTY | D_KQFILTER },
+       .d_open =       sioopen,
+       .d_close =      sioclose,
+       .d_read =       ttyread,
+       .d_write =      siowrite,
+       .d_ioctl =      sioioctl,
+       .d_poll =       ttypoll,
+       .d_kqfilter =   ttykqfilter
 };
 
 static int     comconsole = -1;
@@ -404,8 +397,7 @@ static      u_int   com_events;     /* input chars + weighted output completions */
 static bool_t  sio_registered;
 static int     sio_timeout;
 static int     sio_timeouts_until_log;
-static struct  callout_handle sio_timeout_handle
-    = CALLOUT_HANDLE_INITIALIZER(&sio_timeout_handle);
+static struct  callout sio_timeout_handle;
 #if 0 /* XXX */
 static struct tty      *sio_tty[NSIO];
 #else
@@ -517,7 +509,7 @@ sioattach(isdp)
                printf("cy%d: attached as cy%d\n", isdp->id_unit, adapter);
                isdp->id_unit = adapter;        /* XXX */
        }
-       isdp->id_ointr = siointr;
+       isdp->id_intr = (inthand2_t *)siointr;
        /* isdp->id_ri_flags |= RI_FAST; XXX unimplemented - use newbus! */
        return (1);
 }
@@ -563,13 +555,10 @@ cyattach_common(cy_iobase, cy_align)
 
                for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; ++cdu, ++unit) {
                        struct com_s    *com;
-                       int             s;
 
-       com = malloc(sizeof *com, M_DEVBUF, M_NOWAIT);
-       if (com == NULL)
-               break;
-       bzero(com, sizeof *com);
+       com = kmalloc(sizeof *com, M_DEVBUF, M_WAITOK | M_ZERO);
        com->unit = unit;
+                       callout_init(&com->dtr_ch);
                        com->gfrcr_image = firmware_version;
                        if (CY_RTS_DTR_SWAPPED(firmware_version)) {
                                com->mcr_dtr = MCR_RTS;
@@ -608,7 +597,7 @@ cyattach_common(cy_iobase, cy_align)
        }
        if (siosetwater(com, com->it_in.c_ispeed) != 0) {
                enable_intr();
-               free(com, M_DEVBUF);
+               kfree(com, M_DEVBUF);
                return (0);
        }
        enable_intr();
@@ -616,34 +605,37 @@ cyattach_common(cy_iobase, cy_align)
        com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
        com->it_out = com->it_in;
 
-       s = spltty();
+       crit_enter();
        com_addr(unit) = com;
-       splx(s);
+       crit_exit();
 
        if (!sio_registered) {
-               register_swi(SWI_TTY, siopoll, NULL, "cy");
+               callout_init(&sio_timeout_handle);
+               register_swi(SWI_TTY, siopoll, NULL, "cy", NULL);
                sio_registered = TRUE;
        }
        minorbase = UNIT_TO_MINOR(unit);
-       cdevsw_add(&sio_cdevsw, UNIT_TO_MINOR(-1), minorbase);
-       make_dev(&sio_cdevsw, minorbase,
+       dev_ops_add(&sio_ops, UNIT_TO_MINOR(-1), minorbase);
+       make_dev(&sio_ops, minorbase,
                UID_ROOT, GID_WHEEL, 0600, "ttyc%r%r", adapter,
                unit % CY_MAX_PORTS);
-       make_dev(&sio_cdevsw, minorbase | CONTROL_INIT_STATE,
+       make_dev(&sio_ops, minorbase | CONTROL_INIT_STATE,
                UID_ROOT, GID_WHEEL, 0600, "ttyic%r%r", adapter,
                unit % CY_MAX_PORTS);
-       make_dev(&sio_cdevsw, minorbase | CONTROL_LOCK_STATE,
+       make_dev(&sio_ops, minorbase | CONTROL_LOCK_STATE,
                UID_ROOT, GID_WHEEL, 0600, "ttylc%r%r", adapter,
                unit % CY_MAX_PORTS);
-       make_dev(&sio_cdevsw, minorbase | CALLOUT_MASK,
+       make_dev(&sio_ops, minorbase | CALLOUT_MASK,
                UID_UUCP, GID_DIALER, 0660, "cuac%r%r", adapter,
                unit % CY_MAX_PORTS);
-       make_dev(&sio_cdevsw, minorbase | CALLOUT_MASK | CONTROL_INIT_STATE,
+       make_dev(&sio_ops, minorbase | CALLOUT_MASK | CONTROL_INIT_STATE,
                UID_UUCP, GID_DIALER, 0660, "cuaic%r%r", adapter,
                unit % CY_MAX_PORTS);
-       make_dev(&sio_cdevsw, minorbase | CALLOUT_MASK | CONTROL_LOCK_STATE,
+       make_dev(&sio_ops, minorbase | CALLOUT_MASK | CONTROL_LOCK_STATE,
                UID_UUCP, GID_DIALER, 0660, "cualc%r%r", adapter,
                unit % CY_MAX_PORTS);
+
+       /* for(cdu...), for(cyu...) terminating blocks */
                }
        }
 
@@ -654,12 +646,12 @@ cyattach_common(cy_iobase, cy_align)
 }
 
 static int
-sioopen(dev_t dev, int flag, int mode, struct thread *td)
+sioopen(struct dev_open_args *ap)
 {
+       cdev_t dev = ap->a_head.a_dev;
        struct com_s    *com;
        int             error;
        int             mynor;
-       int             s;
        struct tty      *tp;
        int             unit;
 
@@ -675,7 +667,7 @@ sioopen(dev_t dev, int flag, int mode, struct thread *td)
        tp = com->tp = &sio_tty[unit];
 #endif
        dev->si_tty = tp;
-       s = spltty();
+       crit_enter();
        /*
         * We jump to this label after all non-interrupted sleeps to pick
         * up any changes of the device state.
@@ -698,7 +690,7 @@ open_top:
                        }
                } else {
                        if (com->active_out) {
-                               if (flag & O_NONBLOCK) {
+                               if (ap->a_oflags & O_NONBLOCK) {
                                        error = EBUSY;
                                        goto out;
                                }
@@ -710,7 +702,7 @@ open_top:
                        }
                }
                if (tp->t_state & TS_XCLUDE &&
-                   suser(td)) {
+                   suser_cred(ap->a_cred, 0)) {
                        error = EBUSY;
                        goto out;
                }
@@ -814,7 +806,7 @@ open_top:
         * Wait for DCD if necessary.
         */
        if (!(tp->t_state & TS_CARR_ON) && !(mynor & CALLOUT_MASK)
-           && !(tp->t_cflag & CLOCAL) && !(flag & O_NONBLOCK)) {
+           && !(tp->t_cflag & CLOCAL) && !(ap->a_oflags & O_NONBLOCK)) {
                ++com->wopeners;
                error = tsleep(TSA_CARR_ON(tp), PCATCH, "cydcd", 0);
                --com->wopeners;
@@ -828,18 +820,18 @@ open_top:
                com->active_out = TRUE;
        siosettimeout();
 out:
-       splx(s);
+       crit_exit();
        if (!(tp->t_state & TS_ISOPEN) && com->wopeners == 0)
                comhardclose(com);
        return (error);
 }
 
 static int
-sioclose(dev_t dev, int flag, int mode, struct thread *td)
+sioclose(struct dev_close_args *ap)
 {
+       cdev_t dev = ap->a_head.a_dev;
        struct com_s    *com;
        int             mynor;
-       int             s;
        struct tty      *tp;
 
        mynor = minor(dev);
@@ -847,15 +839,15 @@ sioclose(dev_t dev, int flag, int mode, struct thread *td)
                return (0);
        com = com_addr(MINOR_TO_UNIT(mynor));
        tp = com->tp;
-       s = spltty();
+       crit_enter();
        cd_etc(com, CD1400_ETC_STOPBREAK);
-       (*linesw[tp->t_line].l_close)(tp, flag);
+       (*linesw[tp->t_line].l_close)(tp, ap->a_fflag);
        disc_optim(tp, &tp->t_termios, com);
        comstop(tp, FREAD | FWRITE);
        comhardclose(com);
        ttyclose(tp);
        siosettimeout();
-       splx(s);
+       crit_exit();
 #ifdef broken /* session holds a ref to the tty; can't deallocate */
        ttyfree(tp);
        com->tp = sio_tty[unit] = NULL;
@@ -868,13 +860,12 @@ comhardclose(com)
        struct com_s    *com;
 {
        cy_addr         iobase;
-       int             s;
        struct tty      *tp;
        int             unit;
 
        unit = com->unit;
        iobase = com->iobase;
-       s = spltty();
+       crit_enter();
 #if 0
        com->poll = FALSE;
        com->poll_output = FALSE;
@@ -921,7 +912,8 @@ comhardclose(com)
                        cd1400_channel_cmd(com, com->channel_control);
 
                        if (com->dtr_wait != 0 && !(com->state & CS_DTR_OFF)) {
-                               timeout(siodtrwakeup, com, com->dtr_wait);
+                               callout_reset(&com->dtr_ch, com->dtr_wait,
+                                               siodtrwakeup, com);
                                com->state |= CS_DTR_OFF;
                        }
                }
@@ -939,15 +931,14 @@ comhardclose(com)
        com->active_out = FALSE;
        wakeup(&com->active_out);
        wakeup(TSA_CARR_ON(tp));        /* restart any wopeners */
-       splx(s);
+       crit_exit();
 }
 
 static int
-siowrite(dev, uio, flag)
-       dev_t           dev;
-       struct uio      *uio;
-       int             flag;
+siowrite(struct dev_write_args *ap)
 {
+       cdev_t dev = ap->a_head.a_dev;
+       struct uio *uio = ap->a_uio;
        int             mynor;
        struct tty      *tp;
        int             unit;
@@ -972,7 +963,7 @@ siowrite(dev, uio, flag)
         * sessions are raw anyhow.
         */
 #else
-       return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
+       return ((*linesw[tp->t_line].l_write)(tp, uio, ap->a_ioflag));
 #endif
 }
 
@@ -1075,9 +1066,9 @@ sioinput(com)
 }
 
 void
-siointr(unit)
-       int     unit;
+siointr(void *arg)
 {
+       int     unit = (int)arg;
        int     baseu;
        int     cy_align;
        cy_addr cy_iobase;
@@ -1562,12 +1553,14 @@ siointr1(com)
 #endif
 
 static int
-sioioctl(dev_t dev, u_long cmd, caddr_t        data, int flag, struct thread *td)
+sioioctl(struct dev_ioctl_args *ap)
 {
+       cdev_t dev = ap->a_head.a_dev;
+       caddr_t data = ap->a_data;
+       u_long cmd = ap->a_cmd;
        struct com_s    *com;
        int             error;
        int             mynor;
-       int             s;
        struct tty      *tp;
 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
        int             oldcmd;
@@ -1591,7 +1584,7 @@ sioioctl(dev_t dev, u_long cmd, caddr_t   data, int flag, struct thread *td)
                }
                switch (cmd) {
                case TIOCSETA:
-                       error = suser(td);
+                       error = suser_cred(ap->a_cred, 0);
                        if (error != 0)
                                return (error);
                        *ct = *(struct termios *)data;
@@ -1641,14 +1634,15 @@ sioioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
                if (lt->c_ospeed != 0)
                        dt->c_ospeed = tp->t_ospeed;
        }
-       error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, td);
+       error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data,
+                                             ap->a_fflag, ap->a_cred);
        if (error != ENOIOCTL)
                return (error);
-       s = spltty();
-       error = ttioctl(tp, cmd, data, flag);
+       crit_enter();
+       error = ttioctl(tp, cmd, data, ap->a_fflag);
        disc_optim(tp, &tp->t_termios, com);
        if (error != ENOIOCTL) {
-               splx(s);
+               crit_exit();
                return (error);
        }
        switch (cmd) {
@@ -1690,9 +1684,9 @@ sioioctl(dev_t dev, u_long cmd, caddr_t   data, int flag, struct thread *td)
                break;
        case TIOCMSDTRWAIT:
                /* must be root since the wait applies to following logins */
-               error = suser(td);
+               error = suser_cred(ap->a_cred, 0);
                if (error != 0) {
-                       splx(s);
+                       crit_exit();
                        return (error);
                }
                com->dtr_wait = *(int *)data * hz / 100;
@@ -1709,15 +1703,15 @@ sioioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
                *(struct timeval *)data = com->dcd_timestamp;
                break;
        default:
-               splx(s);
+               crit_exit();
                return (ENOTTY);
        }
-       splx(s);
+       crit_exit();
        return (0);
 }
 
 static void
-siopoll(void *data)
+siopoll(void *data, void *frame)
 {
        int             unit;
 
@@ -1822,7 +1816,6 @@ comparam(tp, t)
        int             odivisor;
        int             oprescaler;
        u_char          opt;
-       int             s;
        int             unit;
 
        /* do historical conversions */
@@ -1842,7 +1835,7 @@ comparam(tp, t)
                return (EINVAL);
 
        /* parameters are OK, convert them to the com struct and the device */
-       s = spltty();
+       crit_enter();
        if (odivisor == 0)
                (void)commctl(com, TIOCM_DTR, DMBIC);   /* hang up line */
        else
@@ -2169,10 +2162,10 @@ comparam(tp, t)
        }
 
        enable_intr();
-       splx(s);
+       crit_exit();
        comstart(tp);
        if (com->ibufold != NULL) {
-               free(com->ibufold, M_DEVBUF);
+               kfree(com->ibufold, M_DEVBUF);
                com->ibufold = NULL;
        }
        return (0);
@@ -2206,11 +2199,7 @@ siosetwater(com, speed)
         * Allocate input buffer.  The extra factor of 2 in the size is
         * to allow for an error byte for each input byte.
         */
-       ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT);
-       if (ibuf == NULL) {
-               disable_intr();
-               return (ENOMEM);
-       }
+       ibuf = kmalloc(2 * ibufsize, M_DEVBUF, M_WAITOK);
 
        /* Initialize non-critical variables. */
        com->ibufold = com->ibuf;
@@ -2253,7 +2242,6 @@ comstart(tp)
        struct tty      *tp;
 {
        struct com_s    *com;
-       int             s;
 #ifdef CyDebug
        bool_t          started;
 #endif
@@ -2261,7 +2249,7 @@ comstart(tp)
 
        unit = DEV_TO_UNIT(tp->t_dev);
        com = com_addr(unit);
-       s = spltty();
+       crit_enter();
 
 #ifdef CyDebug
        ++com->start_count;
@@ -2307,7 +2295,7 @@ comstart(tp)
        enable_intr();
        if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
                ttwwakeup(tp);
-               splx(s);
+               crit_exit();
                return;
        }
        if (tp->t_outq.c_cc != 0) {
@@ -2387,7 +2375,7 @@ comstart(tp)
        enable_intr();
 #endif
        ttwwakeup(tp);
-       splx(s);
+       crit_exit();
 }
 
 static void
@@ -2510,7 +2498,7 @@ siosettimeout()
         * Otherwise set it to max(1/200, 1/hz).
         * Enable timeouts iff some device is open.
         */
-       untimeout(comwakeup, (void *)NULL, sio_timeout_handle);
+       callout_stop(&sio_timeout_handle);
        sio_timeout = hz;
        someopen = FALSE;
        for (unit = 0; unit < NSIO; ++unit) {
@@ -2528,13 +2516,13 @@ siosettimeout()
        }
        if (someopen) {
                sio_timeouts_until_log = hz / sio_timeout;
-               sio_timeout_handle = timeout(comwakeup, (void *)NULL,
-                                            sio_timeout);
+               callout_reset(&sio_timeout_handle, sio_timeout,
+                               comwakeup, NULL);
        } else {
                /* Flush error messages, if any. */
                sio_timeouts_until_log = 1;
                comwakeup((void *)NULL);
-               untimeout(comwakeup, (void *)NULL, sio_timeout_handle);
+               callout_stop(&sio_timeout_handle);
        }
 }
 
@@ -2545,7 +2533,7 @@ comwakeup(chan)
        struct com_s    *com;
        int             unit;
 
-       sio_timeout_handle = timeout(comwakeup, (void *)NULL, sio_timeout);
+       callout_reset(&sio_timeout_handle, sio_timeout, comwakeup, NULL);
 
 #if 0
        /*