Annotation of cci/sys/stand/vddc.c, revision 1.1

1.1     ! root        1: /*
        !             2: ** Stand alone driver for the VDDC controller 
        !             3: **     TAHOE Version, Oct 1983.
        !             4: **
        !             5: */
        !             6: 
        !             7: #include "../machine/mtpr.h"
        !             8: #include "../h/param.h"
        !             9: #include "../h/inode.h"
        !            10: #include "../h/fs.h"
        !            11: #define VDGENDATA 1
        !            12: #include "../vba/vddc.h"
        !            13: #undef VDGENDATA
        !            14: #include "../stand/saio.h"
        !            15: 
        !            16: #define NVD            4                       /* Max number of controllers */
        !            17: 
        !            18: #define TRUE           1
        !            19: #define        FALSE           0
        !            20: #define VDUNIT(x)      (minor(x) & 0x3)
        !            21: #define VDCTLR(x)      (minor(x) >> 2)
        !            22: 
        !            23: /*
        !            24: **     MDCB
        !            25: */
        !            26: 
        !            27: fmt_mdcb       mdcb;
        !            28: 
        !            29: /*
        !            30: **     DCB
        !            31: */
        !            32: 
        !            33: fmt_dcb                dcb;
        !            34: 
        !            35: /*
        !            36: ** Unit specific information.
        !            37: */
        !            38: 
        !            39: struct {
        !            40:        char    configured;
        !            41:        fs_tab  info;
        !            42: }unit_info[NVD][16];
        !            43: 
        !            44: /*
        !            45: ** Controller specific information.
        !            46: */
        !            47: 
        !            48: struct {
        !            49:        unsigned char   ctlr_type;
        !            50:        char            *ctlr_name;
        !            51:        unsigned char   initialized;
        !            52:        unsigned char   ctlr_started;
        !            53: } ctlr_info[NVD];
        !            54: 
        !            55: static char    junk[1024];
        !            56: 
        !            57: 
        !            58: /*
        !            59: **
        !            60: */
        !            61: 
        !            62: vdopen(io)
        !            63: register struct iob    *io;
        !            64: {
        !            65:        register int    ctlr = VDCTLR(io->i_unit);
        !            66:        register int    unit = VDUNIT(io->i_unit);
        !            67:        register int    i, j;
        !            68: 
        !            69:        /* Make sure controller number is in range */
        !            70:        if(ctlr >= NVD) {
        !            71:                printf("vd%d: Unit number can't be greater than %x!\n",
        !            72:                    io->i_unit, (NVD * 4) - 1);
        !            73:                _stop("");
        !            74:        }
        !            75:        /* check file system for validity */
        !            76:        if((io->i_boff < 0) || (io->i_boff > 5)) {
        !            77:                printf("vd%d: File system #%d, should be less than #6.\n",
        !            78:                    io->i_unit, io->i_boff);
        !            79:                _stop("");
        !            80:        }
        !            81:        if(!ctlr_info[ctlr].initialized) {
        !            82:                vdinit(io);     /* initialize controller/drive */
        !            83:                ctlr_info[ctlr].initialized = TRUE;
        !            84:                for(i=0; i<NVD; i++)
        !            85:                        for(j=0; j<16; j++)
        !            86:                                unit_info[i][j].configured = FALSE;
        !            87:        }
        !            88:        if(!unit_info[ctlr][unit].configured) {
        !            89:                vdconfigure_drive(io);
        !            90:                unit_info[ctlr][unit].configured = TRUE;
        !            91:        }
        !            92:        io->i_boff = unit_info[ctlr][unit].info.partition[io->i_boff].par_start;
        !            93: }
        !            94: 
        !            95: 
        !            96: /*
        !            97: **
        !            98: */
        !            99: 
        !           100: vdinit(io)
        !           101: register struct iob    *io;
        !           102: {
        !           103:        register int    ctlr = VDCTLR(io->i_unit);
        !           104:        register int    unit = VDUNIT(io->i_unit);
        !           105:        register cdr    *ctlr_addr = (cdr *)(vddcaddr[ctlr]+IOBASE);
        !           106:        register char   *ctlr_type;
        !           107: 
        !           108:        /* Check to see if controller is really there */
        !           109:        if(badaddr(ctlr_addr, 2)) {
        !           110:                printf("vd%d: Controller %d is non-existant!\n",
        !           111:                    io->i_unit, ctlr);
        !           112:                _stop("");
        !           113:        }
        !           114:        /* Probe further to find what kind of controller it is */
        !           115:        ctlr_addr->cdr_reset = 0xffffffff;
        !           116:        DELAY(1000000);
        !           117:        /* Probe further to find what kind of controller it is */
        !           118:        if(ctlr_addr->cdr_reset != 0xffffffff) {
        !           119:                ctlr_info[ctlr].ctlr_type = SMDCTLR;
        !           120:                ctlr_info[ctlr].ctlr_name = "SMD";
        !           121:                DELAY(1000000);
        !           122:        }
        !           123:        else {
        !           124:                ctlr_info[ctlr].ctlr_type = SMD_ECTLR;
        !           125:                ctlr_info[ctlr].ctlr_name = "SMD/E";
        !           126:                ctlr_addr->cdr_reserved = 0x0;
        !           127:                DELAY(3000000);
        !           128:        }
        !           129:        if(ctlr_info[ctlr].ctlr_type == SMD_ECTLR) {
        !           130:                ctlr_addr->cdr_csr =  0;
        !           131:                ctlr_addr->mdcb_tcf = AM_ENPDA;
        !           132:                ctlr_addr->dcb_tcf = AM_ENPDA;
        !           133:                ctlr_addr->trail_tcf = AM_ENPDA;
        !           134:                ctlr_addr->data_tcf = AM_ENPDA;
        !           135:                ctlr_addr->cdr_ccf = CCF_STS | XMD_32BIT | BSZ_16WRD |
        !           136:                    CCF_ENP | CCF_EPE /* | CCF_EDE */ | CCF_ECE | CCF_ERR;
        !           137:        }
        !           138:        if(vdaccess_with_no_trailer(io, INIT, 8) & HRDERR) {
        !           139:                vdprint_error(io->i_unit, "Initialization error",
        !           140:                    dcb.operrsta,dcb.err_code);
        !           141:                _stop("");
        !           142:        }
        !           143:        if(vdaccess_with_no_trailer(io, DIAG, 8) & HRDERR) {
        !           144:                vdprint_error(io->i_unit, "Diagnostic error",
        !           145:                    dcb.operrsta, dcb.err_code);
        !           146:                _stop("");
        !           147:        }
        !           148: }
        !           149: 
        !           150: 
        !           151: /*
        !           152: **
        !           153: */
        !           154: 
        !           155: vdconfigure_drive(io)
        !           156: register struct iob    *io;
        !           157: {
        !           158:        register int    ctlr = VDCTLR(io->i_unit);
        !           159:        register int    unit = VDUNIT(io->i_unit);
        !           160:        register fs_tab *file_sys;
        !           161:        dskadr          daddr;
        !           162:        register int    i;
        !           163: 
        !           164:        for(i=0; i < nvddrv; i++) {
        !           165:                unit_info[ctlr][unit].info = vdst[i];
        !           166:                if(ctlr_info[ctlr].ctlr_type == SMDCTLR)
        !           167:                        if(unit_info[ctlr][unit].info.nsec != 32)
        !           168:                                continue;
        !           169:                vdconfigure(io, 0);
        !           170:                daddr.cylinder = unit_info[ctlr][unit].info.ncyl - 2;
        !           171:                daddr.track = unit_info[ctlr][unit].info.ntrak - 1;
        !           172:                daddr.sector = unit_info[ctlr][unit].info.nsec - 1;
        !           173:                io->i_ma = junk;
        !           174:                io->i_cc = unit_info[ctlr][unit].info.secsize;
        !           175:                if(!(vdaccess(io, &daddr, RD) & HRDERR))
        !           176:                        return;
        !           177:        }
        !           178:        printf("vd%d: Unrecognizable drive; controller %d, unit %d!\n",
        !           179:            io->i_unit, ctlr, unit);
        !           180:        _stop("");
        !           181: }
        !           182: 
        !           183: 
        !           184: /*
        !           185: **
        !           186: */
        !           187: 
        !           188: vdstart_drive(io)
        !           189: register struct iob    *io;
        !           190: {
        !           191:        register int    ctlr = VDCTLR(io->i_unit);
        !           192:        register int    unit = VDUNIT(io->i_unit);
        !           193:        register int    io_unit_save = io->i_unit;
        !           194: 
        !           195:        if(ctlr_info[ctlr].ctlr_started) {
        !           196:                DELAY(5500000);
        !           197:                return TRUE;
        !           198:        }
        !           199:        io->i_unit &= ~3;
        !           200:        if(vdaccess_with_no_trailer(io, VDSTART, ((unit * 6) + 62)) & HRDERR) {
        !           201:                vdprint_error(io->i_unit, "Start error",
        !           202:                    dcb.operrsta, dcb.err_code);
        !           203:                _stop("");
        !           204:        }
        !           205:        ctlr_info[ctlr].ctlr_started = TRUE;
        !           206:        io->i_unit = io_unit_save;
        !           207:        DELAY((unit * 5500000) + 62000000);
        !           208:        return TRUE;
        !           209: }
        !           210: 
        !           211: 
        !           212: /*
        !           213: **  This routine actually configures a particular drive.
        !           214: **
        !           215: **  If the controller is an SMD/E controller then the number of sectors per
        !           216: **  track is loaded into the appropriate register, otherwise it is left 
        !           217: **  alone because the old SMD controller requires a constant 32 sectors
        !           218: **  per track for it's drives. (an error would be returned if the value is
        !           219: **  loaded.)
        !           220: **
        !           221: **  In the stand-alone spirit of things the system is halted if an error
        !           222: **  occurs during this operation.
        !           223: */
        !           224: 
        !           225: vdconfigure(io, pass)
        !           226: register struct iob    *io;
        !           227: int    pass;
        !           228: {
        !           229:        register int    ctlr = VDCTLR(io->i_unit);
        !           230:        register int    unit = VDUNIT(io->i_unit);
        !           231:        register cdr    *ctlr_addr = (cdr *)(vddcaddr[ctlr]+IOBASE);
        !           232: 
        !           233:        dcb.opcode = RSTCFG;            /* command */
        !           234:        dcb.intflg = NOINT;
        !           235:        dcb.nxtdcb = (fmt_dcb *)0;      /* end of chain */
        !           236:        dcb.operrsta  = 0;
        !           237:        dcb.devselect = (char)unit;
        !           238:        dcb.trail.rstrail.ncyl = unit_info[ctlr][unit].info.ncyl;
        !           239:        dcb.trail.rstrail.nsurfaces = unit_info[ctlr][unit].info.ntrak;
        !           240:        if(ctlr_info[ctlr].ctlr_type == SMD_ECTLR) {
        !           241:                dcb.trailcnt = (char)4;
        !           242:                dcb.trail.rstrail.nsectors = unit_info[ctlr][unit].info.nsec;
        !           243:                dcb.trail.rstrail.slip_sec = unit_info[ctlr][unit].info.nslip;
        !           244:        }
        !           245:        else
        !           246:                dcb.trailcnt = (char)2;
        !           247:        mdcb.firstdcb = &dcb;
        !           248:        mdcb.vddcstat = 0;
        !           249:        VDDC_ATTENTION(ctlr_addr, &mdcb, ctlr_info[ctlr].ctlr_type);
        !           250:        POLLTILLDONE(ctlr_addr,&dcb,5,ctlr_info[ctlr].ctlr_type);
        !           251:        if(vdtimeout <= 0)
        !           252:                _stop(" during drive configuration.\n");
        !           253:        if(dcb.operrsta & (NOTCYLERR | DRVNRDY))
        !           254:                if(!pass) {
        !           255:                        vdstart_drive(io);
        !           256:                        vdconfigure(io, 1);
        !           257:                }
        !           258:        if(dcb.operrsta & HRDERR) {
        !           259:                vdprint_error(io->i_unit, "Configuration error",
        !           260:                    dcb.operrsta, dcb.err_code);
        !           261:                _stop("");
        !           262:        }
        !           263: }
        !           264: 
        !           265: 
        !           266: /*
        !           267: **  Strategy is called to the actual I/O to the disk drives.
        !           268: **
        !           269: **  Some simple checks are made to make sure we don't do anything rediculus,
        !           270: **  If everything is sane then the request is issued.
        !           271: **
        !           272: **  If no errors occured then the original byte count is returned,
        !           273: **  otherwise -1 is returned to indicate an error occured.
        !           274: */
        !           275: 
        !           276: vdstrategy(io, func)
        !           277: register struct iob    *io;
        !           278: register int func;
        !           279: {
        !           280:        dskadr          daddr;
        !           281:        register int    ctlr = VDCTLR(io->i_unit);
        !           282:        register int    unit = VDUNIT(io->i_unit);
        !           283:        register fs_tab *u_info = &unit_info[ctlr][unit].info;
        !           284:        register int    op = (func == READ) ? RD : WD;
        !           285:        register int    blk;
        !           286: 
        !           287:        if(io->i_cc == 0)
        !           288:                _stop("vd: Can't transfer zero length records!\n");
        !           289:        if(io->i_cc > 0xffff)
        !           290:                _stop("vd: Can't transfer greater than 2 to the 16th bytes!\n");
        !           291:        blk = io->i_bn * DEV_BSIZE / u_info->secsize;
        !           292:        daddr.sector = blk % u_info->nsec;
        !           293:        daddr.track = (blk / u_info->nsec) % u_info->ntrak;
        !           294:        daddr.cylinder = (blk/u_info->nsec) / u_info->ntrak;
        !           295:        if(vdaccess(io, &daddr, op) & HRDERR) {
        !           296:                vdprint_error(io->i_unit,"I/O error",dcb.operrsta,dcb.err_code);
        !           297:                return(-1);
        !           298:        }
        !           299:        mtpr(0,PADC);
        !           300:        return(io->i_cc);
        !           301: }
        !           302: 
        !           303: 
        !           304: 
        !           305: /*
        !           306: **
        !           307: */
        !           308: 
        !           309: vdprint_error(unit, str, status, smde_status)
        !           310: int            unit;
        !           311: char           *str;
        !           312: unsigned long  status;
        !           313: unsigned long  smde_status;
        !           314: {
        !           315:        printf("vd%d: %s; ", unit, str);
        !           316:        if(status & DRVNRDY)
        !           317:                printf("Drive is not ready");
        !           318:        else if(status & INVDADR)
        !           319:                printf("Invalid disk address issued");
        !           320:        else if(status & DNEMEM)
        !           321:                printf("Non-existent memory error");
        !           322:        else if(status & PARERR)
        !           323:                printf("Main memory parity error");
        !           324:        else if(status & OPABRT) 
        !           325:                printf("Program aborted operation");
        !           326:        else if(status & WPTERR)
        !           327:                printf("Drive is write protected");
        !           328:        else if(status & DSEEKERR)
        !           329:                printf("Disk seek error");
        !           330:        else if(status & UCDATERR)
        !           331:                printf("Uncorrectable data error");
        !           332:        else if(status & CTLRERR)
        !           333:                printf("Controller faulted");
        !           334:        else if(status & NOTCYLERR)
        !           335:                printf("Not on cylinder error");
        !           336:        else if(status & INVCMD)
        !           337:                printf("Invalid command issued to controller");
        !           338:        else 
        !           339:                printf("Controller error");
        !           340:        printf("!  Status = 0x%x", status);
        !           341:        if(smde_status)
        !           342:                printf("  Error code = %x", smde_status);
        !           343:        printf("\n");
        !           344: }
        !           345: 
        !           346: 
        !           347: /*
        !           348: **
        !           349: */
        !           350: 
        !           351: vdaccess_with_no_trailer(io, function, time)
        !           352: register struct iob    *io;
        !           353: register int           function, time;
        !           354: {
        !           355:        register int    ctlr = VDCTLR(io->i_unit);
        !           356:        register cdr    *ctlr_addr = (cdr *)(vddcaddr[ctlr]+IOBASE);
        !           357: 
        !           358:        dcb.opcode = function;          /* command */
        !           359:        dcb.intflg = NOINT;
        !           360:        dcb.nxtdcb = (fmt_dcb *)0;      /* end of chain */
        !           361:        dcb.operrsta  = 0;
        !           362:        dcb.devselect = (char)VDUNIT(io->i_unit);
        !           363:        dcb.trailcnt = (char)0;
        !           364:        mdcb.firstdcb = &dcb;
        !           365:        mdcb.vddcstat = 0;
        !           366:        VDDC_ATTENTION(ctlr_addr, &mdcb, ctlr_info[ctlr].ctlr_type);
        !           367:        POLLTILLDONE(ctlr_addr,&dcb,time,ctlr_info[ctlr].ctlr_type);
        !           368:        if(vdtimeout <= 0)
        !           369:                _stop(" during initialization operation.\n");
        !           370:        return dcb.operrsta;
        !           371: }
        !           372: 
        !           373: 
        !           374: /*
        !           375: **
        !           376: */
        !           377: 
        !           378: vdaccess(io, daddr, func)
        !           379: register struct iob    *io;
        !           380: dskadr                 *daddr;
        !           381: int                    func;
        !           382: {
        !           383:        register int    ctlr = VDCTLR(io->i_unit);
        !           384:        register cdr    *ctlr_addr = (cdr *)(vddcaddr[ctlr]+IOBASE);
        !           385: 
        !           386:        dcb.opcode = (short)func;               /* format sector command */
        !           387:        dcb.intflg = NOINT;
        !           388:        dcb.nxtdcb = (fmt_dcb *)0;      /* end of chain */
        !           389:        dcb.operrsta  = 0;
        !           390:        dcb.devselect = (char)VDUNIT(io->i_unit);
        !           391:        dcb.trailcnt = (char)(sizeof(trrw) / 4);
        !           392:        dcb.trail.rwtrail.memadr = io->i_ma; 
        !           393:        dcb.trail.rwtrail.wcount = ((io->i_cc + 1) / sizeof(short));
        !           394:        dcb.trail.rwtrail.disk.cylinder = daddr->cylinder;
        !           395:        dcb.trail.rwtrail.disk.track = daddr->track;
        !           396:        dcb.trail.rwtrail.disk.sector = daddr->sector;
        !           397:        mdcb.firstdcb = &dcb;
        !           398:        mdcb.vddcstat = 0;
        !           399:        VDDC_ATTENTION(ctlr_addr, &mdcb, ctlr_info[ctlr].ctlr_type);
        !           400:        POLLTILLDONE(ctlr_addr, &dcb, 60, ctlr_info[ctlr].ctlr_type);
        !           401:        if(vdtimeout <= 0)
        !           402:                _stop(" during I/O operation.\n");
        !           403:        return dcb.operrsta;
        !           404: }
        !           405: 
        !           406: /*
        !           407: **     Print_dcb() dumps the MDCB and DCB for diagnostic purposes.  This
        !           408: ** routine is called whenever a fatal error is encountered.
        !           409: */
        !           410: 
        !           411: vdprintdcb(ptr)
        !           412: register long  *ptr;
        !           413: {
        !           414:        register long   i;
        !           415:        register long   trailer_count;
        !           416: 
        !           417:        printf("Dump of MDCB: ");
        !           418:        for(i=0; i<4; i++)
        !           419:                printf("  %lx", *(ptr+i));
        !           420:        if(ptr = (long *)*ptr) {
        !           421:                printf(" and DCB:");
        !           422:                trailer_count = *(ptr+3) & 0xff;
        !           423:                for(i=0; i<7+trailer_count; i++) {
        !           424:                        uncache(ptr+i);
        !           425:                        printf("  %lx", *(ptr+i));
        !           426:                }
        !           427:        }
        !           428:        printf("\n");
        !           429:        for(i=0; i<5000000; i++) ;
        !           430: }
        !           431: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.