BSD 4_4 release
[unix-history] / usr / src / sys / tahoe / vba / mp.c
index ccf52b0..250f4c9 100644 (file)
@@ -5,19 +5,35 @@
  * This code is derived from software contributed to Berkeley by
  * Computer Consoles Inc.
  *
  * This code is derived from software contributed to Berkeley by
  * Computer Consoles Inc.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- *     @(#)mp.c        7.10 (Berkeley) %G%
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)mp.c        7.17 (Berkeley) 5/16/91
  */
 
 #include "mp.h"
  */
 
 #include "mp.h"
  * Multi Protocol Communications Controller (MPCC).
  * Asynchronous Terminal Protocol Support.
  */
  * Multi Protocol Communications Controller (MPCC).
  * Asynchronous Terminal Protocol Support.
  */
-#include "param.h"
-#include "ioctl.h"
-#include "tty.h"
-#include "user.h"
-#include "map.h"
-#include "buf.h"
-#include "conf.h"
-#include "file.h"
-#include "errno.h"
-#include "syslog.h"
-#include "vmmac.h"
-#include "kernel.h"
-#include "clist.h"
-
-#include "machine/pte.h"
-#include "machine/mtpr.h"
-
-#include "../tahoevba/vbavar.h"
-#include "../tahoevba/mpreg.h"
+#include "sys/param.h"
+#include "sys/ioctl.h"
+#include "sys/tty.h"
+#include "sys/user.h"
+#include "sys/map.h"
+#include "sys/buf.h"
+#include "sys/conf.h"
+#include "sys/file.h"
+#include "sys/errno.h"
+#include "sys/syslog.h"
+#include "sys/vmmac.h"
+#include "sys/kernel.h"
+#include "sys/clist.h"
+
+#include "../include/pte.h"
+#include "../include/mtpr.h"
+
+#include "../vba/vbavar.h"
+#include "../vba/mpreg.h"
 
 #define        MPCHUNK 16
 #define        MPPORT(n)       ((n) & 0xf)
 
 #define        MPCHUNK 16
 #define        MPPORT(n)       ((n) & 0xf)
@@ -210,8 +226,12 @@ mpopen(dev, mode)
         * serialize open and close events
         */
        while ((mp->mp_flags & MP_PROGRESS) || ((tp->t_state & TS_WOPEN) && 
         * serialize open and close events
         */
        while ((mp->mp_flags & MP_PROGRESS) || ((tp->t_state & TS_WOPEN) && 
-               !(mode&O_NONBLOCK) && !(tp->t_cflag&CLOCAL)))
-               sleep((caddr_t)&tp->t_canq, TTIPRI);
+           !(mode&O_NONBLOCK) && !(tp->t_cflag&CLOCAL)))
+               if (error = tsleep((caddr_t)&tp->t_canq, TTIPRI | PCATCH,
+                   ttopen, 0)) {
+                       splx(s);
+                       return (error);
+               }
 restart:
        tp->t_state |= TS_WOPEN;
        tp->t_addr = (caddr_t)ms;
 restart:
        tp->t_state |= TS_WOPEN;
        tp->t_addr = (caddr_t)ms;
@@ -221,12 +241,12 @@ restart:
        if ((tp->t_state & TS_ISOPEN) == 0) {
                ttychars(tp);
                if (tp->t_ispeed == 0) {
        if ((tp->t_state & TS_ISOPEN) == 0) {
                ttychars(tp);
                if (tp->t_ispeed == 0) {
-               tp->t_ispeed = TTYDEF_SPEED;
-               tp->t_ospeed = TTYDEF_SPEED;
-               tp->t_iflag = TTYDEF_IFLAG;
-               tp->t_oflag = TTYDEF_OFLAG;
-               tp->t_lflag = TTYDEF_LFLAG;
-               tp->t_cflag = TTYDEF_CFLAG;
+                       tp->t_ispeed = TTYDEF_SPEED;
+                       tp->t_ospeed = TTYDEF_SPEED;
+                       tp->t_iflag = TTYDEF_IFLAG;
+                       tp->t_oflag = TTYDEF_OFLAG;
+                       tp->t_lflag = TTYDEF_LFLAG;
+                       tp->t_cflag = TTYDEF_CFLAG;
                }
                /*
                 * Initialize port state: init MPCC interface
                }
                /*
                 * Initialize port state: init MPCC interface
@@ -246,13 +266,17 @@ restart:
                 * wait for port to start
                 */
                while (mp->mp_proto != MPPROTO_ASYNC)
                 * wait for port to start
                 */
                while (mp->mp_proto != MPPROTO_ASYNC)
-                       sleep((caddr_t)&tp->t_canq, TTIPRI);
+                       if (error = tsleep((caddr_t)&tp->t_canq,
+                           TTIPRI | PCATCH, ttopen, 0))
+                               goto bad;
                ttsetwater(tp);
                mp->mp_flags &= ~MP_PROGRESS;
        }
                ttsetwater(tp);
                mp->mp_flags &= ~MP_PROGRESS;
        }
-       while (!(mode&O_NONBLOCK) && !(tp->t_cflag&CLOCAL) &&  
-              (tp->t_state & TS_CARR_ON) == 0) {
-               sleep((caddr_t)&tp->t_rawq, TTIPRI);
+       while ((mode&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 &&  
+           (tp->t_state & TS_CARR_ON) == 0) {
+               if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
+                   ttopen, 0))
+                       goto bad;
                /*
                 * a mpclose() might have disabled port. if so restart
                 */
                /*
                 * a mpclose() might have disabled port. if so restart
                 */
@@ -283,7 +307,7 @@ mpclose(dev, flag)
        register struct tty *tp;
        register struct mpport *mp;
        register struct mpevent *ev;
        register struct tty *tp;
        register struct mpport *mp;
        register struct mpevent *ev;
-       int s, port, unit, error;
+       int s, port, unit, error = 0;
        struct mblok *mb;
 
        unit = minor(dev);
        struct mblok *mb;
 
        unit = minor(dev);
@@ -299,11 +323,14 @@ mpclose(dev, flag)
                        return (0);
                }
                while (mp->mp_flags & MP_PROGRESS)
                        return (0);
                }
                while (mp->mp_flags & MP_PROGRESS)
-                       sleep((caddr_t)&tp->t_canq, TTIPRI);
+                       if (error = tsleep((caddr_t)&tp->t_canq,
+                           TTIPRI | PCATCH, ttclos, 0)) {
+                               splx(s);
+                               return (error);
+                       }
        }
        }
-       error = 0;
        mp->mp_flags |= MP_PROGRESS;
        mp->mp_flags |= MP_PROGRESS;
-       (*linesw[tp->t_line].l_close)(tp);
+       (*linesw[tp->t_line].l_close)(tp, flag);
        ev = mp_getevent(mp, unit, 1);
        if (ev == 0) {
                error = ENOBUFS;
        ev = mp_getevent(mp, unit, 1);
        if (ev == 0) {
                error = ENOBUFS;
@@ -315,13 +342,14 @@ mpclose(dev, flag)
        else
                mpmodem(unit, MMOD_ON);
        mpcmd(ev, EVCMD_CLOSE, 0, mb, port);
        else
                mpmodem(unit, MMOD_ON);
        mpcmd(ev, EVCMD_CLOSE, 0, mb, port);
-       ttyclose(tp);
+       error = ttyclose(tp);
 out:
        if (mp->mp_flags & MP_REMBSY)
                mpclean(mb, port);
        else
 out:
        if (mp->mp_flags & MP_REMBSY)
                mpclean(mb, port);
        else
-               while (mp->mp_flags & MP_PROGRESS)
-                       sleep((caddr_t)&tp->t_canq,TTIPRI);
+               while (mp->mp_flags & MP_PROGRESS && error == 0)
+                       error = tsleep((caddr_t)&tp->t_canq, TTIPRI | PCATCH,
+                           ttclos, 0);
        splx(s);
        return (error);
 }
        splx(s);
        return (error);
 }
@@ -385,11 +413,14 @@ mpioctl(dev, cmd, data, flag)
        case TIOCCBRK:                  /* clear break */
                s = spl8();
                while (mp->mp_flags & MP_IOCTL) {
        case TIOCCBRK:                  /* clear break */
                s = spl8();
                while (mp->mp_flags & MP_IOCTL) {
-                       sleep((caddr_t)&tp->t_canq, TTIPRI);
+                       if (error = tsleep((caddr_t)&tp->t_canq,
+                           TTIPRI | PCATCH, ttyout, 0)) {
+                               splx(s);
+                               return (error);
+                       }
                        if (mp->mp_proto != MPPROTO_ASYNC) {
                        if (mp->mp_proto != MPPROTO_ASYNC) {
-                               mp->mp_flags &= ~MP_IOCTL;
                                splx(s);
                                splx(s);
-                               return(ENXIO);
+                               return (ENXIO);
                        }
                }
                ev = mp_getevent(mp, unit, 0);
                        }
                }
                ev = mp_getevent(mp, unit, 0);
@@ -1335,8 +1366,6 @@ mpdlclose(dev)
        return (0);
 }
 
        return (0);
 }
 
-int    mpdltimeout();
-
 /* ARGSUSED */
 mpdlioctl(dev, cmd, data, flag)
        dev_t dev;
 /* ARGSUSED */
 mpdlioctl(dev, cmd, data, flag)
        dev_t dev;
@@ -1344,11 +1373,11 @@ mpdlioctl(dev, cmd, data, flag)
 {
        register struct mblok *mb;
        register struct mpdl *dl;
 {
        register struct mblok *mb;
        register struct mpdl *dl;
-       int unit, error, s, i;
+       int unit, error = 0, s, i;
 
        mb = mp_softc[unit=MPUNIT(minor(dev))].ms_mb;
        if (mb == 0)
 
        mb = mp_softc[unit=MPUNIT(minor(dev))].ms_mb;
        if (mb == 0)
-               return (EEXIST);
+                return (EEXIST);
        dl = &mb->mb_dl;
        error = 0;
        switch (cmd) {
        dl = &mb->mb_dl;
        error = 0;
        switch (cmd) {
@@ -1381,8 +1410,14 @@ mpdlioctl(dev, cmd, data, flag)
                error = mpdlwait(dl);
                break;
        case MPIOSTARTDL:
                error = mpdlwait(dl);
                break;
        case MPIOSTARTDL:
+               s = spl8();
                while (mpdlbusy)
                while (mpdlbusy)
-                       sleep((caddr_t)&mpdlbusy, PZERO+1);
+                       if (error = tsleep((caddr_t)&mpdlbusy,
+                           (PZERO+1) | PCATCH, devioc, 0))
+                               break;
+               splx(s);
+               if (error)
+                       break;
                mpdlbusy++;
                /* initialize the downloading interface */
                mpbogus.magic = MPMAGIC;
                mpdlbusy++;
                /* initialize the downloading interface */
                mpbogus.magic = MPMAGIC;
@@ -1400,20 +1435,13 @@ mpdlioctl(dev, cmd, data, flag)
                mb->mb_diagswitch[1] = 'P';
                s = spl8();
                *(u_short *)mpinfo[unit]->ui_addr = 2;
                mb->mb_diagswitch[1] = 'P';
                s = spl8();
                *(u_short *)mpinfo[unit]->ui_addr = 2;
-               timeout(mpdltimeout, (caddr_t)mb, 30*hz);
-               sleep((caddr_t)&mb->mb_status, PZERO+1);
+               error = tsleep((caddr_t)&mb->mb_status, (PZERO+1) | PCATCH,
+                   devio, 30*hz);
                splx(s);
                splx(s);
-               if (mb->mb_status == MP_DLOPEN) {
-                       untimeout(mpdltimeout, (caddr_t)mb);
-               } else if (mb->mb_status == MP_DLTIME) {
-                       mpbogus.status = 0;
+               if (error == EWOULDBLOCK)
                        error = ETIMEDOUT;
                        error = ETIMEDOUT;
-               } else {
+               if (error)
                        mpbogus.status = 0;
                        mpbogus.status = 0;
-                       error = ENXIO;
-                       log(LOG_ERR, "mp%d: start download: unknown status %x",
-                           unit, mb->mb_status);
-               }
                bzero((caddr_t)mb->mb_port, sizeof (mb->mb_port));
                break;
        case MPIORESETBOARD:
                bzero((caddr_t)mb->mb_port, sizeof (mb->mb_port));
                break;
        case MPIORESETBOARD:
@@ -1503,14 +1531,6 @@ mpdlintr(mpcc)
        }
 }
 
        }
 }
 
-mpdltimeout(mp)
-       struct mblok *mp;
-{
-
-       mp->mb_status = MP_DLTIME;
-       wakeup((caddr_t)&mp->mb_status);
-}
-
 /* 
  * Wait for a transfer to complete or a timeout to occur.
  */
 /* 
  * Wait for a transfer to complete or a timeout to occur.
  */
@@ -1522,9 +1542,12 @@ mpdlwait(dl)
        s = spl8();
        dl->mpdl_status = EVSTATUS_GO;
        while (dl->mpdl_status != EVSTATUS_FREE) {
        s = spl8();
        dl->mpdl_status = EVSTATUS_GO;
        while (dl->mpdl_status != EVSTATUS_FREE) {
-               sleep((caddr_t)&dl->mpdl_status, PZERO+1);
+               error = tsleep((caddr_t)&dl->mpdl_status, (PZERO+1) | PCATCH,
+                   devout, 0);
                if (mpdlerr == MP_DLERROR)
                        error = EIO;
                if (mpdlerr == MP_DLERROR)
                        error = EIO;
+               if (error)
+                       break;
        }
        splx(s);
        return (error);
        }
        splx(s);
        return (error);