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