BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / vax / uba / np.c
index 2fe6027..3ed1211 100644 (file)
@@ -1,9 +1,48 @@
-/*
+/*-
  * Copyright (c) 1986 MICOM-Interlan, Inc., Boxborough Mass
  * Copyright (c) 1986 MICOM-Interlan, Inc., Boxborough Mass
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ *     @(#)np.c        7.10 (Berkeley) 5/9/91
+ */
+
+/*
+ * From:
+ *     np.c version 1.5
+ *
+ *     This version retrieved: 8/18/86 @ 18:58:54
+ *         This delta created: 8/18/86 @ 18:19:24
+ *
+ *     static          char    *SCCSID = "@(#)np.c     1.5";
  *
  *
- *     @(#)np.c        7.1 (Berkeley) %G%
  */
 
                /******************************************
  */
 
                /******************************************
  * control functions are accessed via npioctl() by the NP support utilities.
  */
 
  * control functions are accessed via npioctl() by the NP support utilities.
  */
 
+/*
+ * Modification History:
+ * 4/9/86 DDW Removed pseudo-driver initialization flag resets from NpReset
+ * 5/28/86 CJM Changed iodone() to wakeup() in NpProcQueue().
+ *
+ */
 
 /*
  * Include Files
 
 /*
  * Include Files
 
 #include "np.h"
 #if NNP > 0
 
 #include "np.h"
 #if NNP > 0
-#include "param.h"
-#include "buf.h"
-#include "signal.h"
-#include "systm.h"
-#include "dir.h"
-#include "user.h"
-#include "proc.h"
-#include "uio.h"
-#include "errno.h"
-
-#include "../vaxuba/ubavar.h"
-#include "../vaxuba/npreg.h"
-
+#include "sys/param.h"
+#include "sys/buf.h"
+#include "sys/conf.h"
+#include "sys/ubavar.h"
+#include "sys/signal.h"
+#include "sys/systm.h"
+#include "sys/user.h"
+#include "sys/proc.h"
+#include "sys/uio.h"
+#include "sys/errno.h"
+#include "sys/ioctl.h"
+
+#include "../uba/npreg.h"
+
+#define b_uio b_forw
+#define b_rp  av_back
 /*
  * Global variables for pseudo-drivers.
  */
 
 /*
  * Global variables for pseudo-drivers.
  */
 
-int WnInitFlag;
-int IsInitFlag;
+int WnInitFlag = 0;
+int IsInitFlag = 0;
+int (*IxAttach)();
+int (*IxReset)();
 
 /*
  * Debugging level.
 
 /*
  * Debugging level.
@@ -84,6 +134,11 @@ static struct npconn npcnxtab[NNP][NNPCNN];
 
 static struct npreq reqhdr[NNP];
 
 
 static struct npreq reqhdr[NNP];
 
+/* Require for diagnostic packages */
+
+typedef struct npreq *reqptr;
+reqptr np_mapreq[NNP];
+
 /* The request structures, one pool per board */
 
 static struct npreq npreqs[NNP][NUMCQE];
 /* The request structures, one pool per board */
 
 static struct npreq npreqs[NNP][NUMCQE];
@@ -107,6 +162,7 @@ static unsign16 npvectors[NNP];
 struct uba_driver npdriver =
     { npprobe, 0, npattach, 0, npstd, "np", npdinfo };
 struct buf     np_tab[NNP];
 struct uba_driver npdriver =
     { npprobe, 0, npattach, 0, npstd, "np", npdinfo };
 struct buf     np_tab[NNP];
+static unsigned long np_icount[NNP];
 
 
 /*
 
 
 /*
@@ -117,8 +173,6 @@ struct npreq * NpGetReq();
 struct npmaster        *NpBoardChange();
 int NpTimer();
 struct CQE * NpRemCQE();
 struct npmaster        *NpBoardChange();
 int NpTimer();
 struct CQE * NpRemCQE();
-int (*IxAttach)();
-int (*IxReset)();
 
 extern struct user u;
 \f
 
 extern struct user u;
 \f
@@ -291,7 +345,6 @@ int flag;
 
        rp->intr = (int (*)())0;        /* Do not call interrupt routine */
        rp->bufoffset = 0;              /* Offset into data buffer */
 
        rp->intr = (int (*)())0;        /* Do not call interrupt routine */
        rp->bufoffset = 0;              /* Offset into data buffer */
-       rp->flags = NPCLEAR;            /* Clear flags */
        rp->procp = u.u_procp;  /* Process structure for this user */
 
        /* Copy in user's argument to ioctl() call */
        rp->procp = u.u_procp;  /* Process structure for this user */
 
        /* Copy in user's argument to ioctl() call */
@@ -398,13 +451,32 @@ int flag;
                if(error) break;
                error = NpSetXeqAddr(mp,(caddr_t)INETBOOT);
                break;
                if(error) break;
                error = NpSetXeqAddr(mp,(caddr_t)INETBOOT);
                break;
+           case NPSETLAST:
+               if (usrarg)
+                       mp->flags &= ~LSTCMD;
+               else
+                       mp->flags |= LSTCMD;
+               break;
+           case NPCLRICNT:
+               np_icount[unit] = NPCLEAR;
+               break;
+           case NPGETICNT:
+               usrarg = np_icount[unit];
+               error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg));
+               break;
+           case NPGETIVEC:
+               usrarg = mp->vector;
+               error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg));
+               break;
+           case NPMAPMEM:
+               error = NpMem(mp, rp, *addr);
+               break;
            default:
                printf("Bad Maintenance command: %d!\n",cmd);
                error = EIO;
                break;
            default:
                printf("Bad Maintenance command: %d!\n",cmd);
                error = EIO;
                break;
-
        }
        }
-       if((cmd != NPRESET) && (cmd != NPINIT))
+       if((cmd != NPRESET) && (cmd != NPINIT) && (cmd != NPMAPMEM))
                NpFreeReq(mp->reqtab,rp);
 
        if(NpDebug & DEBENTRY)
                NpFreeReq(mp->reqtab,rp);
 
        if(NpDebug & DEBENTRY)
@@ -420,6 +492,7 @@ npstart(mp)
 register struct npmaster *mp;
 {
 
 register struct npmaster *mp;
 {
 
+       register struct uio     *uio;
        register struct buf     *bp;
        register struct npreq   *rp;
 
        register struct buf     *bp;
        register struct npreq   *rp;
 
@@ -432,7 +505,12 @@ register struct npmaster *mp;
                np_tab[mp->unit].b_active = 0;
                return;
        }
                np_tab[mp->unit].b_active = 0;
                return;
        }
-       if((rp = (struct npreq *)(bp->av_back)) == (struct npreq *)0) {
+       if((rp = (struct npreq *)(bp->b_rp)) == (struct npreq *)0) {
+               bp->b_flags = B_ERROR;
+               iodone(bp);
+               return;
+       }
+       if ((uio = (struct uio *)bp->b_uio) == (struct uio *)0) {
                bp->b_flags = B_ERROR;
                iodone(bp);
                return;
                bp->b_flags = B_ERROR;
                iodone(bp);
                return;
@@ -440,18 +518,17 @@ register struct npmaster *mp;
        np_tab[mp->unit].b_active = 1;
 
        if(NpDebug & DEBIO)
        np_tab[mp->unit].b_active = 1;
 
        if(NpDebug & DEBIO)
-               printf("NP IO src %x dst = %x cnt = %x\n",bp->b_un.b_addr,bp->b_blkno << DEV_BSHIFT,bp->b_bcount);
+               printf("NP IO src %x dst = %x cnt = %x\n", bp->b_un.b_addr,
+                       uio->uio_offset, bp->b_bcount);
 
        /* Send the request to the board via the CSR0 command interface */
 
        if(bp->b_flags & B_READ) 
 
        /* Send the request to the board via the CSR0 command interface */
 
        if(bp->b_flags & B_READ) 
-
-               error = NPIO(mp,(paddr_t)((long)bp->b_blkno << DEV_BSHIFT),(paddr_t)(rp->bufaddr),
-           bp->b_bcount,(bp->b_flags & B_READ)); 
-
+               error = NPIO(mp, (paddr_t)uio->uio_offset, (paddr_t)rp->bufaddr,
+                       bp->b_bcount, (bp->b_flags & B_READ)); 
        else
        else
-               error = NPIO(mp,(paddr_t)(rp->bufaddr),(paddr_t)((long)bp->b_blkno << DEV_BSHIFT),
-           bp->b_bcount,(bp->b_flags & B_READ)); 
+               error = NPIO(mp, (paddr_t)rp->bufaddr, (paddr_t)uio->uio_offset,
+                       bp->b_bcount, (bp->b_flags & B_READ)); 
        
 
        /* Check return from I/O */
        
 
        /* Check return from I/O */
@@ -459,7 +536,6 @@ register struct npmaster *mp;
        if(error) {
                bp->b_flags |= B_ERROR;
                np_tab[mp->unit].b_actf = bp->av_forw;
        if(error) {
                bp->b_flags |= B_ERROR;
                np_tab[mp->unit].b_actf = bp->av_forw;
-
                if(NpDebug & DEBIO)
                        printf("NPIO return error: b_flags is %x \n",bp->b_flags);
                iodone(bp);
                if(NpDebug & DEBIO)
                        printf("NPIO return error: b_flags is %x \n",bp->b_flags);
                iodone(bp);
@@ -470,7 +546,7 @@ register struct npmaster *mp;
 
 }
 /*
 
 }
 /*
- * npstratagey - the strategy routine
+ * npstrategy - the strategy routine
  */
 
 npstrategy(bp)
  */
 
 npstrategy(bp)
@@ -486,7 +562,8 @@ register struct buf *bp;
                printf("npstrategy\n");
        if(NpDebug & DEBIO)
                printf("flag = %x count = %x paddr = %x %x blkno = %x %x\n",
                printf("npstrategy\n");
        if(NpDebug & DEBIO)
                printf("flag = %x count = %x paddr = %x %x blkno = %x %x\n",
-                   bp->b_flags,bp->b_bcount,bp->b_un.b_addr,bp->b_un.b_addr,bp->b_blkno,bp->b_blkno);
+                   bp->b_flags, bp->b_bcount, bp->b_un.b_addr, bp->b_un.b_addr,
+                   bp->b_blkno,bp->b_blkno);
 
        /* get master structure */
 
 
        /* get master structure */
 
@@ -514,8 +591,7 @@ register struct buf *bp;
 
        rp->bufoffset = 0;              /* This is the start of the buffer */
        ip = &np_tab[mp->unit];
 
        rp->bufoffset = 0;              /* This is the start of the buffer */
        ip = &np_tab[mp->unit];
-       bp->av_forw = (struct buf *)0;
-       bp->av_back = (struct buf *)rp;
+       bp->b_rp = (struct buf *)rp;
 
        rp->flags |= KERNREQ;           /* Mark it as kernel so not to map */
 
 
        rp->flags |= KERNREQ;           /* Mark it as kernel so not to map */
 
@@ -585,12 +661,14 @@ npread(dev,uio)
 dev_t dev;
 struct uio *uio;
 {
 dev_t dev;
 struct uio *uio;
 {
+       struct buf *bp;
+       bp = &npcnxtab[NPUNIT(dev)][NPCONN(dev)].np_rbuf;
 
        if(NpDebug & DEBENTRY)
                printf("in npread\n");
 
 
        if(NpDebug & DEBENTRY)
                printf("in npread\n");
 
-       return(physio(npstrategy,&npcnxtab[NPUNIT(dev)][NPCONN(dev)].np_rbuf,dev,B_READ ,nptrim,uio));
-
+       bp->b_uio = (struct buf *)uio;
+       return(physio(npstrategy,bp,dev,B_READ ,nptrim,uio));
 }
 
 /*
 }
 
 /*
@@ -607,10 +685,11 @@ struct uio *uio;
        if(NpDebug & DEBENTRY)
                printf("in npwrite \n");
 
        if(NpDebug & DEBENTRY)
                printf("in npwrite \n");
 
+       bp->b_uio = (struct buf *)uio;
        return(physio(npstrategy,bp,dev,B_WRITE ,nptrim,uio));
 }
        return(physio(npstrategy,bp,dev,B_WRITE ,nptrim,uio));
 }
-/*
 
 
+/*
  * npreset - called as result of a UNIBUS reset.
  */
 
  * npreset - called as result of a UNIBUS reset.
  */
 
@@ -623,6 +702,8 @@ int uban;
        register struct uba_device *ui;
        int i;
 
        register struct uba_device *ui;
        int i;
 
+       if(NpDebug & DEBENTRY)
+               printf("npreset(ubareset)\n");
        for(i = 0; i < NNP; i++) {
 
                if(((ui = npdinfo[i]) == (struct uba_device *)NULL) ||
        for(i = 0; i < NNP; i++) {
 
                if(((ui = npdinfo[i]) == (struct uba_device *)NULL) ||
@@ -630,11 +711,21 @@ int uban;
                        continue;
 
                mp = &npmasters[i];
                        continue;
 
                mp = &npmasters[i];
-               mp->iomapbase = 0;
-               NpReset(mp,0);
+
+               /* Get a Request structure */
+
+               while((rp = NpGetReq(mp->reqtab)) == NULL) {
+                       mp->reqtab->flags |= WANTREQ;
+                       sleep((caddr_t)(mp->reqtab),PZERO -1);
+               }
+
+               NpReset(mp,rp);
        }
        }
+       if(NpDebug & DEBENTRY)
+               printf("npreset(ubareset)...\n");
 }
 
 }
 
+
 /*
  * Nppoll looks for work by polling each board. He goes to sleep if there are
  * no outstanding requests for him but reminds the board that he's there when
 /*
  * Nppoll looks for work by polling each board. He goes to sleep if there are
  * no outstanding requests for him but reminds the board that he's there when
@@ -706,7 +797,9 @@ caddr_t     addr;
 
                NpState |= ICPAVAIL;
 
 
                NpState |= ICPAVAIL;
 
-               sleep((caddr_t)&NpState, PZERO + 1);
+               if (error = tsleep((caddr_t)&NpState, (PZERO + 1) | PCATCH,
+                   devio, 0))
+                       return (error);
 
                if(NpDebug & DEBMAINT)
                        printf("wakeup in NpPoll\n");
 
                if(NpDebug & DEBMAINT)
                        printf("wakeup in NpPoll\n");
@@ -731,6 +824,9 @@ int unit;
        if(NpDebug & DEBINIT)
                printf("SW reset on unit %d.\n",unit);
 
        if(NpDebug & DEBINIT)
                printf("SW reset on unit %d.\n",unit);
 
+       np_icount[unit] = NPCLEAR;
+       np_mapreq[unit] = (struct npreq *) NPCLEAR;
+
        /* Initialize master structure pointer for this unit */
 
        mp = &npmasters[unit];
        /* Initialize master structure pointer for this unit */
 
        mp = &npmasters[unit];
@@ -849,10 +945,10 @@ int unit;
        reqhdr[unit].free = &npreqs[unit][0];
 
        for(j = 0; j < NUMCQE; j++) {
        reqhdr[unit].free = &npreqs[unit][0];
 
        for(j = 0; j < NUMCQE; j++) {
-
                npreqs[unit][j].free = &npreqs[unit][j + 1];
                npreqs[unit][j].element = &npsp->elements[j];
                npreqs[unit][j].forw = npreqs[unit][j].back = (struct npreq *)NULL;
                npreqs[unit][j].free = &npreqs[unit][j + 1];
                npreqs[unit][j].element = &npsp->elements[j];
                npreqs[unit][j].forw = npreqs[unit][j].back = (struct npreq *)NULL;
+               npreqs[unit][j].flags = NPCLEAR;
        }
        npreqs[unit][--j].free = &reqhdr[unit];
 
        }
        npreqs[unit][--j].free = &reqhdr[unit];
 
@@ -866,6 +962,7 @@ int unit;
 
        if(NpDebug & DEBENTRY)
                printf("SW_Init...\n");
 
        if(NpDebug & DEBENTRY)
                printf("SW_Init...\n");
+       return(0);
 }
 \f
 /*
 }
 \f
 /*
@@ -906,21 +1003,6 @@ int unit;
                }
 
 
                }
 
 
-#ifdef mc500
-       if(setjmp(u.u_tsav) == 0) {
-               u.u_nofault = TRUE;
-               status = RCSR1(mp->iobase);
-               u.u_nofault = FALSE;
-       }
-       else {
-               np__addr[unit] = 0;
-               mp->flags |= BADBOARD;
-               u.u_error = ENXIO;
-               printf("\nNP100 Unit %x not here!\n",unit);
-               return(0);
-       }
-#endif
-
        if(NpDebug & DEBENTRY)
                printf("Resetting the NP100 Board at %x\n",mp->iobase);
 
        if(NpDebug & DEBENTRY)
                printf("Resetting the NP100 Board at %x\n",mp->iobase);
 
@@ -957,7 +1039,6 @@ int unit;
 
        if(!(RCSR1(mp->iobase) & NPHOK)) {
                mp->flags |= BADBOARD;
 
        if(!(RCSR1(mp->iobase) & NPHOK)) {
                mp->flags |= BADBOARD;
-               u.u_error = EIO;
                printf("NP100 Unit %d Failed diagnostics!\n",unit);
                printf("Status from CSR0: %x.\n",status);
                return(EIO);
                printf("NP100 Unit %d Failed diagnostics!\n",unit);
                printf("Status from CSR0: %x.\n",status);
                return(EIO);
@@ -983,9 +1064,11 @@ int unit;
                printf("npintr on unit %d!\n",unit);
 
        mp = &npmasters[unit];
                printf("npintr on unit %d!\n",unit);
 
        mp = &npmasters[unit];
+       np_icount[unit]++;
 
        if(NpDebug & DEBINTR)
 
        if(NpDebug & DEBINTR)
-               printf("npintr mp->flags = %x\n",mp->flags);
+               printf("npintr mp->flags = %x  interupt count = %x\n",
+                       mp->flags, np_icount[unit]);
 
        /* Wake up anyone sleeping on a CSR0 Command */
 
 
        /* Wake up anyone sleeping on a CSR0 Command */
 
@@ -1033,11 +1116,9 @@ int unit;
 
        if(!(mp->flags & AVAILABLE)) {
 
 
        if(!(mp->flags & AVAILABLE)) {
 
-               if((mp->shmemp->statblock.sb_dpm) && (!(mp->flags & BRDRESET))){
+               if((mp->shmemp->statblock.sb_dpm) && (!(mp->flags & BRDRESET)))
 
                        mp->flags = AVAILABLE;
 
                        mp->flags = AVAILABLE;
-                       printf("\nNP100 unit #%d available!\n",mp->unit);
-               }
        }
 
        /* Honor service requests from the device */
        }
 
        /* Honor service requests from the device */
@@ -1116,21 +1197,29 @@ struct npmaster *mp;
        register struct CQE *ep;
        register struct npreq *rp;
        register int base;
        register struct CQE *ep;
        register struct npreq *rp;
        register int base;
+       int s;
 
        if(NpDebug & DEBENTRY)
                printf("NpProcQueue\n");
 
        cqp = &mp->shmemp->hostcq;      /* Command Queue pointer */
 
 
        if(NpDebug & DEBENTRY)
                printf("NpProcQueue\n");
 
        cqp = &mp->shmemp->hostcq;      /* Command Queue pointer */
 
-       if(cqp->scanflag & ON)
+       s = spl5();
+       if(mp->flags & SCANNING) {
+               splx(s);
                return;
                return;
+       }
+       mp->flags |= SCANNING;
+       splx(s);
 
 
-       else cqp->scanflag | = ON;
+       cqp->scanflag | = ON;
 
        base = (int)mp->shmemp;         /* Shared memory base address */
 
 
        base = (int)mp->shmemp;         /* Shared memory base address */
 
-       while(cqp->scanflag & ON) {
+       while(1) {
 
 
+               cqp->scanflag |= ON;
+               cqp->chngflag &= ~ON;
                while(ep = NpRemCQE(cqp,base)) {
 
                        rp = ep->cqe_reqid;
                while(ep = NpRemCQE(cqp,base)) {
 
                        rp = ep->cqe_reqid;
@@ -1172,28 +1261,29 @@ struct npmaster *mp;
                                /* Call interrupt routine */
 
                                (*rp->intr)(mp,rp);
                                /* Call interrupt routine */
 
                                (*rp->intr)(mp,rp);
-
                        }
                        else {
 
                        if(NpDebug & DEBINTR)
                                printf("waking up %x\n",rp);
 
                        }
                        else {
 
                        if(NpDebug & DEBINTR)
                                printf("waking up %x\n",rp);
 
-                               if(rp->flags & NPUIO)
+                               /* if(rp->flags & NPUIO)
                                        iodone(&rp->buf);
                                else    wakeup((caddr_t) (rp)); /* Awaken */
 
                                        iodone(&rp->buf);
                                else    wakeup((caddr_t) (rp)); /* Awaken */
 
+                               wakeup((caddr_t)(rp));  /* Awaken */
                        if(NpDebug & DEBINTR)
                                printf("AWAKE\n");
                        }
                        if(NpDebug & DEBINTR)
                                printf("AWAKE\n");
                        }
-
                }
 
                }
 
+               cqp->scanflag &= ~ON;
                if(!(cqp->chngflag & ON))
                if(!(cqp->chngflag & ON))
-                       cqp->scanflag &= ~ON;
+                       break;
 
        }
 
 
        }
 
+       mp->flags &= ~SCANNING;
        if(NpDebug & DEBENTRY)
                printf("NpProcQueue...\n");
 }
        if(NpDebug & DEBENTRY)
                printf("NpProcQueue...\n");
 }
@@ -1277,6 +1367,11 @@ struct npreq *head;
 
        p = head->free;
        head->free = p->free;
 
        p = head->free;
        head->free = p->free;
+       if (p->flags & REQALOC)
+               printf("GetReq: Req %x already allocated\n", p);
+       p->flags &= WANTREQ;
+       if (p != head)
+               p->flags |= REQALOC;
        return(p==head ? (struct npreq *)NULL : p);
 }
 
        return(p==head ? (struct npreq *)NULL : p);
 }
 
@@ -1287,13 +1382,29 @@ struct npreq *head;
 NpFreeReq(head,nprp)
 register struct npreq *head, *nprp;
 {
 NpFreeReq(head,nprp)
 register struct npreq *head, *nprp;
 {
+       int s;
 
        if(NpDebug & DEBREQ)
                printf("NpFreeReq, head is %x rp is %x\n",head,nprp);
 
 
        if(NpDebug & DEBREQ)
                printf("NpFreeReq, head is %x rp is %x\n",head,nprp);
 
+       if (nprp == NULL) {
+               printf("FREEREQ: attempt to free null pointer\n");
+               return;
+       }
+       if (!(nprp->flags & REQALOC)) {
+               printf("FREEREQ: attempt to free unallocated request %x\n",
+                       nprp);
+               return;
+       }
+       if (nprp->flags & REQUSE)
+               printf("FREEREQ: freeing unremoved request %x\n", nprp);
+
+       s = spl5();
        nprp->forw = nprp->back = (struct npreq *)NULL;
        nprp->free = head->free;
        head->free = nprp;
        nprp->forw = nprp->back = (struct npreq *)NULL;
        nprp->free = head->free;
        head->free = nprp;
+       nprp->flags &= ~REQALOC;
+       splx(s);
 
        /* Wake up any processes waiting for a request structure */
 
 
        /* Wake up any processes waiting for a request structure */
 
@@ -1330,13 +1441,10 @@ struct npmaster *mp;
        if(*temp) {                     /* Should never happen */
 
                printf("No more room on Command Queue!\n");
        if(*temp) {                     /* Should never happen */
 
                printf("No more room on Command Queue!\n");
-               u.u_error = EIO;
                return;
        }
        else *temp = cqe_offset;        /* Enter this request's offset */
 
                return;
        }
        else *temp = cqe_offset;        /* Enter this request's offset */
 
-       cqp->chngflag |= ON;            /* Set change flag unconditionally */
-
        /* Update cqe_add where next request is to be added */
 
        cqp->cq_add += sizeof(unsign16);
        /* Update cqe_add where next request is to be added */
 
        cqp->cq_add += sizeof(unsign16);
@@ -1344,6 +1452,8 @@ struct npmaster *mp;
        if(cqp->cq_add == cqp->cq_wrap) /* Wrap if necessary */
                cqp->cq_add = (unsign16)((int)cqp->cq_cqe - base);
 
        if(cqp->cq_add == cqp->cq_wrap) /* Wrap if necessary */
                cqp->cq_add = (unsign16)((int)cqp->cq_cqe - base);
 
+       cqp->chngflag |= ON;            /* Set change flag unconditionally */
+
        /* Interrupt the Board if his scan flag isn't on */
 
        if(!(cqp->scanflag & ON))
        /* Interrupt the Board if his scan flag isn't on */
 
        if(!(cqp->scanflag & ON))
@@ -1402,17 +1512,21 @@ int base;
 NpAddReq(head,rp)
 register struct npreq *head, *rp;
 {
 NpAddReq(head,rp)
 register struct npreq *head, *rp;
 {
+       int s;
 
 
-       if(NpDebug & DEBENTRY)
-               printf("NpAddReq\n");
-
-       if(NpDebug & DEBREQ)
+       if (NpDebug & (DEBENTRY|DEBREQ))
                printf("NpAddReq: %x\n",rp);
 
                printf("NpAddReq: %x\n",rp);
 
+       if (rp->flags & REQUSE)
+               printf("ADDREQ: Request %x allready in use\n", rp);
+
+       s = spl7();
        rp->forw = head->forw;
        rp->forw->back = rp;
        rp->back = head;
        head->forw = rp;
        rp->forw = head->forw;
        rp->forw->back = rp;
        rp->back = head;
        head->forw = rp;
+       rp->flags |= REQUSE;
+       splx(s);
 
        if(NpDebug & DEBENTRY)
                printf("NpAddReq...\n");
 
        if(NpDebug & DEBENTRY)
                printf("NpAddReq...\n");
@@ -1426,15 +1540,29 @@ register struct npreq *head, *rp;
 NpRemReq(rp)
 register struct npreq *rp;
 {
 NpRemReq(rp)
 register struct npreq *rp;
 {
+       int s;
 
 
-       if(NpDebug & DEBENTRY)
-               printf("NpRemReq\n");
-
-       if(NpDebug & DEBREQ)
+       if (NpDebug & (DEBENTRY|DEBREQ))
                printf("NpRemReq: %x\n",rp);
 
                printf("NpRemReq: %x\n",rp);
 
+       if (rp == NULL) {
+               printf("REMREQ: null pointer removal requested\n");
+               return;
+       }
+       if (!(rp->flags & REQUSE)) {
+               printf("REMREQ: trying to rem unused req %x\n", rp);
+               return;
+       }
+       if (!(rp->flags & REQALOC)) {
+               printf("REMREQ: trying to rem unallocated req %x\n", rp);
+               return;
+       }
+               
+       s = spl7();
        rp->back->forw = rp->forw;
        rp->forw->back = rp->back;
        rp->back->forw = rp->forw;
        rp->forw->back = rp->back;
+       rp->flags &= ~REQUSE;
+       splx(s);
 
        if(NpDebug & DEBENTRY)
                printf("NpRemReq...\n");
 
        if(NpDebug & DEBENTRY)
                printf("NpRemReq...\n");
@@ -1639,13 +1767,15 @@ int dir;                /* Direction  READ/WRITE */
                printf("I/O count = %d \n",count);
        }
 
                printf("I/O count = %d \n",count);
        }
 
-       cmd_block.cmd_word = NPCBI | NPLST | (CBICNT + IOCNT);
+       cmd_block.cmd_word = NPCBI | (CBICNT + IOCNT);
        cmd_block.intlevel = mp->vector;
        cmd_block.shi_addr = HIWORD(src);
        cmd_block.slo_addr = LOWORD(src);
        cmd_block.dhi_addr = HIWORD(dest);
        cmd_block.dlo_addr = LOWORD(dest);
        cmd_block.count = count;
        cmd_block.intlevel = mp->vector;
        cmd_block.shi_addr = HIWORD(src);
        cmd_block.slo_addr = LOWORD(src);
        cmd_block.dhi_addr = HIWORD(dest);
        cmd_block.dlo_addr = LOWORD(dest);
        cmd_block.count = count;
+       if ((mp->flags & LSTCMD) == 0)
+               cmd_block.cmd_word |= NPLST;
        if(dir == B_READ)
                cmd_block.cmd_word |= NPDMP;
        else
        if(dir == B_READ)
                cmd_block.cmd_word |= NPDMP;
        else
@@ -1684,7 +1814,7 @@ struct npreq *curr_rp;
 
        mp->reqtab->reqcnt = 0;         /* Init request count */
 
 
        mp->reqtab->reqcnt = 0;         /* Init request count */
 
-       s = spl4();                     /* Disable interrupts */
+       s = spl5();                     /* Disable interrupts */
 
        /* Mark each active request as having an error and wake him up */
 
 
        /* Mark each active request as having an error and wake him up */
 
@@ -1694,9 +1824,10 @@ struct npreq *curr_rp;
 
                rp->flags |= (IOABORT | REQDONE);
                mp->reqtab->reqcnt++;
 
                rp->flags |= (IOABORT | REQDONE);
                mp->reqtab->reqcnt++;
-               if(rp->flags & NPUIO)
+               /* if(rp->flags & NPUIO)
                        iodone(&rp->buf);
                        iodone(&rp->buf);
-               else wakeup((caddr_t)rp);
+               else */
+               wakeup((caddr_t)rp);
        }
 
        if(NpDebug & DEBMAINT)
        }
 
        if(NpDebug & DEBMAINT)
@@ -1743,7 +1874,9 @@ struct npreq *rp;
                wakeup((caddr_t)&NpState);
 
                while(mp->reqtab->reqcnt)
                wakeup((caddr_t)&NpState);
 
                while(mp->reqtab->reqcnt)
-                       sleep((caddr_t)(&mp->reqtab),PZERO +1);
+                       if (error = tsleep((caddr_t)(&mp->reqtab),
+                           (PZERO + 1) | PCATCH, devio, 0))
+                               return (error);
 
                if(NpDebug & DEBMAINT)
                        printf("Reset:awoken by ICP senior!\n");
 
                if(NpDebug & DEBMAINT)
                        printf("Reset:awoken by ICP senior!\n");
@@ -1761,8 +1894,9 @@ struct npreq *rp;
                        printf("Reqcnt is %d.\n",mp->reqtab->reqcnt);
                }
 
                        printf("Reqcnt is %d.\n",mp->reqtab->reqcnt);
                }
 
-               sleep((caddr_t)(&mp->reqtab),PZERO +1);
-
+               if (error = tsleep((caddr_t)(&mp->reqtab),
+                   (PZERO + 1) | PCATCH, devio, 0))
+                       return (error);
        }
 
        /* Free up I/O Map registers if any allocated */
        }
 
        /* Free up I/O Map registers if any allocated */
@@ -1788,9 +1922,6 @@ struct npreq *rp;
 
        /* Initialize Pseudo-Drivers */
 
 
        /* Initialize Pseudo-Drivers */
 
-       WnInitFlag = 0;                 /* WN Pseudo-Driver */
-       IsInitFlag = 0;                 /* IS Pseudo-Driver */
-
        if (IxReset)
                (*IxReset)(mp->unit, mp->devp->ui_ubanum, rp);
 
        if (IxReset)
                (*IxReset)(mp->unit, mp->devp->ui_ubanum, rp);
 
@@ -1855,7 +1986,6 @@ unsign16 protocol;
        }
 
        rp->intr = (int (*)())0;        /* Do not call interrupt routine */
        }
 
        rp->intr = (int (*)())0;        /* Do not call interrupt routine */
-       rp->flags = NPCLEAR;
        rp->mapbase = 0;                /* Clear mapping information */
 
        ep = rp->element;               /* Handy pointer */
        rp->mapbase = 0;                /* Clear mapping information */
 
        ep = rp->element;               /* Handy pointer */
@@ -1877,7 +2007,7 @@ unsign16 protocol;
 
        NpAddReq(mp->reqtab,rp);        /* Queue onto active list */
 
 
        NpAddReq(mp->reqtab,rp);        /* Queue onto active list */
 
-       pri = spl4();                   /* Mask our interrupts */
+       pri = spl5();                   /* Mask our interrupts */
 
        NpAddCQE(ep,&mp->shmemp->devcq,mp); /* Add CQE to device's queue */
 
 
        NpAddCQE(ep,&mp->shmemp->devcq,mp); /* Add CQE to device's queue */
 
@@ -1990,7 +2120,11 @@ int      count;
        rp->buf.b_proc = rp->procp;
                
        rp->procp->p_flag |= SPHYSIO;
        rp->buf.b_proc = rp->procp;
                
        rp->procp->p_flag |= SPHYSIO;
+       if(NpDebug & DEBENTRY)
+               printf("vslock\n");
        vslock(addr,count);
        vslock(addr,count);
+       if(NpDebug & DEBENTRY)
+               printf("vslock...\n");
 
        rp->mapbase = ubasetup(mp->devp->ui_ubanum,&rp->buf,0);
 
 
        rp->mapbase = ubasetup(mp->devp->ui_ubanum,&rp->buf,0);
 
@@ -2037,7 +2171,7 @@ int i;
 
        cvec = (uba_hd[numuba].uh_lastiv -= 4); 
 
 
        cvec = (uba_hd[numuba].uh_lastiv -= 4); 
 
-#ifdef OLDBSD4_2
+#ifdef OLDBSD
        /* Find unit number from npstd[] by matching the csr address */
 
        csraddr = (u_short)((int)reg & 0x0FFFF);
        /* Find unit number from npstd[] by matching the csr address */
 
        csraddr = (u_short)((int)reg & 0x0FFFF);
@@ -2051,6 +2185,7 @@ int i;
        }
        if(i == NNP)
                printf("Couldn't find device in npstd[]!\n");
        }
        if(i == NNP)
                printf("Couldn't find device in npstd[]!\n");
+
 #else
        npvectors[ui->ui_unit] = cvec;
 #endif
 #else
        npvectors[ui->ui_unit] = cvec;
 #endif
@@ -2071,7 +2206,6 @@ register struct uba_device *ui;
                printf("In npattach, ui is %x.\n",ui);
 
        npinit(ui->ui_unit);
                printf("In npattach, ui is %x.\n",ui);
 
        npinit(ui->ui_unit);
-
        if (IxAttach)
                (*IxAttach)(ui);
 
        if (IxAttach)
                (*IxAttach)(ui);
 
@@ -2079,4 +2213,44 @@ register struct uba_device *ui;
                printf("npattach...\n");
 }
 
                printf("npattach...\n");
 }
 
+
+NpMem(mp, rp, uaddr)
+struct npmaster *mp;
+struct npreq *rp;
+unsigned long uaddr;
+{
+       struct np_mem mem;
+       register int error = 0;
+
+       if(NpDebug & DEBENTRY)
+               printf("npmem\n");
+
+       if (error = copyin(uaddr, &mem, sizeof(mem)))
+               return (error);
+
+       if (mem.mem_type == NP_SET) {
+               if (np_mapreq[mp->unit] != (struct npreq *)NPCLEAR)
+                       error = EBUSY;
+               else {
+                       error = NpMapMem(mp, rp, mem.mem_addr, mem.mem_count);
+                       if (error != 0) {
+                               np_mapreq[mp->unit] = rp;
+                               mem.mem_addr = rp->bufaddr;
+                       }
+               }
+       } else if (mem.mem_type == NP_USET) {
+               error = NpUnMapMem(mp, np_mapreq[mp->unit]);
+               NpFreeReq(mp->reqtab, rp);
+               NpFreeReq(mp->reqtab, np_mapreq[mp->unit]);
+               np_mapreq[mp->unit] = (struct npreq *)NPCLEAR;
+       } else 
+               error = EIO;
+
+       if (error != 0)
+               error = copyout(&mem, uaddr, sizeof(mem));
+
+       if(NpDebug & DEBENTRY)
+               printf("npmem...\n");
+       return (error);
+}
 #endif
 #endif