Bell 32V development
authorTom London <tbl@research.uucp>
Thu, 25 Jan 1979 01:47:54 +0000 (20:47 -0500)
committerTom London <tbl@research.uucp>
Thu, 25 Jan 1979 01:47:54 +0000 (20:47 -0500)
Work on file usr/src/sys/sys/v45lnk.c

Co-Authored-By: John Reiser <jfr@research.uucp>
Synthesized-from: 32v

usr/src/sys/sys/v45lnk.c [new file with mode: 0644]

diff --git a/usr/src/sys/sys/v45lnk.c b/usr/src/sys/sys/v45lnk.c
new file mode 100644 (file)
index 0000000..83bd407
--- /dev/null
@@ -0,0 +1,219 @@
+# include "../h/param.h"
+# include "../h/dir.h"
+# include "../h/user.h"
+# include "../h/proc.h"
+# include "../h/uba.h"
+# include "../h/buf.h"
+/*             */
+# define LNKADR (UBA0_DEV+0172410) /* DR11-B devive reg's */
+/*
+*  UBA0_DEV = 0x80018000
+*  LNKADR = 0x80027508
+*/
+/*  DA11-B  DR-11B Status & Command reg */
+# define ERR  0x8000  /*  error bit */
+# define NEX  0x4000  /*  non-existent memory */
+# define IIR  0x800  /*  Input Interrupt Request */
+# define ID  0x400  /*  Input direction */
+# define IM  0x200  /*  Input mode */
+# define CYCLE  0x100  /* Cycle */
+# define RDY  0x80  /* Ready */
+# define IE  0x40  /*  Interrupt Enable */
+# define OIR  8  /*  Output interrupt request */
+# define OD  4  /* Output direction */
+# define OM  2  /* output mode */
+# define GO  1  /* Go bit */
+/*     states  */
+# define CLOSED 0  /*  closed */
+# define  OPEN  1  /* open  */
+# define  S1  2  /* write state 1 */
+# define  S2  4  /* write state 2 */
+# define  R1  8  /* read state 1 */
+# define  R2  16  /* read state 2 */
+# define L_NOT 128  /*  send OIR to other end link */
+# define IPEND 256
+# define PREread  512  /*  'lnkmon' wait */
+# define L_MON 1024  /* 'lnkmon' decr V11opn */
+# define L_WAKE  2048
+# define BUSY (S1|S2|R1|R2)  /* i-o in progress for driver */
+# define S_ERR  0x8000
+/*             */
+# define  V11PRI  0
+# define BUFSIZ  512
+# define VSPEC  0100000
+/*             */
+struct lnkreg {
+       short drwc , drba , drst , drdb ;
+       } ;
+struct {
+       short state ;
+       struct buf *bp ;
+       } V11tab ;
+char V11opn ;
+/*             */
+V11open(dev,flag)
+{
+struct buf *geteblk() ;
+if (V11opn) {
+       u.u_error = EBUSY;
+       return;
+       }
+V11opn++;
+if (V11tab.bp == 0) /* grab system buffer */
+       V11tab.bp = geteblk() ;  /*  VAX call */
+((struct lnkreg *)LNKADR)->drst |= IE ;
+V11tab.state |= OPEN ;
+}
+/*             */
+V11close(dev,flag) /* called on last close only ! ! */
+{
+V11opn = 0;
+V11tab.state = CLOSED ;
+((struct lnkreg *)LNKADR)->drst = 0 ; /* IE off */
+if (V11tab.bp) brelse(V11tab.bp) ; /* release system buffer */
+V11tab.bp = 0 ;
+}
+/*             */
+V11write(dev)
+{
+register int i , j  , k ;
+/*  INIT clears OUTPUT DIR bit = transmitter */
+spl5() ;
+V11tab.state |= S1 ;
+/* setup for transmit */
+((struct lnkreg *)LNKADR)->drst &= ~(OD) ; /* 0 -> transmitter */
+spl0() ;
+i = uballoc(V11tab.bp->b_un.b_addr,BUFSIZ,1) ; /* get UBA map entry for
+       system buffer and set valid bit & BDP no. & BO bit & load map */
+j = i & 0x3ffff ; /* start map no. & byte offset */
+/* write loop, until done or error */
+while ((u.u_count > 0) && (u.u_error == 0)) {
+       iomove(V11tab.bp->b_un.b_addr,min(BUFSIZ,u.u_count),B_WRITE) ; /* move
+               data from user space to system buffer */
+       ((struct lnkreg *)LNKADR)->drwc = (-(BUFSIZ>>1)) ; /* word count */
+       ((struct lnkreg *)LNKADR)->drba = j ; /* map no. (SBI page) & byte offset */
+       spl5() ;
+       ((struct lnkreg *)LNKADR)->drst |= GO ; /* setup for transfer */
+       sleep(LNKADR,V11PRI) ; /* wait for transfer to finish(interrupt) */
+       spl0() ;
+       if (V11tab.state & S_ERR) {
+               u.u_error = ENXIO ;
+               V11tab.state &= (~S_ERR);
+               }
+       }
+ubafree(i) ;
+((struct lnkreg *)LNKADR)->drst &= (~OM);
+V11tab.state &= (~BUSY) ;
+}
+/*             */
+V11read(dev)
+{
+register i , j  ;
+spl5() ;
+V11tab.state |= R1 ;
+((struct lnkreg *)LNKADR)->drst |= OD ; /* receiver */
+spl0() ;
+i = uballoc(V11tab.bp->b_un.b_addr,BUFSIZ,1) ;
+j = i & 0x3ffff ; /* start map no. & byte offset */
+while ((u.u_count>0) && (u.u_error == 0)) {
+       ((struct lnkreg *)LNKADR)->drwc = (-(BUFSIZ>>1)) ;
+       ((struct lnkreg *)LNKADR)->drba = j ;
+       spl5() ;
+       ((struct lnkreg *)LNKADR)->drst |= GO ;
+       /* wait for i-o to finish */
+       sleep(LNKADR,V11PRI) ;
+       spl0() ;
+       if (V11tab.state & S_ERR) {
+               u.u_error = ENXIO ;
+               V11tab.state &= (~S_ERR);
+               continue ;
+               }
+       iomove(V11tab.bp->b_un.b_addr,min(BUFSIZ,u.u_count),B_READ) ;
+       }
+ubafree(i) ;
+V11tab.state &= (~BUSY) ;
+}
+/*             */
+V11int(dev)
+{
+register unsigned short state ;
+register int i ;
+extern int V11ioctl() ;
+state = V11tab.state ;
+if ((i = ((struct lnkreg *)LNKADR)->drst) & ERR)
+       if (state&BUSY) V11tab.state |= S_ERR ;
+if (state&BUSY) {
+       wakeup(LNKADR) ;
+       return ;
+       }
+if (i&IM) {
+       if (state&PREread) {
+               wakeup(V11ioctl);
+               return;
+               }
+       if (((state&BUSY) == 0) && (state&OPEN))
+               V11tab.state |= IPEND ;
+       return;
+       }
+}
+/*             */
+V11ioctl(dev,cmd,addr,flag)
+dev_t dev;
+caddr_t addr;
+{
+if (cmd & VSPEC) {
+       switch (cmd & 077777) {
+               case L_WAKE : { /* debug wakeup */
+                       wakeup(LNKADR);
+                       break;
+                       }
+               case L_NOT : { /* send OIR to other end of link */
+                       spl5();
+                       ((struct lnkreg *)LNKADR)->drst |= (OIR|OM) ;
+                       ((struct lnkreg *)LNKADR)->drst &= (~OIR);
+                       spl0();
+                       break;
+                       }
+               case L_MON : { /* 'lnkmon' decr 'V11opn' */
+                       V11opn--;
+                       break;
+                       }
+               case PREread : { /* 'lnkmon' wait */
+                       spl5();
+                       if (V11tab.state&IPEND) {
+                               V11tab.state &= (~IPEND);
+                               }
+                       else {
+                               V11tab.state |= PREread;
+                               sleep(V11ioctl,PZERO+1);
+                               V11tab.state &= (~PREread);
+                               }
+                       spl0();
+                       break;
+                       }
+               }
+       }
+else {
+       *((short *)addr) = V11tab.state;
+       }
+}