From b49e078ffc66ebccab7e10d5a2de38571ca9f4ab Mon Sep 17 00:00:00 2001 From: Dennis Ritchie Date: Tue, 26 Nov 1974 18:13:21 -0500 Subject: [PATCH] Research V5 development Work on file usr/sys/dmr/tm.c Synthesized-from: v5 --- usr/sys/dmr/tm.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 usr/sys/dmr/tm.c diff --git a/usr/sys/dmr/tm.c b/usr/sys/dmr/tm.c new file mode 100644 index 0000000000..57b12c79e0 --- /dev/null +++ b/usr/sys/dmr/tm.c @@ -0,0 +1,222 @@ +# +/* + * Copyright 1973 Bell Telephone Laboratories Inc + */ + +/* + * TM tape driver + */ + +#include "../param.h" +#include "../buf.h" +#include "../conf.h" +#include "../user.h" + +struct { + int tmer; + int tmcs; + int tmbc; + int tmba; + int tmdb; + int tmrd; +}; + +struct devtab tmtab; +struct buf rtmbuf; + +char t_openf[8]; +char *t_blkno[8]; +char *t_nxrec[8]; + +#define TMADDR 0172520 + +#define GO 01 +#define RCOM 02 +#define WCOM 04 +#define WEOF 06 +#define SFORW 010 +#define SREV 012 +#define WIRG 014 +#define REW 016 +#define DENS 060000 /* 9-channel */ +#define IENABLE 0100 +#define CRDY 0200 +#define GAPSD 010000 +#define TUR 1 +#define HARD 0102200 /* ILC, EOT, NXM */ +#define EOF 0040000 + +#define SSEEK 1 +#define SIO 2 + +tmopen(dev, flag) +{ + register dminor; + + dminor = dev.d_minor; + if (t_openf[dminor]) + u.u_error = ENXIO; + else { + t_openf[dminor]++; + t_blkno[dminor] = 0; + t_nxrec[dminor] = 65535; + } +} + +tmclose(dev, flag) +{ + register int dminor; + + dminor = dev.d_minor; + t_openf[dminor] = 0; + if (flag) + tcommand(dminor, WEOF); + tcommand(dminor, REW); +} + +tcommand(unit, com) +{ + extern lbolt; + + while (tmtab.d_active || (TMADDR->tmcs & CRDY)==0) + sleep(&lbolt, 1); + TMADDR->tmcs = DENS|com|GO | (unit<<8); +} + +tmstrategy(abp) +struct buf *abp; +{ + register struct buf *bp; + register char **p; + + bp = abp; + p = &t_nxrec[bp->b_dev.d_minor]; + if (*p <= bp->b_blkno) { + if (*p < bp->b_blkno) { + bp->b_flags =| B_ERROR; + iodone(bp); + return; + } + if (bp->b_flags&B_READ) { + clrbuf(bp); + iodone(bp); + return; + } + } + if ((bp->b_flags&B_READ)==0) + *p = bp->b_blkno + 1; + bp->av_forw = 0; + spl5(); + if (tmtab.d_actf==0) + tmtab.d_actf = bp; + else + tmtab.d_actl->av_forw = bp; + tmtab.d_actl = bp; + if (tmtab.d_active==0) + tmstart(); + spl0(); +} + +tmstart() +{ + register struct buf *bp; + register int com; + int unit; + register char *blkno; + + loop: + if ((bp = tmtab.d_actf) == 0) + return; + unit = bp->b_dev.d_minor; + blkno = t_blkno[unit]; + if (t_openf[unit] < 0 || (TMADDR->tmcs & CRDY)==0) { + bp->b_flags =| B_ERROR; + tmtab.d_actf = bp->av_forw; + iodone(bp); + goto loop; + } + com = (unit<<8) | (bp->b_flags&B_XMEM) | IENABLE|DENS; + if (blkno != bp->b_blkno) { + tmtab.d_active = SSEEK; + if (blkno < bp->b_blkno) { + com =| SFORW|GO; + TMADDR->tmbc = blkno - bp->b_blkno; + } else { + if (bp->b_blkno == 0) + com =| REW|GO; + else { + com =| SREV|GO; + TMADDR->tmbc = bp->b_blkno - blkno; + } + } + TMADDR->tmcs = com; + return; + } + tmtab.d_active = SIO; + TMADDR->tmbc = bp->b_wcount << 1; + TMADDR->tmba = bp->b_addr; /* core address */ + TMADDR->tmcs = com | ((bp->b_flags&B_READ)? RCOM|GO: + ((tmtab.d_errcnt)? WIRG|GO: WCOM|GO)); +} + +tmintr() +{ + register struct buf *bp; + register int unit; + + if ((bp = tmtab.d_actf)==0) + return; + unit = bp->b_dev.d_minor; + if (TMADDR->tmcs < 0) { /* error bit */ +/* + deverror(bp, TMADDR->tmer); + */ + while(TMADDR->tmrd & GAPSD) ; /* wait for gap shutdown */ + if ((TMADDR->tmer&(HARD|EOF))==0 && tmtab.d_active==SIO) { + if (++tmtab.d_errcnt < 10) { + t_blkno[unit]++; + tmtab.d_active = 0; + tmstart(); + return; + } + } else + if(bp != &rtmbuf && (TMADDR->tmer&EOF)==0) + t_openf[unit] = -1; + bp->b_flags =| B_ERROR; + tmtab.d_active = SIO; + } + if (tmtab.d_active == SIO) { + tmtab.d_errcnt = 0; + t_blkno[unit]++; + tmtab.d_actf = bp->av_forw; + tmtab.d_active = 0; + iodone(bp); + bp->b_resid = TMADDR->tmbc; + } else + t_blkno[unit] = bp->b_blkno; + tmstart(); +} + +tmread(dev) +{ + tmphys(dev); + physio(tmstrategy, &rtmbuf, dev, B_READ); + u.u_count = -rtmbuf.b_resid; +} + +tmwrite(dev) +{ + tmphys(dev); + physio(tmstrategy, &rtmbuf, dev, B_WRITE); + u.u_count = 0; +} + +tmphys(dev) +{ + register unit, a; + + unit = dev.d_minor; + a = lshift(u.u_offset, -9); + t_blkno[unit] = a; + t_nxrec[unit] = ++a; +} -- 2.20.1