?? orig_rl.c
字號:
/* * RL disk driver */#define DK_N 2#include "../h/param.h"#include "../h/buf.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/systm.h"#define NRLBLK 10240#define RLCYLSZ 10240#define RLSECSZ 256#define RESET 013#define STAT 03#define GETSTAT 04#define WCOM 012#define RCOM 014#define SEEK 06#define SEEKHI 5#define SEEKLO 1#define RDHDR 010#define IENABLE 0100#define CRDY 0200#define OPI 02000#define CRCERR 04000#define TIMOUT 010000#define NXM 020000#define DE 040000struct device{ int rlcs, rlba, rlda, rlmp;};#define RLADDR ((struct device *)0174400)#define RL_CNT 1struct buf rrlbuf;struct buf rltab;struct { int cn[4]; /* location of heads for each drive */ int dn; /* drive number */ int com; /* read or write command word */ int chn; /* cylinder and head number */ unsigned int bleft; /* bytes left to be transferred */ unsigned int bpart; /* number of bytes transferred */ int sn; /* sector number */ union { int w[2]; long l; } addr; /* address of memory for transfer */} rl = {-1,-1,-1,-1};rlstrategy(bp)register struct buf *bp;{ if(bp->b_blkno >= NRLBLK) { if(bp->b_blkno == NRLBLK && bp->b_flags&B_READ) bp->b_resid = bp->b_bcount; else { bp->b_flags |= B_ERROR; bp->b_error = ENXIO; } iodone(bp); return; } bp->av_forw = NULL; spl5(); if(rltab.b_actf == NULL) rltab.b_actf = bp; else rltab.b_actl->av_forw = bp; rltab.b_actl = bp; if(rltab.b_active == NULL) rlstart(); spl0();}rlstart(){ register struct buf *bp; if ((bp = rltab.b_actf) == NULL) return; rltab.b_active++; rl.dn = minor(bp->b_dev); rl.chn = bp->b_blkno/20; rl.sn = (bp->b_blkno%20) << 1; rl.bleft = bp->b_bcount; rl.addr.w[0] = bp->b_xmem & 3; rl.addr.w[1] = (int)bp->b_un.b_addr; rl.com = (rl.dn << 8) | IENABLE; if (bp->b_flags & B_READ) rl.com |= RCOM; else rl.com |= WCOM; rlio();}rlintr(){ register struct buf *bp; register struct device *rp; register int status; rp = RLADDR; if (rltab.b_active == NULL) {/* logstray(rp);*/ return; } bp = rltab.b_actf; dk_busy &= ~(1<<DK_N); if (rp->rlcs < 0) { /* error bit */ if (rp->rlcs & 036000) { if(rltab.b_errcnt > 2) deverror(bp, rp->rlcs, rp->rlda); } if (rp->rlcs & 040000) { rp->rlda = STAT; rp->rlcs = (rl.dn << 8) | GETSTAT; while ((rp->rlcs & CRDY) == 0) ; status = rp->rlmp; if(rltab.b_errcnt > 2) deverror(bp, status, rp->rlda); rp->rlda = RESET; rp->rlcs = (rl.dn << 8) | GETSTAT; while ((rp->rlcs & CRDY) == 0) ; if(status & 01000) { rlstart(); return; } } if (++rltab.b_errcnt <= 10) { rl.cn[rl.dn] = -1; rlstart(); return; } else { bp->b_flags |= B_ERROR; rl.bpart = rl.bleft; } } if ((rl.bleft -= rl.bpart) > 0) { rl.addr.l += rl.bpart; rl.sn=0; rl.chn++; rlio(); return; } rltab.b_active = NULL; rltab.b_errcnt = 0; rltab.b_actf = bp->av_forw; bp->b_resid = 0; iodone(bp); rlstart();}rlio(){ register struct device *rp; register dif; register int head; rp = RLADDR; dk_busy |= 1<<DK_N; dk_numb[DK_N] += 1; head = rl.bpart>>6; dk_wds[DK_N] += head; if (rl.cn[rl.dn] < 0) { rp->rlcs = (rl.dn << 8) | RDHDR; while ((rp->rlcs&CRDY) == 0) ; rl.cn[rl.dn] = (rp->rlmp&077700) >> 6; } dif =(rl.cn[rl.dn] >> 1) - (rl.chn >>1); head = (rl.chn & 1) << 4; if (dif < 0) rp->rlda = (-dif <<7) | SEEKHI | head; else rp->rlda = (dif << 7) | SEEKLO | head; rp->rlcs = (rl.dn << 8) | SEEK; rl.cn[rl.dn] = rl.chn; if (rl.bleft < (rl.bpart = RLCYLSZ - (rl.sn * RLSECSZ))) rl.bpart = rl.bleft; while ((rp->rlcs&CRDY) == 0) ; rp->rlda = (rl.chn << 6) | rl.sn; rp->rlba = rl.addr.w[1]; rp->rlmp = -(rl.bpart >> 1); rp->rlcs = rl.com | rl.addr.w[0] << 4;}rlread(dev){ physio(rlstrategy, &rrlbuf, dev, B_READ);}rlwrite(dev){ physio(rlstrategy, &rrlbuf, dev, B_WRITE);}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -