home *** CD-ROM | disk | FTP | other *** search
- #
- /*
- */
-
- /*
- * 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);
- }
-