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

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

unix.superglobalmegacorp.com

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