Add original unix v6
This commit is contained in:
+174
@@ -0,0 +1,174 @@
|
||||
#
|
||||
/*
|
||||
*/
|
||||
|
||||
/*
|
||||
* RP disk driver
|
||||
*/
|
||||
|
||||
#include "../param.h"
|
||||
#include "../buf.h"
|
||||
#include "../conf.h"
|
||||
#include "../user.h"
|
||||
|
||||
struct {
|
||||
int rpds;
|
||||
int rper;
|
||||
int rpcs;
|
||||
int rpwc;
|
||||
int rpba;
|
||||
int rpca;
|
||||
int rpda;
|
||||
};
|
||||
|
||||
#define RPADDR 0176710
|
||||
#define NRP 8
|
||||
|
||||
struct {
|
||||
char *nblocks;
|
||||
int cyloff;
|
||||
} rp_sizes[] {
|
||||
40600, 0, /* cyl 0 thru 202 */
|
||||
40600, 203, /* cyl 203 thru 405 */
|
||||
9200, 0, /* cyl 0 thru 45 */
|
||||
9200, 360, /* cyl 360 thru 405 */
|
||||
-1, 0, /* cyl 0 thru 327 */
|
||||
-1, 78, /* cyl 78 thru 405 */
|
||||
15600, 0, /* cyl 0 thru 77 */
|
||||
15600, 328, /* cyl 328 thru 405 */
|
||||
};
|
||||
|
||||
struct devtab rptab;
|
||||
struct buf rrpbuf;
|
||||
|
||||
#define GO 01
|
||||
#define RESET 0
|
||||
#define HSEEK 014
|
||||
|
||||
#define IENABLE 0100
|
||||
#define READY 0200
|
||||
|
||||
#define SUFU 01000
|
||||
#define SUSU 02000
|
||||
#define SUSI 04000
|
||||
#define HNF 010000
|
||||
|
||||
/*
|
||||
* Use av_back to save track+sector,
|
||||
* b_resid for cylinder.
|
||||
*/
|
||||
|
||||
#define trksec av_back
|
||||
#define cylin b_resid
|
||||
|
||||
rpstrategy(abp)
|
||||
struct buf *abp;
|
||||
{
|
||||
register struct buf *bp;
|
||||
register char *p1, *p2;
|
||||
|
||||
bp = abp;
|
||||
if(bp->b_flags&B_PHYS)
|
||||
mapalloc(bp);
|
||||
p1 = &rp_sizes[bp->b_dev.d_minor&07];
|
||||
if (bp->b_dev.d_minor >= (NRP<<3) ||
|
||||
bp->b_blkno >= p1->nblocks) {
|
||||
bp->b_flags =| B_ERROR;
|
||||
iodone(bp);
|
||||
return;
|
||||
}
|
||||
bp->av_forw = 0;
|
||||
bp->cylin = p1->cyloff;
|
||||
p1 = bp->b_blkno;
|
||||
p2 = lrem(p1, 10);
|
||||
p1 = ldiv(p1, 10);
|
||||
bp->trksec = (p1%20)<<8 | p2;
|
||||
bp->cylin =+ p1/20;
|
||||
spl5();
|
||||
if ((p1 = rptab.d_actf)==0)
|
||||
rptab.d_actf = bp;
|
||||
else {
|
||||
for (; p2 = p1->av_forw; p1 = p2) {
|
||||
if (p1->cylin <= bp->cylin
|
||||
&& bp->cylin < p2->cylin
|
||||
|| p1->cylin >= bp->cylin
|
||||
&& bp->cylin > p2->cylin)
|
||||
break;
|
||||
}
|
||||
bp->av_forw = p2;
|
||||
p1->av_forw = bp;
|
||||
}
|
||||
if (rptab.d_active==0)
|
||||
rpstart();
|
||||
spl0();
|
||||
}
|
||||
|
||||
rpstart()
|
||||
{
|
||||
register struct buf *bp;
|
||||
|
||||
if ((bp = rptab.d_actf) == 0)
|
||||
return;
|
||||
rptab.d_active++;
|
||||
RPADDR->rpda = bp->trksec;
|
||||
devstart(bp, &RPADDR->rpca, bp->cylin, bp->b_dev.d_minor>>3);
|
||||
}
|
||||
|
||||
rpintr()
|
||||
{
|
||||
register struct buf *bp;
|
||||
register int ctr;
|
||||
|
||||
if (rptab.d_active == 0)
|
||||
return;
|
||||
bp = rptab.d_actf;
|
||||
rptab.d_active = 0;
|
||||
if (RPADDR->rpcs < 0) { /* error bit */
|
||||
deverror(bp, RPADDR->rper, RPADDR->rpds);
|
||||
if(RPADDR->rpds & (SUFU|SUSI|HNF)) {
|
||||
RPADDR->rpcs.lobyte = HSEEK|GO;
|
||||
ctr = 0;
|
||||
while ((RPADDR->rpds&SUSU) && --ctr);
|
||||
}
|
||||
RPADDR->rpcs = RESET|GO;
|
||||
ctr = 0;
|
||||
while ((RPADDR->rpcs&READY) == 0 && --ctr);
|
||||
if (++rptab.d_errcnt <= 10) {
|
||||
rpstart();
|
||||
return;
|
||||
}
|
||||
bp->b_flags =| B_ERROR;
|
||||
}
|
||||
rptab.d_errcnt = 0;
|
||||
rptab.d_actf = bp->av_forw;
|
||||
bp->b_resid = RPADDR->rpwc;
|
||||
iodone(bp);
|
||||
rpstart();
|
||||
}
|
||||
|
||||
rpread(dev)
|
||||
{
|
||||
|
||||
if(rpphys(dev))
|
||||
physio(rpstrategy, &rrpbuf, dev, B_READ);
|
||||
}
|
||||
|
||||
rpwrite(dev)
|
||||
{
|
||||
|
||||
if(rpphys(dev))
|
||||
physio(rpstrategy, &rrpbuf, dev, B_WRITE);
|
||||
}
|
||||
|
||||
rpphys(dev)
|
||||
{
|
||||
register c;
|
||||
|
||||
c = lshift(u.u_offset, -9);
|
||||
c =+ ldiv(u.u_count+511, 512);
|
||||
if(c > rp_sizes[dev.d_minor & 07].nblocks) {
|
||||
u.u_error = ENXIO;
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
Reference in New Issue
Block a user