date and time created 86/01/12 18:04:58 by sam
authorSam Leffler <sam@ucbvax.Berkeley.EDU>
Mon, 13 Jan 1986 10:04:58 +0000 (02:04 -0800)
committerSam Leffler <sam@ucbvax.Berkeley.EDU>
Mon, 13 Jan 1986 10:04:58 +0000 (02:04 -0800)
SCCS-vsn: sys/tahoe/stand/cy.c 7.1
SCCS-vsn: sys/tahoe/stand/devcopy.c 1.1

usr/src/sys/tahoe/stand/cy.c [new file with mode: 0644]
usr/src/sys/tahoe/stand/devcopy.c [new file with mode: 0644]

diff --git a/usr/src/sys/tahoe/stand/cy.c b/usr/src/sys/tahoe/stand/cy.c
new file mode 100644 (file)
index 0000000..ebefcba
--- /dev/null
@@ -0,0 +1,343 @@
+/*     cy.c    7.1     86/01/12        */
+/*     cy.c    Tahoe version   Mar 1983.       */
+
+/*
+ * Cypher tape driver. Stand alone version.
+ *
+ */
+#include "../machine/pte.h"
+#include "../machine/mtpr.h"
+
+#include "param.h"
+#include "inode.h"
+#include "fs.h"
+
+#include "saio.h"
+#include "cyvar.h"
+
+long   cystd[] = { 0xf4000, 0 };
+
+struct scp     /* SYSTEM CONFIGURATION POINTER */
+{
+  char sysbus ;        /* width of system buss 0=8;1=16 */
+  char nu1 ;
+  char pt_scb[4] ;     /* pointer to ->SYSTEM CONFIGURATION BLOCK */
+};
+
+struct scp * SCP;      /* absolute address - jumpered on the controller */
+                       /* set to 0xC06 for Tahoe */
+
+struct scb     /* SYSTEM CONFIGUREATION BLOCK */
+{
+  char sysblk[1] ;     /* 0x03 fixed value code */
+  char nu2[1] ;
+  char pt_ccb[4] ;     /* pointer to ->CHANNEL CONTROL BLOCK */
+}scb;
+
+struct ccb     /* CHANNEL CONTROL BLOCK */
+{
+  char ccw[1] ;                /* 0x11 normal; 0x09 clear non_vect interrupt */
+  char gate[1] ;       /* This is "the" GATE */
+  char pt_tpb[4] ;     /* pointer to ->TAPE OPERATION BLOCK or MOVE BLOCK */
+}ccb;
+
+struct tpb     /* TAPE OPERATIONS PARAMETER BLOCK */
+{
+  long cmd ;           /* COMMAND (input) */
+  char control[2] ;    /* CONTROL (input) */
+  short count ;                /* RETURN COUNT (output) */
+  short size ;         /* BUFFER SIZE (input/output) */
+  short rec_over ;     /* RECORDS/OVERRUN (input/output) */
+  char pt_data[4] ;    /* pointer to ->SOURCE/DEST (input) */
+  char status[2] ;     /* STATUS (output) */
+  char pt_link[4] ;    /* pointer to ->INTERRUPT/PARAMETER BLOCK (input) */
+} tpb;
+
+struct tpb cycool      /* tape parameter block to clear interrupts */
+= {
+       0L,             /* command */
+       0,0,            /* control */
+       0,              /* count */
+       0,              /* size */
+       0,              /* rec_over */
+       0,0,0,0,        /* pt_data */
+       0,0,            /* status */
+       0,0,0,0         /* pt_link */
+} ;    
+int cyblksiz = 1024;   /* foreign tape size as found in open routine */
+long cyblock;          /* next block number for i/o */
+/*
+ * Reset the controller.
+ */
+cyopen(io)
+       register struct iob *io;
+{
+       register ctlradr;
+
+       ctlradr = cystd[0] + (int)IOBASE;
+       SCP = (struct scp *)0xc06;              /* absolute - for setup */
+       TM_RESET(ctlradr,0xff); /* reset the controller */
+       /*
+        * Initialize the system configuration pointer
+        */
+       SCP->sysbus = 1;                        /* system width = 16 bits. */
+       /* initialize the pointer to the system configuration block */
+       set_pointer((long)&scb.sysblk[0],(char *)SCP->pt_scb);
+       /*
+        * Initialize the system configuration block.
+        */
+       scb.sysblk[0] = 0x3;            /* fixed value */
+       /* initialize the pointer to the channel control block */
+       set_pointer((long)&ccb.ccw[0],(char *)scb.pt_ccb);
+       /*
+        * Initialize the channel control block.
+        */
+       ccb.ccw[0] = 0x11;              /* normal interrupts */
+       /* initialize the pointer to the tape parameter block */
+       set_pointer((long)&tpb,(char *)ccb.pt_tpb);
+       /*
+        * set the command to be NO_OP.
+        */
+       tpb.cmd = NO_OP;
+       tpb.control[0] = CW_BL;         /* TPB not used on first attention */
+       tpb.control[1] = CW_16bits;
+       ccb.gate[0] = GATE_CLOSED;      
+       TM_ATTENTION(ctlradr, 0xff);    /* execute! */
+       cywait(10*1000);
+       /*
+        * set the command to be CONFIGURE.
+        */
+       tpb.cmd = CONFIG;
+       tpb.control[0] = CW_BL;         /* NO interrupt on completion */
+       tpb.control[1] = CW_16bits;
+       tpb.status[0] = tpb.status[1] = 0;
+       ccb.gate[0] = GATE_CLOSED;      
+       TM_ATTENTION(ctlradr, 0xff);    /* execute! */
+       cywait(10*1000);
+       uncache (&tpb.status[1]) ;
+       if (tpb.status[1] & CS_ERm) {
+          printf("Cypher initialization error!\n");
+          cy_decode_error(tpb.status[1]&CS_ERm);
+          _stop("");
+       }
+       if(cycmd(io,REWD_TA) == -1)
+               _stop("Rewind failed!\n");
+       while(io->i_boff > 0) {
+               if(cycmd(io,SPAC_FM) == -1)
+                       _stop("cy: seek failure!\n");
+               io->i_boff--;
+       }
+#ifdef NOBLOCK
+       if (io->i_flgs & F_READ) {
+               if((cyblksiz = cycmd(io,READ_FO)) == -1)
+                       _stop("Read foriegn tape failed!\n");
+               if(cycmd(io,REWD_TA) == -1)
+                       _stop("Rewind after read failed\n");
+       }
+#endif
+}
+
+/* if tape was open for writing write a file mark */
+cyclose(io)
+       register struct iob *io;
+{
+       if (io->i_flgs & F_WRITE) cycmd(io,WRITE_FMARK);
+       cycmd(io,REWD_TA);
+       cyblock = 0;
+}
+
+cystrategy(io,func)
+       register struct iob *io;
+       register long   func;
+{
+
+#ifndef NOBLOCK
+       if ((func != SPACE) && (func != REWD_TA) && (io->i_bn != cyblock)) {
+               cycmd(io,SPACE);
+               tpb.rec_over = 0;
+       }
+       if(func==READ || func==WRITE) {
+               struct iob liob;
+               register struct iob *lio = &liob;
+               register count;
+
+               liob = *io;
+               while(lio->i_cc > 0) {
+                       if((count = cycmd(lio, func)) == 0)
+                               return(-1);
+                       lio->i_cc -= count;
+                       lio->i_ma += count;
+               }
+               return(io->i_cc);
+       }
+#endif
+       return(cycmd(io, func));
+}
+
+cycmd(io,func)
+       register struct iob *io;
+       long    func;
+{
+       register ctlradr;
+       short j;
+
+       ctlradr = cystd[0] + (int)IOBASE;
+       cywait(9000); 
+       if (func == READ) func = READ_TA;
+       else if (func == WRITE) func = WRIT_TA;
+       else if (func == WRITE_FMARK) func = WRIT_FM;
+       tpb.cmd = func;
+       uncache(&ccb.gate[0]);
+       while(ccb.gate[0] == GATE_CLOSED)
+               uncache(&ccb.gate[0]);
+       ccb.gate[0] = GATE_CLOSED;
+       tpb.control[0] = CW_BL;
+       tpb.control[1] = CW_16bits;
+       tpb.status[0] = tpb.status[1] = 0;
+       tpb.count = 0;
+       set_pointer((long)&tpb,(char *)ccb.pt_tpb);
+       switch (func) 
+       {
+       case READ_TA:
+               if (io->i_cc > cyblksiz)
+                       tpb.size = TM_SHORT(cyblksiz);
+               else tpb.size = TM_SHORT(io->i_cc);
+               set_pointer((long)io->i_ma,(char *)tpb.pt_data);
+               cyblock += 1;
+               break;
+       case WRIT_TA:
+               tpb.size = TM_SHORT(io->i_cc);
+               set_pointer((long)io->i_ma,(char *)tpb.pt_data);
+               cyblock += 1;
+               break;
+       case SPACE:
+               if ((j = io->i_bn - cyblock) < 0) {
+                       j = -j;
+                       tpb.control[1] |= CW_R;
+                       cyblock -= j;
+               }
+               else
+                       cyblock += j;
+               tpb.rec_over = TM_SHORT(j);
+               break;
+       case REWD_TA:
+               cyblock = 0;
+               break;
+       }
+       TM_ATTENTION(ctlradr, 0xff);    /* execute! */
+       if (func == REWD_TA || func == SPACE) {
+               cywait(60*5*1000);
+       }
+       else cywait(10*1000);
+       /*
+        * First we clear the interrupt and close the gate.
+        */
+       mtpr(PADC, 0);
+       ccb.gate[0] = GATE_CLOSED;
+       set_pointer((int)&cycool,(char *)ccb.pt_tpb);
+       cycool.cmd = NO_OP;     /* no operation */
+       cycool.control[0] = CW_BL;      /* No INTERRUPTS */
+       cycool.control[1] = 0;
+       TM_ATTENTION(ctlradr,0xff);     /* cool it ! */
+       cywait(20000); 
+       uncache (&tpb.status[1] ) ; 
+       if (tpb.status[1] & CS_ERm) {
+               cy_decode_error(tpb.status[1]&CS_ERm);
+               return -1;
+       }
+       uncache (&tpb.count);
+       return((long)TM_SHORT(tpb.count));
+}
+       
+
+
+cyprint_error(message)
+register char  *message;
+{
+       printf("cy0: %s.\n", message);
+}
+\f
+/*
+*/
+
+cy_decode_error(status)
+register int   status;
+{
+       switch(status) {
+       case ER_TO1:
+       case ER_TO2:
+       case ER_TO3:
+       case ER_TO4:
+       case ER_TO5:
+               cyprint_error("Drive timed out during transfer");
+               break;
+       case ER_TO6:    
+               cyprint_error("Non-existant system memory reference");
+               break;
+       case ER_DIAG:
+       case ER_JUMP:
+               cyprint_error("Controller micro diagnostics failed");
+               break;
+       case ER_HARD:
+               cyprint_error("Unrecoverble media error");
+               break;
+       case ER_TOF:
+               if (tpb.cmd == WRIT_TA)
+                       cyprint_error("Unsatisfactory media");
+               break;
+       case ER_FIFO:
+               cyprint_error("Data transfer over run");
+               break;
+       case ER_TRN:
+               cyprint_error("Drive is not ready");
+               break;
+       case ER_PRO:
+               cyprint_error("Tape is write protected");
+               break;
+       case ER_PSUM:
+               cyprint_error("Checksum error in controller proms");
+               break;
+       case ER_PARI:
+               cyprint_error("Unrecoverable tape parity error");
+               break;
+       case ER_BLAN:
+               cyprint_error("Blank tape found where data was expected");
+               break;
+       case ER_ER:
+               cyprint_error("Unrecoverble hardware error");
+       default:
+               break;
+       }
+}
+
+
+long 
+cywait(timeout)
+       long timeout;
+{
+       long dummy;
+
+       uncache (&ccb.gate[0]) ;
+       while (ccb.gate[0] != GATE_OPEN) {
+               uncache (&ccb.gate[0]) ;
+               DELAY(1000);
+               if (--timeout == 0) {
+                       cyprint_error("Transfer timeout");
+                       _stop("");
+               }
+       }
+}
+
+/*
+ *  Set a TAPEMASTER pointer (first parameter), into the
+ *  4 bytes array pointed by the second parameter.
+ */
+set_pointer(pointer,dest)
+long pointer;
+char * dest;
+{
+       *dest++ = pointer & 0xff;               /* low byte - offset */
+       *dest++ = (pointer >> 8) & 0xff;        /* high byte - offset */
+       *dest++ = 0; 
+       *dest   = (pointer & 0xf0000) >> 12;    /* base */
+}
diff --git a/usr/src/sys/tahoe/stand/devcopy.c b/usr/src/sys/tahoe/stand/devcopy.c
new file mode 100644 (file)
index 0000000..b86e7bb
--- /dev/null
@@ -0,0 +1,60 @@
+/*     devcopy.c       1.1     86/01/12        */
+/*     devcopy.c */
+#define        BSIZE   1024
+char dev[50];
+char disk[50];
+char blocks[50] ;
+int    fsi;
+int    fso;
+char   buffer[BSIZE];
+
+main()
+{
+       int j, c, i, n;
+       char buf[50];
+       int input, output;
+
+       do {
+               printf("Source device : ");
+               gets(dev);
+               printf("Copy to device : ");
+               gets(disk);
+               printf("Number of blocks : ");
+               gets(blocks);
+               j = number(blocks);
+               input = open(dev, 0);
+               if (input <= 0) printf("Cannot open %s\n", dev);
+               output = open(disk, 1);
+               if (output <= 0) printf("Cannot open output\n", disk);
+       } while (input <= 0 || output <= 0);
+
+       i = 0;  /* Block number */
+       n = BSIZE;
+       while (n == BSIZE && i < j) {
+               if (i > 0 && (i%500 == 0) ) printf("%d blocks\n", i);
+               lseek (input, i*BSIZE, 0);
+               n = read (input, buffer, BSIZE);
+               if (n == BSIZE) {
+                       lseek (output, i*BSIZE, 0);
+                       n = write(output, buffer, BSIZE);
+                       if (n != BSIZE) printf("Short write, block %d, %d bytes only\n",i,n);
+                       i++;
+               }
+               else printf("Short read, block %d, %d bytes only\n",i,n);
+       }
+       printf ("Total of %d blocks copied\n",i);
+}
+
+int number (response)
+char *response;
+{
+       int     i, j;
+       
+       j = 0;  /* Total */
+       while (*response == ' ' || *response == '\t') response++;
+       while (*response >= '0' && *response <= '9') {
+               j = j*10 + *response - '0';
+               response++;
+       }
+       return (j);
+}