Annotation of cci/sys/stand/vddc.c, revision 1.1.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.