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

1.1     ! root        1: #include "fsd.h"
        !             2: #if NVD > 0
        !             3: 
        !             4: 
        !             5: /*
        !             6: **     VDDC Driver - Versabus to SMD direct interface version.
        !             7: **             Written for TAHOE vmunix, CCI-WDC 9/1/83.               
        !             8: */
        !             9: 
        !            10: #include "../h/param.h"
        !            11: #include "../h/buf.h"
        !            12: #include "../h/cmap.h"
        !            13: #include "../h/conf.h"
        !            14: #include "../h/dir.h"
        !            15: #include "../h/dk.h"
        !            16: #include "../h/map.h"
        !            17: #include "../machine/mtpr.h"
        !            18: #include "../machine/pte.h"
        !            19: #include "../h/systm.h"
        !            20: #include "../vba/vbavar.h"
        !            21: #include "../h/user.h"
        !            22: #include "../h/vmmac.h"
        !            23: #include "../h/proc.h"
        !            24: #include "../h/uio.h"
        !            25: #define        VDGENDATA
        !            26: #include "../vba/vddc.h"
        !            27: #undef VDGENDATA
        !            28: 
        !            29: 
        !            30: #define        MAX_BLOCKSIZE   MAXBPTE * NBPG
        !            31: #define        DUMPSIZE        64      /* Up to 64k at a time - controller limit */
        !            32: 
        !            33: /*
        !            34: ** Layout of minor number assignments for the VDDC devices.
        !            35: **
        !            36: **       1
        !            37: **       5                         3 2   0
        !            38: **      +---------------------------+-----+
        !            39: **      |               Unit number | FLS |
        !            40: **      +---------------------------+-----+
        !            41: **                                |    |_____ File system # ( 0-7 )
        !            42: **                                |__________ Unit # in the system
        !            43: */
        !            44: 
        !            45: #define VDUNIT(x)      (minor(x) >> 3)
        !            46: #define FILSYS(x)      (minor(x) & 0x07)
        !            47: #define PHYS(x)                (vtoph(0, (int)(x)))
        !            48: #define TRUE           1
        !            49: #define        FALSE           0
        !            50: #define        NOERROR         0
        !            51: 
        !            52: #define CTLR_ERROR     1
        !            53: #define DRIVE_ERROR    2
        !            54: #define HARD_DATA_ERROR        3
        !            55: #define SOFT_DATA_ERROR        4
        !            56: 
        !            57: #define b_cylin                b_resid
        !            58: #define b_daddr                b_error
        !            59: 
        !            60: /*
        !            61: **
        !            62: */
        !            63: 
        !            64: struct vba_ctlr        *vdminfo[NVD];
        !            65: 
        !            66: 
        !            67: /*
        !            68: **
        !            69: */
        !            70: 
        !            71: struct  vba_device     *vddinfo[NFSD];
        !            72: 
        !            73: 
        !            74: /*
        !            75: **
        !            76: */
        !            77: 
        !            78: int    vdprobe();              /* See if VDDC is really there */
        !            79: int    vdslave();              /* See if drive is really there */
        !            80: int    vdattach();             /* Enter a drive in internal tables */
        !            81: int    vddgo();                /* Old VAX function, not used. */
        !            82: 
        !            83: 
        !            84: 
        !            85: /*
        !            86: **
        !            87: */
        !            88: 
        !            89: struct vba_driver vddriver = {
        !            90:        vdprobe, vdslave, vdattach, vddgo, vddcaddr, 
        !            91:        "", vddinfo, "", vdminfo
        !            92: };
        !            93: 
        !            94: 
        !            95: /*
        !            96: **
        !            97: */
        !            98: 
        !            99: typedef struct {
        !           100:        struct buf      raw_q_element;
        !           101:        short           sec_per_blk;
        !           102:        short           sec_per_cyl;
        !           103:        char            status;
        !           104:        struct buf      xfer_queue;
        !           105:        int             drive_type;
        !           106:        fs_tab          info;
        !           107: } unit_tab;
        !           108: 
        !           109: /*
        !           110: **
        !           111: */
        !           112: 
        !           113: typedef struct {
        !           114:        char            ctlr_type;              /*  */
        !           115:        char            *map;                   /*  */
        !           116:        char            *utl;                   /*  */
        !           117:        unsigned        cur_slave : 8;          /* last active unit number */
        !           118:        unsigned        int_expected : 1;       /* expect an interupt */
        !           119:        unsigned        ctlr_started : 1;       /* start command was issued */
        !           120:        unsigned        overlap_seeks : 1;      /* Should overlap seeks */
        !           121:        unsigned        off_cylinder : 16;      /* Off cylinder bit map */
        !           122:        unsigned        unit_type[16];          /* type of each slave */
        !           123:        long            cur_cyl[16];            /* cylinder last selected */
        !           124:        long            cur_trk[16];            /* track last selected */
        !           125:        fmt_mdcb        ctlr_mdcb;              /* controller mdcb */
        !           126:        fmt_dcb         ctlr_dcb;               /* R/W dcb */
        !           127:        fmt_dcb         seek_dcb[4];            /* dcbs for overlapped seeks */
        !           128:        char            rawbuf[MAX_BLOCKSIZE];  /* buffer for raw/swap i/o */
        !           129: } ctlr_tab;
        !           130: 
        !           131: 
        !           132: /*
        !           133: **
        !           134: */
        !           135: 
        !           136: extern char    vd0utl[];
        !           137: #if NVD > 1
        !           138: extern char    vd1utl[];
        !           139: #if NVD > 2
        !           140: extern char    vd2utl[];
        !           141: #if NVD > 3
        !           142: extern char    vd3utl[];
        !           143: #endif
        !           144: #endif
        !           145: #endif
        !           146: 
        !           147: 
        !           148: /*
        !           149: **
        !           150: */
        !           151: 
        !           152: ctlr_tab       vdctlr_info[NVD] = {
        !           153:         {UNKNOWN, (char *)VD0map, vd0utl, 0, FALSE, FALSE, TRUE, 0,
        !           154:                {UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
        !           155:                 UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
        !           156:                 UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
        !           157:                 UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN}}
        !           158: #if NVD > 1
        !           159:        ,{UNKNOWN, (char *)VD1map, vd1utl, 0, FALSE, FALSE, TRUE, 0,
        !           160:                {UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
        !           161:                 UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
        !           162:                 UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
        !           163:                 UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN}}
        !           164: #if NVD > 2
        !           165:        ,{UNKNOWN, (char *)VD2map, vd2utl, 0, FALSE, FALSE, TRUE, 0,
        !           166:                {UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
        !           167:                 UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
        !           168:                 UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
        !           169:                 UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN}}
        !           170: #if NVD > 3
        !           171:        ,{UNKNOWN, (char *)VD3map, vd3utl, 0, FALSE, FALSE, TRUE, 0,
        !           172:                {UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
        !           173:                 UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
        !           174:                 UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN,
        !           175:                 UNKNOWN,UNKNOWN,UNKNOWN,UNKNOWN}}
        !           176: #endif
        !           177: #endif
        !           178: #endif
        !           179: };
        !           180: 
        !           181: 
        !           182: /*
        !           183: **
        !           184: */
        !           185: 
        !           186: unit_tab       vdunit_info[NFSD];
        !           187: 
        !           188: 
        !           189: /*
        !           190: **     See if the controller is really there. 
        !           191: **  if TRUE - initialize the controller.
        !           192: */
        !           193: 
        !           194: vdprobe(ctlr_addr)
        !           195: cdr    *ctlr_addr;
        !           196: {
        !           197:        if(!badaddr(ctlr_addr, 2)) {
        !           198:                ctlr_addr->cdr_reset = 0xffffffff;
        !           199:                DELAY(1000000);
        !           200:                if(ctlr_addr->cdr_reset != 0xffffffff) {
        !           201:                        vddriver.ud_mname = "VSMD Controller #";
        !           202:                        DELAY(1000000);
        !           203:                }
        !           204:                else {
        !           205:                        vddriver.ud_mname = "SMD/E Controller #";
        !           206:                        ctlr_addr->cdr_reserved = 0x0;
        !           207:                        DELAY(3000000);
        !           208:                }
        !           209:                return TRUE;
        !           210:        }
        !           211:        return FALSE;                           /* no controller */     
        !           212: }
        !           213: 
        !           214: 
        !           215: /*
        !           216: ** See if a drive is really there
        !           217: ** Try to Reset/Configure the drive, then test its status.
        !           218: */
        !           219: 
        !           220: vdslave(vba_dev_info, ctlr_addr)
        !           221: register struct vba_device     *vba_dev_info;
        !           222: register cdr                   *ctlr_addr;
        !           223: {
        !           224:        register int            ctlr = vba_dev_info->ui_ctlr;
        !           225:        register ctlr_tab       *c_info = &vdctlr_info[ctlr];
        !           226:        register int            unit = vba_dev_info->ui_unit;
        !           227:        register unit_tab       *u_info = &vdunit_info[unit];
        !           228:        register int            slave = vba_dev_info->ui_slave;
        !           229:        register int            type;
        !           230:        register fmt_mdcb       *mdcb = &c_info->ctlr_mdcb;
        !           231:        register fmt_dcb        *dcb = &c_info->ctlr_dcb;
        !           232: 
        !           233:        if(c_info->ctlr_type == UNKNOWN) {
        !           234:                ctlr_addr->cdr_reset = 0xffffffff;
        !           235:                DELAY(1000000);
        !           236:                if(ctlr_addr->cdr_reset != 0xffffffff) {
        !           237:                        c_info->ctlr_type = SMDCTLR;
        !           238:                        c_info->overlap_seeks = FALSE;
        !           239:                        DELAY(1000000);
        !           240:                }
        !           241:                else {
        !           242:                        c_info->overlap_seeks = TRUE;
        !           243:                        c_info->ctlr_type = SMD_ECTLR;
        !           244:                        ctlr_addr->cdr_reserved = 0x0;
        !           245:                        DELAY(3000000);
        !           246:                        ctlr_addr->cdr_csr = 0;
        !           247:                        ctlr_addr->mdcb_tcf = AM_ENPDA;
        !           248:                        ctlr_addr->dcb_tcf = AM_ENPDA;
        !           249:                        ctlr_addr->trail_tcf = AM_ENPDA;
        !           250:                        ctlr_addr->data_tcf = AM_ENPDA;
        !           251:                        ctlr_addr->cdr_ccf = CCF_STS | XMD_32BIT | BSZ_16WRD |
        !           252:                            CCF_ENP | CCF_EPE | CCF_EDE | CCF_ECE | CCF_ERR;
        !           253:                }
        !           254:                if(vdaccess_with_no_trailer(ctlr_addr,ctlr,slave,INIT,10) & 
        !           255:                    HRDERR) {
        !           256:                        printf("\nVDDC: Controller #%d init error.\n", ctlr);
        !           257:                        return  FALSE;
        !           258:                }
        !           259:                if(vdaccess_with_no_trailer(ctlr_addr,ctlr,slave,DIAG,10) & 
        !           260:                    HRDERR) {
        !           261:                        printf("\nVDDC: Controller #%d diagnostic error.\n",ctlr);
        !           262:                        return  FALSE;
        !           263:                }
        !           264:        }
        !           265:        /*
        !           266:         * Seek on all drive types starting from the largest one.
        !           267:         * a successful seek to the last sector/cylinder/track verifies 
        !           268:         * the drive type connected to this port. 
        !           269:         */
        !           270:        for (type = 0; type < nvddrv; type++) { 
        !           271:                if((c_info->ctlr_type == SMDCTLR) && (vdst[type].nsec != 32))
        !           272:                        continue;
        !           273:                if(vdconfigure_drive(ctlr_addr, ctlr, slave, type, 0)) {
        !           274:                        dcb->opcode = (short)RD;
        !           275:                        dcb->intflg = NOINT;
        !           276:                        dcb->nxtdcb = (fmt_dcb *)0;     /* end of chain */
        !           277:                        dcb->operrsta  = 0;
        !           278:                        dcb->devselect = (char)slave;
        !           279:                        dcb->trailcnt = (char)(sizeof(trrw) / sizeof(long));
        !           280:                        dcb->trail.rwtrail.memadr=(char *)PHYS(c_info->rawbuf); 
        !           281:                        dcb->trail.rwtrail.wcount =
        !           282:                            vdst[type].secsize/sizeof(short);
        !           283:                        dcb->trail.rwtrail.disk.cylinder = vdst[type].ncyl - 2;
        !           284:                        dcb->trail.rwtrail.disk.track = vdst[type].ntrak - 1;
        !           285:                        dcb->trail.rwtrail.disk.sector=vdst[type].nsec - 1;
        !           286:                        mdcb->firstdcb = (fmt_dcb *)(PHYS(dcb));
        !           287:                        mdcb->vddcstat = 0;
        !           288:                        VDDC_ATTENTION(ctlr_addr, (fmt_mdcb *)(PHYS(mdcb)),
        !           289:                            c_info->ctlr_type);
        !           290:                        POLLTILLDONE(ctlr_addr, dcb, 60, c_info->ctlr_type);
        !           291:                        if(vdtimeout <= 0) {
        !           292:                                printf(" during probe operation.\n");
        !           293:                        }
        !           294:                        if(!(dcb->operrsta & HRDERR))
        !           295:                                break;
        !           296:                }
        !           297:                else
        !           298:                        return FALSE;
        !           299:        }
        !           300:        if (type >= nvddrv) {
        !           301:                /*
        !           302:                 *      If reached here, a drive which is not defined in the 
        !           303:                 * 'vdst' tables is connected. Cannot set it's type.
        !           304:                 */
        !           305:                printf("VDDC: Counld not identify controller #%d, drive #%d!\n",
        !           306:                    ctlr, slave);
        !           307:                return FALSE;
        !           308:        }
        !           309:        u_info->drive_type = type;
        !           310:        u_info->info = vdst[type];
        !           311:        u_info->sec_per_blk = DEV_BSIZE / u_info->info.secsize;
        !           312:        vba_dev_info->ui_type = type;
        !           313:        vba_dev_info->ui_dk = TRUE;
        !           314:        vddriver.ud_dname = u_info->info.type_name;
        !           315:        return TRUE;
        !           316: }
        !           317: 
        !           318: 
        !           319: 
        !           320: /*
        !           321: **
        !           322: */
        !           323: 
        !           324: vdconfigure_drive(ctlr_addr, ctlr, slave, type, pass)
        !           325: cdr            *ctlr_addr;
        !           326: register int   ctlr, slave, type, pass;
        !           327: {
        !           328:        register ctlr_tab       *c_info = &vdctlr_info[ctlr];
        !           329: 
        !           330:        c_info->ctlr_dcb.opcode = RSTCFG;               /* command */
        !           331:        c_info->ctlr_dcb.intflg = NOINT;
        !           332:        c_info->ctlr_dcb.nxtdcb = (fmt_dcb *)0; /* end of chain */
        !           333:        c_info->ctlr_dcb.operrsta  = 0;
        !           334:        c_info->ctlr_dcb.devselect = (char)slave;
        !           335:        c_info->ctlr_dcb.trail.rstrail.ncyl = vdst[type].ncyl;
        !           336:        c_info->ctlr_dcb.trail.rstrail.nsurfaces = vdst[type].ntrak;
        !           337:        if(c_info->ctlr_type == SMD_ECTLR) {
        !           338:                c_info->ctlr_dcb.trailcnt = (char)4;
        !           339:                c_info->ctlr_dcb.trail.rstrail.nsectors = vdst[type].nsec;
        !           340:                c_info->ctlr_dcb.trail.rstrail.slip_sec = vdst[type].nslip;
        !           341:        }
        !           342:        else
        !           343:                c_info->ctlr_dcb.trailcnt = (char)2;
        !           344:        c_info->ctlr_mdcb.firstdcb = (fmt_dcb *)(PHYS(&c_info->ctlr_dcb));
        !           345:        c_info->ctlr_mdcb.vddcstat = 0;
        !           346:        VDDC_ATTENTION(ctlr_addr, (fmt_mdcb *)(PHYS(&c_info->ctlr_mdcb)),
        !           347:            c_info->ctlr_type);
        !           348:        POLLTILLDONE(ctlr_addr, &c_info->ctlr_dcb, 5, c_info->ctlr_type);
        !           349:        if(vdtimeout <= 0) {
        !           350:                printf(" during drive configuration.\n");
        !           351:                return FALSE;
        !           352:        }
        !           353:        if(c_info->ctlr_dcb.operrsta & HRDERR) {
        !           354:                if(!(c_info->ctlr_dcb.operrsta & (NOTCYLERR | DRVNRDY)))
        !           355:                        printf("\nVDDC: Configuration error.\n");
        !           356:                else if(pass == 0) {
        !           357:                        vdstart_drive(ctlr_addr, ctlr, slave);
        !           358:                        return vdconfigure_drive(ctlr_addr,ctlr,slave,type,1);
        !           359:                }
        !           360:                else if(pass == 2)
        !           361:                        return vdconfigure_drive(ctlr_addr,ctlr,slave,type,3);
        !           362:                return FALSE;
        !           363:        }
        !           364:        return TRUE;
        !           365: }
        !           366: 
        !           367: 
        !           368: /*
        !           369: **
        !           370: */
        !           371: 
        !           372: vdstart_drive(ctlr_addr, ctlr, slave)
        !           373: cdr            *ctlr_addr;
        !           374: register int   ctlr, slave;
        !           375: {
        !           376:        printf("\nVDDC: Attempting to start drive #%d.  Please wait...", slave);
        !           377:        if(vdctlr_info[ctlr].ctlr_started) {
        !           378:                DELAY(5500000);
        !           379:                printf("\n");
        !           380:                return TRUE;
        !           381:        }
        !           382:        vdctlr_info[ctlr].ctlr_started = TRUE;
        !           383:        if(vdaccess_with_no_trailer(ctlr_addr, ctlr, 0, VDSTART, (slave*6)+62)
        !           384:            & HRDERR) {
        !           385:                printf("\n");
        !           386:                return  FALSE;
        !           387:        }
        !           388:        DELAY((slave * 5500000) + 62000000);
        !           389:        printf("\n");
        !           390:        return TRUE;
        !           391: }
        !           392: 
        !           393: 
        !           394: /*
        !           395: **
        !           396: */
        !           397: 
        !           398: vdaccess_with_no_trailer(ctlr_addr, ctlr, unit, function, time)
        !           399: register cdr           *ctlr_addr;
        !           400: register int           ctlr, unit, function, time;
        !           401: {
        !           402:        fmt_mdcb        *mdcb = &vdctlr_info[ctlr].ctlr_mdcb;
        !           403:        fmt_dcb         *dcb = &vdctlr_info[ctlr].ctlr_dcb;
        !           404: 
        !           405:        dcb->opcode = function;         /* command */
        !           406:        dcb->intflg = NOINT;
        !           407:        dcb->nxtdcb = (fmt_dcb *)0;     /* end of chain */
        !           408:        dcb->operrsta  = 0;
        !           409:        dcb->devselect = (char)unit;
        !           410:        dcb->trailcnt = (char)0;
        !           411:        mdcb->firstdcb = (fmt_dcb *)(PHYS(dcb));
        !           412:        mdcb->vddcstat = 0;
        !           413:        VDDC_ATTENTION(ctlr_addr, (fmt_mdcb *)(PHYS(mdcb)),
        !           414:            vdctlr_info[ctlr].ctlr_type);
        !           415:        POLLTILLDONE(ctlr_addr, dcb, time, vdctlr_info[ctlr].ctlr_type);
        !           416:        if(vdtimeout <= 0) {
        !           417:                printf(" during initialization operation.\n");
        !           418:                return (DCBCMP | ANYERR | HRDERR | OPABRT);
        !           419:        }
        !           420:        return dcb->operrsta;
        !           421: }
        !           422: 
        !           423: 
        !           424: /*
        !           425: **
        !           426: */
        !           427: 
        !           428: vdattach(vba_dev_info)
        !           429: struct vba_device *vba_dev_info;
        !           430: {
        !           431:        register int            unit = vba_dev_info->ui_unit;
        !           432:        register unit_tab       *u_info = &vdunit_info[unit];
        !           433:        register ctlr_tab       *c_info = &vdctlr_info[vba_dev_info->ui_ctlr];
        !           434:        register struct buf     *c_queue = &vba_dev_info->ui_mi->um_tab;
        !           435:        register struct buf     *u_queue = c_queue->b_forw;
        !           436:        register struct buf     *start_queue = u_queue;
        !           437:        register int            type = vba_dev_info->ui_type;
        !           438:        register fs_tab         *fs = &u_info->info;
        !           439: 
        !           440:        u_info->info = vdst[type];
        !           441:        u_info->sec_per_blk = DEV_BSIZE / u_info->info.secsize;
        !           442:        u_info->sec_per_cyl = u_info->info.nsec * u_info->info.ntrak;
        !           443:        u_info->xfer_queue.b_dev = vba_dev_info->ui_slave;
        !           444:        c_info->unit_type[vba_dev_info->ui_slave] = type;
        !           445:        /* load unit into controller's active unit list */
        !           446:        if(u_queue == NULL) {
        !           447:                c_queue->b_forw = &u_info->xfer_queue;
        !           448:                u_info->xfer_queue.b_forw = &u_info->xfer_queue;
        !           449:                u_info->xfer_queue.b_back = &u_info->xfer_queue;
        !           450:        }
        !           451:        else {
        !           452:                while(u_queue->b_forw != start_queue)
        !           453:                        u_queue = u_queue->b_forw;
        !           454:                u_info->xfer_queue.b_forw = start_queue;
        !           455:                u_info->xfer_queue.b_back = u_queue;
        !           456:                u_queue->b_forw = &u_info->xfer_queue;
        !           457:                start_queue->b_back = &u_info->xfer_queue;
        !           458:        }
        !           459:        /*
        !           460:        **  (60 / rpm) / (number of sectors per track * (bytes per sector / 2))
        !           461:        */
        !           462:        dk_mspw[unit] = 120.0 / (fs->rpm * fs->nsec * fs->secsize);
        !           463: }
        !           464: 
        !           465: 
        !           466: /*
        !           467: ** Historic VAX routine.
        !           468: */
        !           469: 
        !           470: vddgo(um)
        !           471: struct vba_ctlr *um;
        !           472: {
        !           473: }
        !           474: 
        !           475: 
        !           476: /*
        !           477: **
        !           478: */
        !           479: 
        !           480: vdstrategy(request)
        !           481: register struct buf *request;
        !           482: {
        !           483:        register int                    unit = VDUNIT(request->b_dev);
        !           484:        register struct vba_device      *vba_dev_info = vddinfo[unit];
        !           485:        register int                    par = FILSYS(request->b_dev);
        !           486:        register unit_tab               *u_info = &vdunit_info[unit];
        !           487:        register ctlr_tab               *c_info;
        !           488:        register fs_tab                 *fs = &u_info->info;
        !           489:        register int                    blks, blk, priority, slave;
        !           490: 
        !           491:        if((request->b_bcount != 0) && (vba_dev_info != NULL) &&
        !           492:            (vba_dev_info->ui_alive != 0)&&(fs->partition[par].par_len != 0)) {
        !           493:                slave = vba_dev_info->ui_slave;
        !           494:                c_info = &vdctlr_info[vba_dev_info->ui_ctlr];
        !           495:                blks = (request->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
        !           496:                if(fs->partition[par].par_len < (request->b_blkno + blks)) {
        !           497:                        blks = fs->partition[par].par_len - request->b_blkno;
        !           498:                        if(blks > 0)
        !           499:                                request->b_bcount = blks * DEV_BSIZE;
        !           500:                        else
        !           501:                                goto error;
        !           502:                }
        !           503:                blk = request->b_blkno + fs->partition[par].par_start;
        !           504:                blk *= u_info->sec_per_blk;
        !           505:                request->b_daddr = (blk / fs->nsec) % fs->ntrak;
        !           506:                request->b_cylin = blk / u_info->sec_per_cyl;
        !           507:                buf_setup (request, u_info->info.secsize);
        !           508:                priority = spl7();
        !           509:                if(u_info->xfer_queue.av_forw == NULL)
        !           510:                        if((request->b_cylin != c_info->cur_cyl[slave]) ||
        !           511:                            (request->b_daddr)!=(c_info->cur_trk[slave]))
        !           512:                                c_info->off_cylinder |= 1 << slave;
        !           513:                request->b_daddr |= (blk % fs->nsec) << 8;
        !           514:                disksort(&u_info->xfer_queue, request);
        !           515:                if(!vddinfo[unit]->ui_mi->um_tab.b_active++) {
        !           516:                        splx(priority);
        !           517:                        vdstart(vddinfo[unit]->ui_mi);
        !           518:                }
        !           519:                else    splx(priority);
        !           520:                return;
        !           521:        }
        !           522: error: 
        !           523:        request->b_flags |= B_ERROR;
        !           524:        request->b_error = ENXIO;
        !           525:        request->b_resid = request->b_bcount;
        !           526:        iodone(request);
        !           527: }
        !           528: 
        !           529: 
        !           530: /*
        !           531:  * Start up a transfer on a drive.
        !           532:  */
        !           533: vdstart(controller_info)
        !           534: register struct vba_ctlr *controller_info;
        !           535: {
        !           536:        register struct buf     *c_queue = &controller_info->um_tab;
        !           537:        register struct buf     *u_queue = c_queue->b_forw;
        !           538: 
        !           539:        /* Search for next ready unit */
        !           540:        c_queue->b_forw = c_queue->b_forw->b_forw;
        !           541:        u_queue = c_queue->b_forw;
        !           542:        do {
        !           543:                if(u_queue->av_forw != NULL) {
        !           544:                        c_queue->b_forw = u_queue;
        !           545:                        vdexecute(controller_info, c_queue, u_queue);
        !           546:                        return;
        !           547:                }
        !           548:                u_queue = u_queue->b_forw;
        !           549:        } while(u_queue != c_queue->b_forw);
        !           550: }
        !           551: 
        !           552: 
        !           553: vdload_seeks(c_info, u_queue)
        !           554: register ctlr_tab      *c_info;
        !           555: register struct buf    *u_queue;
        !           556: {
        !           557:        register int            unit, slave, seek_count = 0;
        !           558:        register fmt_dcb        *dcb;
        !           559:        register struct buf     *request;
        !           560:        register int            new_cyl;
        !           561:        register struct buf     *start_queue = u_queue;
        !           562: 
        !           563:        do {
        !           564:                if((request = u_queue->av_forw) != NULL) {
        !           565:                        unit = VDUNIT(request->b_dev);
        !           566:                        slave = vddinfo[unit]->ui_slave;
        !           567:                        if(c_info->off_cylinder & (1 << slave)) {
        !           568:                                c_info->off_cylinder &= ~(1 << slave);
        !           569:                                if(c_info->cur_cyl[slave] != request->b_cylin) {
        !           570:                                        c_info->cur_cyl[slave]=request->b_cylin;
        !           571:                                        dk_seek[unit]++;
        !           572:                                }
        !           573:                                c_info->cur_trk[slave] = request->b_daddr&0xff;
        !           574:                                dcb = &c_info->seek_dcb[seek_count++];
        !           575:                                dcb->opcode = SEEK;
        !           576:                                dcb->intflg = NOINT | INT_PBA;
        !           577:                                dcb->operrsta  = 0;
        !           578:                                dcb->devselect = (char)slave;
        !           579:                                dcb->trailcnt = (char)1;
        !           580:                                dcb->trail.sktrail.skaddr.cylinder =
        !           581:                                    request->b_cylin;
        !           582:                                dcb->trail.sktrail.skaddr.track =
        !           583:                                    request->b_daddr & 0xff;
        !           584:                                dcb->trail.sktrail.skaddr.sector = 0;
        !           585:                        }
        !           586:                }
        !           587:                u_queue = u_queue->b_forw;
        !           588:        } while((u_queue != start_queue) && (seek_count < 4));
        !           589:        return seek_count;
        !           590: }
        !           591: 
        !           592: 
        !           593: /*
        !           594: **
        !           595: */
        !           596: 
        !           597: vdexecute(controller_info, c_queue, u_queue)
        !           598: register struct vba_ctlr *controller_info;
        !           599: register struct buf     *c_queue, *u_queue;
        !           600: {
        !           601:        extern                  vd_int_timeout();
        !           602:        register struct buf     *request = u_queue->av_forw;
        !           603:        register int            ctlr = controller_info->um_ctlr;
        !           604:        register ctlr_tab       *c_info = &vdctlr_info[ctlr];
        !           605:        register int            unit = VDUNIT(request->b_dev);
        !           606:        register int            slave = vddinfo[unit]->ui_slave;
        !           607:        register fs_tab         *fs = &vdunit_info[unit].info;
        !           608:        register fmt_mdcb       *mdcb = &c_info->ctlr_mdcb; 
        !           609:        register fmt_dcb        *dcb = &c_info->ctlr_dcb; 
        !           610:        
        !           611:        if((c_info->off_cylinder & ~(1<<slave)) && c_info->overlap_seeks) {
        !           612:                register int    index;
        !           613:                register int    seek_count = vdload_seeks(c_info, u_queue);
        !           614: 
        !           615:                mdcb->firstdcb = (fmt_dcb *)PHYS(&c_info->seek_dcb[0]);
        !           616:                for(index = 1; index < seek_count; index++)
        !           617:                        c_info->seek_dcb[index-1].nxtdcb = 
        !           618:                            (fmt_dcb *)PHYS(&c_info->seek_dcb[index]);
        !           619:                c_info->seek_dcb[seek_count-1].nxtdcb = (fmt_dcb *)PHYS(dcb);
        !           620:        }
        !           621:        else {
        !           622:                if(request->b_cylin != c_info->cur_cyl[slave]) {
        !           623:                        c_info->cur_cyl[slave] = request->b_cylin;
        !           624:                        dk_seek[unit]++;
        !           625:                }
        !           626:                c_info->cur_trk[slave] = request->b_daddr & 0xff;
        !           627:                c_info->off_cylinder = 0;
        !           628:                mdcb->firstdcb = (fmt_dcb *)(PHYS(dcb));
        !           629:        }
        !           630:        dcb->opcode = (request->b_flags & B_READ) ? RD : WD;
        !           631:        dcb->intflg = INTDONE;
        !           632:        dcb->nxtdcb = (fmt_dcb *)0;     /* end of chain */
        !           633:        dcb->operrsta  = 0;
        !           634:        dcb->devselect = (char)slave;
        !           635:        dcb->trailcnt = (char)(sizeof(trrw) / sizeof(long));
        !           636:        dcb->trail.rwtrail.memadr = (char *)get_ioadr(request, c_info->rawbuf,
        !           637:            c_info->map, c_info->utl);
        !           638:        dcb->trail.rwtrail.wcount=(short)((request->b_bcount+1)/sizeof(short));
        !           639:        dcb->trail.rwtrail.disk.cylinder = request->b_cylin;
        !           640:        dcb->trail.rwtrail.disk.track = request->b_daddr & 0xff;
        !           641:        dcb->trail.rwtrail.disk.sector = request->b_daddr >> 8;
        !           642:        mdcb->vddcstat = 0;
        !           643:        dk_wds[unit] += request->b_bcount / 32;
        !           644:        c_info->int_expected = TRUE;
        !           645:        timeout(vd_int_timeout, ctlr, 20*60);
        !           646:        dk_busy |= 1 << unit;
        !           647: #ifdef VDDCPERF
        !           648:        scope_out(1);
        !           649: #endif
        !           650:        VDDC_ATTENTION((cdr *)(vdminfo[ctlr]->um_addr),(fmt_mdcb *)(PHYS(mdcb)),
        !           651:            c_info->ctlr_type);
        !           652: }
        !           653: 
        !           654: 
        !           655: /*
        !           656: **
        !           657: */
        !           658: 
        !           659: vd_int_timeout(ctlr)
        !           660: register int   ctlr;
        !           661: {
        !           662:        register ctlr_tab       *c_info = &vdctlr_info[ctlr];
        !           663:        register fmt_mdcb       *mdcb = &c_info->ctlr_mdcb;
        !           664:        register fmt_dcb        *dcb = &c_info->ctlr_dcb;
        !           665: 
        !           666:        uncache(&dcb->operrsta);
        !           667:        printf("\nVDDC: Controller #%d didn't interupt!", ctlr);
        !           668:        printf("  Status = %x", dcb->operrsta);
        !           669:        if(c_info->ctlr_type == SMD_ECTLR) {
        !           670:                uncache(&dcb->err_code);
        !           671:                printf("  Error code = %x", dcb->err_code);
        !           672:        }
        !           673:        printf("\n");
        !           674:        if(!(dcb->operrsta & DCBCMP)) { 
        !           675:                VDDC_ABORT((cdr *)(vdminfo[ctlr]->um_addr), c_info->ctlr_type);
        !           676:                dcb->operrsta |= DCBUSC | DCBABT | ANYERR | HRDERR | CTLRERR;
        !           677:        }
        !           678:        vdintr(ctlr);
        !           679: }
        !           680: 
        !           681: 
        !           682: /*
        !           683:  * Handle a disk interrupt.
        !           684:  */
        !           685: vdintr(ctlr)
        !           686: register int   ctlr;
        !           687: {
        !           688:        extern                  vd_int_timeout();
        !           689:        register ctlr_tab       *c_info = &vdctlr_info[ctlr];
        !           690: 
        !           691: 
        !           692:        untimeout(vd_int_timeout, ctlr);
        !           693: #ifdef VDDCPERF
        !           694:        scope_out(2);
        !           695: #endif
        !           696:        if(c_info->int_expected) {
        !           697:                register struct buf     *u_queue=vdminfo[ctlr]->um_tab.b_forw;
        !           698:                register struct buf     *request = u_queue->av_forw;
        !           699:                register int            slave = u_queue->b_dev;
        !           700:                register int            unit = VDUNIT(request->b_dev);
        !           701:                register unit_tab       *u_info = &vdunit_info[unit];
        !           702:                register fmt_mdcb       *mdcb = &c_info->ctlr_mdcb;
        !           703:                register fmt_dcb        *dcb = &c_info->ctlr_dcb;
        !           704:                register int            priority;
        !           705: 
        !           706:                dk_busy &= ~(1 << unit);
        !           707:                dk_xfer[unit]++;
        !           708:                c_info->int_expected = FALSE;
        !           709:                uncache(&mdcb->intdcb);
        !           710:                uncache(&dcb->operrsta);
        !           711:                if(c_info->ctlr_type == SMD_ECTLR)
        !           712:                        uncache(&dcb->err_code);
        !           713:                switch(vddecode_error(request, dcb)) {
        !           714:                        case CTLR_ERROR :
        !           715:                                if(vdminfo[ctlr]->um_tab.b_errcnt >= 2)
        !           716:                                        vdhard_error(c_info, request, dcb);
        !           717:                                vdreset_ctlr(vdminfo[ctlr]->um_addr,ctlr);
        !           718:                                if(vdminfo[ctlr]->um_tab.b_errcnt++ < 2) {
        !           719:                                        vdminfo[ctlr]->um_tab.b_forw =
        !           720:                                            u_queue->b_back;
        !           721:                                        vdstart(vdminfo[ctlr]);
        !           722:                                        return;
        !           723:                                }
        !           724:                                request->b_resid = request->b_bcount;
        !           725:                                break;
        !           726:                        case DRIVE_ERROR :
        !           727:                                if(vdminfo[ctlr]->um_tab.b_errcnt >= 2)
        !           728:                                        vdhard_error(c_info, request, dcb);
        !           729:                                reset_drive(vdminfo[ctlr]->um_addr,
        !           730:                                    ctlr, slave, 2);
        !           731:                                if(vdminfo[ctlr]->um_tab.b_errcnt++ < 2) {
        !           732:                                        vdminfo[ctlr]->um_tab.b_forw =
        !           733:                                            u_queue->b_back;
        !           734:                                        vdstart(vdminfo[ctlr]);
        !           735:                                        return;
        !           736:                                }
        !           737:                                request->b_resid = request->b_bcount;
        !           738:                                break;
        !           739:                        case HARD_DATA_ERROR :
        !           740:                                vdhard_error(c_info, request, dcb);
        !           741:                                request->b_resid = 0;
        !           742:                                break;
        !           743:                        case SOFT_DATA_ERROR :
        !           744:                                vdsoft_error(c_info, request, dcb);
        !           745:                        default :
        !           746:                                request->b_error = 0;
        !           747:                                request->b_resid = 0;
        !           748:                                break;
        !           749:                }
        !           750:                end_transfer(request, c_info->rawbuf, c_info->map, c_info->utl);
        !           751:                priority = spl7();
        !           752:                u_queue->av_forw = request->av_forw;
        !           753:                if(u_queue->av_back == request)
        !           754:                        u_queue->av_back = NULL;
        !           755:                else {
        !           756:                        register struct buf     *next;
        !           757: 
        !           758:                        unit = VDUNIT(u_queue->av_forw->b_dev);
        !           759:                        slave = vddinfo[unit]->ui_slave;
        !           760:                        next = u_queue->av_forw;
        !           761:                        if((next->b_cylin != c_info->cur_cyl[slave]) ||
        !           762:                            ((next->b_daddr & 0xff) != c_info->cur_trk[slave]))
        !           763:                                c_info->off_cylinder |= 1 << slave;
        !           764:                }
        !           765:                splx(priority);
        !           766:                vdminfo[ctlr]->um_tab.b_errcnt = 0;
        !           767:                vdminfo[ctlr]->um_tab.b_active--;
        !           768: #ifdef VDDCPERF
        !           769:                scope_out(3);
        !           770: #endif
        !           771:                if(request->b_flags & B_ERROR)
        !           772:                        request->b_error = EIO;
        !           773:                iodone(request);
        !           774:                vdstart(vdminfo[ctlr]);
        !           775:                return;
        !           776:        }
        !           777:        printf("\nVDDC: Unexpected interupt from controller #%d!\n", ctlr);
        !           778: }
        !           779: 
        !           780: 
        !           781: /*
        !           782: **
        !           783: */
        !           784: 
        !           785: vddecode_error(request, dcb)
        !           786: register struct buf    *request;
        !           787: register fmt_dcb       *dcb;
        !           788: {
        !           789:        register int     unit = VDUNIT(request->b_dev);
        !           790: 
        !           791:        if(dcb->operrsta & HRDERR) {
        !           792:                if (dcb->operrsta & (HCRCERR | HCMPERR | UCDATERR | WPTERR |
        !           793:                    DSEEKERR | NOTCYLERR |DRVNRDY | INVDADR))
        !           794:                        return DRIVE_ERROR;
        !           795:                else if(dcb->operrsta & (CTLRERR | OPABRT | INVCMD | DNEMEM))
        !           796:                        return CTLR_ERROR;
        !           797:                return HARD_DATA_ERROR;
        !           798:        }
        !           799:        if(dcb->operrsta & SFTERR)
        !           800:                return SOFT_DATA_ERROR;
        !           801:        return NOERROR;
        !           802: }
        !           803: 
        !           804: 
        !           805: /*
        !           806: **
        !           807: */
        !           808: 
        !           809: vdhard_error(c_info, request, dcb)
        !           810: ctlr_tab               *c_info; 
        !           811: register struct buf    *request;
        !           812: register fmt_dcb       *dcb;
        !           813: {
        !           814:        register int            delta;
        !           815:        register int            unit = VDUNIT(request->b_dev);
        !           816:        register unit_tab       *u_info = &vdunit_info[unit];
        !           817:        register int            blk = request->b_blkno * u_info->sec_per_blk;
        !           818: 
        !           819:        request->b_flags |= B_ERROR;
        !           820:        delta = (request->b_bcount+u_info->info.secsize-1)/u_info->info.secsize;
        !           821:        harderr(request, u_info->info.type_name);
        !           822:        printf("- Hard error between sectors %d and %d.",
        !           823:            blk, blk + delta);
        !           824:        printf("  Status = 0x%x", dcb->operrsta);
        !           825:        if(c_info->ctlr_type == SMD_ECTLR)
        !           826:                printf(", Error code = 0x%x", dcb->err_code);
        !           827:        printf("\n");
        !           828: }
        !           829: 
        !           830: 
        !           831: /*
        !           832: **
        !           833: */
        !           834: 
        !           835: vdsoft_error(c_info, request, dcb)
        !           836: ctlr_tab               *c_info; 
        !           837: register struct buf    *request;
        !           838: register fmt_dcb       *dcb;
        !           839: {
        !           840:        register int            delta;
        !           841:        register int            unit = VDUNIT(request->b_dev);
        !           842:        register unit_tab       *u_info = &vdunit_info[unit];
        !           843:        register int            blk = request->b_blkno * u_info->sec_per_blk;
        !           844: 
        !           845:        delta = (request->b_bcount+u_info->info.secsize-1)/u_info->info.secsize;
        !           846:        harderr(request, u_info->info.type_name);
        !           847:        printf("- Corrected soft error between sectors %d and %d.",
        !           848:            blk, blk + delta);
        !           849:        printf("  Status = 0x%x", dcb->operrsta);
        !           850:        if(c_info->ctlr_type == SMD_ECTLR)
        !           851:                printf(", Error code = 0x%x", dcb->err_code);
        !           852:        printf("\n");
        !           853: }
        !           854: 
        !           855: 
        !           856: /*
        !           857: **
        !           858: */
        !           859: 
        !           860: vdopen(dev, flag)
        !           861: register dev_t dev;
        !           862: int flag;
        !           863: {
        !           864:        register unit = VDUNIT(dev);
        !           865:        register struct vba_device *vba_dev_info = vddinfo[unit];
        !           866: 
        !           867:        if((vba_dev_info == 0) ||
        !           868:            (vba_dev_info->ui_alive == 0) ||
        !           869:            (vba_dev_info->ui_type >= nvddrv))
        !           870:                return ENXIO;
        !           871:        if(vdunit_info[unit].info.partition[FILSYS(dev)].par_len == 0)
        !           872:                return ENXIO;
        !           873:        return NOERROR;
        !           874: }
        !           875: 
        !           876: 
        !           877: /*
        !           878: **
        !           879: */
        !           880: 
        !           881: vdread(dev, uio)
        !           882: dev_t dev;
        !           883: struct uio *uio;
        !           884: {
        !           885:        extern                  vdstrategy();
        !           886:        register int            unit = VDUNIT(dev);
        !           887:        register unit_tab       *u_info = &vdunit_info[unit];
        !           888: 
        !           889:        if (unit >= NFSD)
        !           890:                return ENXIO;
        !           891:        return physio(vdstrategy, &u_info->raw_q_element, dev, B_READ,
        !           892:            minphys, uio);
        !           893: }
        !           894: 
        !           895: 
        !           896: /*
        !           897: **
        !           898: */
        !           899: 
        !           900: vdwrite(dev, uio)
        !           901: dev_t dev;
        !           902: struct uio *uio;
        !           903: {
        !           904:        extern                  vdstrategy();
        !           905:        register int            unit = VDUNIT(dev);
        !           906:        register unit_tab       *u_info = &vdunit_info[unit];
        !           907: 
        !           908:        if (unit >= NFSD)
        !           909:                return ENXIO;
        !           910:        return physio(vdstrategy, &u_info->raw_q_element, dev, B_WRITE,
        !           911:            minphys, uio);
        !           912: }
        !           913: 
        !           914: 
        !           915: /*
        !           916: **
        !           917: */
        !           918: 
        !           919: vddump(dev)
        !           920: dev_t  dev;
        !           921: {
        !           922:        register int             unit = VDUNIT(dev);
        !           923:        register unit_tab        *u_info = &vdunit_info[unit];
        !           924:        register fs_tab          *fs = &u_info->info;
        !           925:        register int             ctlr = vddinfo[unit]->ui_ctlr;
        !           926:        register struct vba_ctlr *vba_vdctlr_info = vdminfo[ctlr];
        !           927:        register int             filsys = FILSYS(dev);
        !           928:        register cdr             *ctlr_addr = (cdr *)(vba_vdctlr_info->um_addr);
        !           929:        register int             cur_blk, blkcount, blocks;
        !           930:        int                      dump_short = FALSE;
        !           931:        int                      memaddr = 0x0;
        !           932: 
        !           933:        vdreset_ctlr(ctlr_addr, ctlr);
        !           934:        blkcount = maxfree - 2;         /* In 1k byte pages */
        !           935:        if ((dumplo + blkcount) > fs->partition[filsys].par_len) {
        !           936:                blkcount = fs->partition[filsys].par_len - dumplo;
        !           937:                printf("\nVDDC: Only dumping first %dmb of memory!\n",
        !           938:                    blkcount / 1024);
        !           939:                dump_short = TRUE;
        !           940:        }
        !           941:        cur_blk = fs->partition[filsys].par_start + dumplo;
        !           942:        while (blkcount > 0) {
        !           943:                blocks = MIN(blkcount, DUMPSIZE);
        !           944:                if(!vdwrite_block(ctlr_addr,ctlr,unit,memaddr,cur_blk,blocks))
        !           945:                        return EIO;
        !           946:                blkcount -= blocks;
        !           947:                memaddr += blocks * NBPG;
        !           948:                cur_blk += blocks;
        !           949:        }
        !           950:        return dump_short ? ENXIO : NOERROR;
        !           951: }
        !           952: 
        !           953: 
        !           954: /*
        !           955: **
        !           956: */
        !           957: 
        !           958: vdwrite_block(ctlr_addr, ctlr, unit, addr, block, blocks)
        !           959: register cdr    *ctlr_addr;
        !           960: register int   ctlr, unit;
        !           961: register char  *addr;
        !           962: register int   block, blocks;
        !           963: {
        !           964:        register fmt_mdcb       *mdcb = &vdctlr_info[ctlr].ctlr_mdcb;
        !           965:        register fmt_dcb        *dcb = &vdctlr_info[ctlr].ctlr_dcb;
        !           966:        register unit_tab       *u_info = &vdunit_info[unit];
        !           967:        register fs_tab         *fs = &u_info->info;
        !           968: 
        !           969:        block *= (int)u_info->sec_per_blk;
        !           970:        blocks *= (int)u_info->sec_per_blk;
        !           971:        mdcb->firstdcb = (fmt_dcb *)(PHYS(dcb));
        !           972:        dcb->intflg = NOINT;
        !           973:        dcb->opcode = WD;
        !           974:        dcb->operrsta = 0;
        !           975:        dcb->devselect = (char)(vddinfo[unit])->ui_slave;
        !           976:        dcb->trailcnt = (char)(sizeof(trrw) / sizeof(long));
        !           977:        dcb->trail.rwtrail.memadr = addr;
        !           978:        dcb->trail.rwtrail.wcount = (short)((blocks*fs->secsize)/sizeof(short));
        !           979:        dcb->trail.rwtrail.disk.cylinder= (short)(block / u_info->sec_per_cyl);
        !           980:        dcb->trail.rwtrail.disk.track = (char)((block / fs->nsec) % fs->ntrak);
        !           981:        dcb->trail.rwtrail.disk.sector = (char)(block % fs->nsec);
        !           982:        VDDC_ATTENTION(ctlr_addr, (fmt_mdcb *)(PHYS(mdcb)),
        !           983:            vdctlr_info[ctlr].ctlr_type);
        !           984:        POLLTILLDONE(ctlr_addr, dcb, 5, vdctlr_info[ctlr].ctlr_type);
        !           985:        if(vdtimeout <= 0) {
        !           986:                printf(" during dump operation!\n");
        !           987:                return(FALSE);
        !           988:        }
        !           989:        if (dcb->operrsta & HRDERR) {
        !           990:                printf("\nVDDC: Dump error.  Status = %x\n", dcb->operrsta);
        !           991:                return(FALSE);
        !           992:        }
        !           993:        return  TRUE;
        !           994: }
        !           995: 
        !           996: 
        !           997: 
        !           998: /*
        !           999: **
        !          1000: */
        !          1001: 
        !          1002: vdsize(dev)
        !          1003: register dev_t dev;
        !          1004: {
        !          1005:        register unit = VDUNIT(dev);
        !          1006:        register struct vba_device *vba_dev_info = vddinfo[unit];
        !          1007: 
        !          1008:        if((vba_dev_info == 0) || 
        !          1009:            (vba_dev_info->ui_alive == 0) ||
        !          1010:            (vba_dev_info->ui_type >= nvddrv))
        !          1011:                return -1;
        !          1012:        return vdunit_info[unit].info.partition[FILSYS(dev)].par_len;
        !          1013: }
        !          1014: 
        !          1015: 
        !          1016: /*
        !          1017: **
        !          1018: */
        !          1019: 
        !          1020: vdreset_ctlr(ctlr_addr, ctlr)
        !          1021: register cdr   *ctlr_addr;
        !          1022: register int   ctlr;
        !          1023: {
        !          1024:        register struct buf     *c_queue = &vdminfo[ctlr]->um_tab;
        !          1025:        register struct buf     *u_queue = c_queue->b_forw;
        !          1026:        register ctlr_tab       *c_info = &vdctlr_info[ctlr];
        !          1027:        register int            type, priority;
        !          1028:        
        !          1029:        printf("\nVDDC: Resetting controller #%d.  Please wait...\n", ctlr);
        !          1030:        VDDC_RESET(ctlr_addr, type);
        !          1031:        c_info->ctlr_started = FALSE;
        !          1032:        if(c_info->ctlr_type == SMD_ECTLR) {
        !          1033:                ctlr_addr->cdr_csr = 0;
        !          1034:                ctlr_addr->mdcb_tcf = AM_ENPDA;
        !          1035:                ctlr_addr->dcb_tcf = AM_ENPDA;
        !          1036:                ctlr_addr->trail_tcf = AM_ENPDA;
        !          1037:                ctlr_addr->data_tcf = AM_ENPDA;
        !          1038:                ctlr_addr->cdr_ccf = CCF_STS | XMD_32BIT | BSZ_16WRD |
        !          1039:                    CCF_ENP | CCF_EPE | CCF_EDE | CCF_ECE | CCF_ERR;
        !          1040:        }
        !          1041:        if(vdaccess_with_no_trailer(ctlr_addr,ctlr,0,INIT,10) & HRDERR) {
        !          1042:                printf("\nVDDC: Controller #%d failed to initialize!\n", ctlr);
        !          1043:                return  FALSE;
        !          1044:        }
        !          1045:        if(vdaccess_with_no_trailer(ctlr_addr,ctlr,0,DIAG,10) & HRDERR) {
        !          1046:                printf("\nVDDC: Controller #%d diagnostic error!\n",ctlr);
        !          1047:                return  FALSE;
        !          1048:        }
        !          1049:        /*  reset all units attached to controller */
        !          1050:        u_queue = c_queue->b_forw;
        !          1051:        do {
        !          1052:                reset_drive(ctlr_addr, ctlr, u_queue->b_dev, 0);
        !          1053:                u_queue = u_queue->b_forw;
        !          1054:        } while(u_queue != c_queue->b_forw);
        !          1055:        printf("VDDC: Controller #%d was reset successfully.\n", ctlr);
        !          1056:        return TRUE;
        !          1057: }
        !          1058: 
        !          1059: 
        !          1060: /*
        !          1061: **
        !          1062: */
        !          1063: 
        !          1064: reset_drive(ctlr_addr, ctlr, slave, start)
        !          1065: register cdr   *ctlr_addr;
        !          1066: register int   ctlr, slave, start;
        !          1067: {
        !          1068:        register int    type = vdctlr_info[ctlr].unit_type[slave];
        !          1069: 
        !          1070:        if(type != UNKNOWN)
        !          1071:                if(!vdconfigure_drive(ctlr_addr, ctlr, slave, type, start))
        !          1072:                        printf("\nVDDC: Couldn't reset unit #%d, controller #%d!\n",
        !          1073:                            slave, ctlr);
        !          1074: }
        !          1075: 
        !          1076: /*
        !          1077:        Print_dcb() dumps the mdcb and DCB for diagnostic purposes.  This
        !          1078:  routine is called whenever a fatal error is encountered.
        !          1079: */
        !          1080: 
        !          1081: vdprintdcb(ptr)
        !          1082: register long  *ptr;
        !          1083: {
        !          1084:        register long   i, j=0;
        !          1085:        register long   trailer_count;
        !          1086: 
        !          1087:        ptr = (long *)(*ptr | 0xc0000000);
        !          1088:        while(ptr != (long *)NULL) {
        !          1089:                ptr = (long *)((long)ptr | 0xc0000000);
        !          1090:                printf(" Dump of DCB 0x%x,%d:", ptr, j++);
        !          1091:                trailer_count = *(ptr+3) & 0xff;
        !          1092:                for(i=0; i<7+trailer_count; i++)
        !          1093:                        printf("  %lx", *(ptr+i));
        !          1094:                ptr = (long *)(*ptr);
        !          1095:                printf("\n");
        !          1096:        }
        !          1097:        printf("\n");
        !          1098:        for(i=0; i<5000000; i++) ;
        !          1099: }
        !          1100: 
        !          1101: #endif NVD > 0
        !          1102: 

unix.superglobalmegacorp.com

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