Annotation of cci/d/pits/vddc.c, revision 1.1.1.2

1.1       root        1: 
                      2: /*
                      3:  *     Base of share memory for VDDC is at : 0x2000 (0x2X00)
                      4:  *             X is switch selectable. 
                      5:  */
                      6: 
1.1.1.2 ! root        7: #define        NOUNIT  20
        !             8: #define        PGSHIFT 10
        !             9: 
1.1       root       10: #include "pte.h"
                     11: #include "vddc.h"
                     12: 
1.1.1.2 ! root       13: /*     ******************************
        !            14:        parameters for FSD,SMD,XFD,XSD
        !            15:        ******************************
1.1       root       16: */
                     17: 
                     18: struct DEVPAR devpar[NOUNIT] = {
1.1.1.2 ! root       19:        823,10,10,32,512,0,"fsd",       /* FSD */
        !            20:        823,10,10,32,512,0,"fsd",       /* FSD */
        !            21:        823,10,10,32,512,0,"fsd",       /* FSD */
        !            22:        823,10,10,32,512,0,"fsd",       /* FSD */
        !            23:        0,0,0,0,0,0,"   ",
        !            24:        823,19,19,32,512,0,"smd",       /* SMD */
        !            25:        823,19,19,32,512,0,"smd",       /* SMD */
        !            26:        823,19,19,32,512,0,"smd",       /* SMD */
        !            27:        823,19,19,32,512,0,"smd",       /* SMD */
1.1       root       28:        0,0,0,0,0,0,"   ",
1.1.1.2 ! root       29:        711,24,24,32,512,0,"xfd",       /* XFD */
        !            30:        711,24,24,32,512,0,"xfd",       /* XFD */
        !            31:        711,24,24,32,512,0,"xfd",       /* XFD */
        !            32:        711,24,24,32,512,0,"xfd",       /* XFD */
1.1       root       33:        0,0,0,0,0,0,"   ",
1.1.1.2 ! root       34:        711,24,24,48,512,0,"xsd",       /* XSD */
        !            35:        711,24,24,48,512,0,"xsd",       /* XSD */
        !            36:        711,24,24,48,512,0,"xsd",       /* XSD */
        !            37:        711,24,24,48,512,0,"xsd",       /* XSD */
1.1       root       38:        0,0,0,0,0,0,"   "
                     39: };
                     40: /*     *****************************************
1.1.1.2 ! root       41:        Controller parameters for controllers 0-7
1.1       root       42:        *****************************************
                     43: */
1.1.1.2 ! root       44: struct DA VDDCBASE[8] = {
1.1       root       45:        0xff2000,0xe0,0,        /* device address, int vect, online flg */
                     46:        0xff2100,0xe1,0,        /* device address, int vect, online flg */
                     47:        0xff2200,0xe2,0,        /* device address, int vect, online flg */
1.1.1.2 ! root       48:        0xff2300,0xe3,0,        /* device address, int vect, online flg */
        !            49:        0xff2400,0xe4,0,        /* device address, int vect, online flg */
        !            50:        0xff2500,0xe5,0,        /* device address, int vect, online flg */
        !            51:        0xff2600,0xe6,0,        /* device address, int vect, online flg */
        !            52:        0xff2700,0xe7,0         /* device address, int vect, online flg */
1.1       root       53: };
                     54: /*     VDDC Master DCB packet  */
                     55: 
                     56: struct MDCB mdcb;
                     57: 
                     58: /*     VDDC DCB        */
                     59: 
                     60: struct DCB dcb;
                     61: 
                     62: long VDDCbase;         /* Virtual address of VDDC */
                     63: long Vdone;            /* Flag polled for status packet */
                     64: long Format = 0;       /* If set, VDDC is formatting, wait longer ! */
                     65: long Probe = 0;                /* If set do not print error message */
                     66: extern long unused, iob0, Multi, Berr, IOinit;
                     67: int cont, type;
                     68: 
                     69: vddc()
                     70: {      register long r12;
                     71:        long oldvec;
                     72:        Probe = 0;
                     73: 
                     74:        /* output test header */ 
                     75: 
                     76:        writes("\n\n\t** VDDC Test **");
                     77: 
                     78:        cont = getcont();               /* Get controller number */
                     79:        type = gettype();               /* Get type of disk drives */
                     80: 
                     81:        /* Check if selected controller is installed */
                     82: 
                     83:        if(VDDCBASE[cont].online == 0) {
                     84:                writes("\n\nVDDC controller no. "); writed(cont);
                     85:                writes(" is not installed\n");
                     86:                return(0); }
                     87:        m_vddc();       /* Map VDDC */
                     88: 
                     89:        /* Set handler for VDDC interrupt */
                     90: 
                     91:        asm("movab vddchdlr,r12");
                     92:        set_handler(VDDCBASE[cont].intvect,&oldvec,r12);
                     93: 
                     94:        /* Reset UDC controller */ 
1.1.1.2 ! root       95:        vddc_reset();
1.1       root       96:        whonline();
                     97:        return(1);
                     98: }
                     99: chk_vdadr()
                    100: {      long curaddr, nvddc, vddcno;
                    101:        short len;
                    102:        len = 4;
                    103:        writes("\nProbing for VDDC controllers...");
1.1.1.2 ! root      104:        for(nvddc=vddcno=0; vddcno<8; vddcno++) {
1.1       root      105:                curaddr = VDDCBASE[vddcno].devaddr + IOBASE;
                    106:                if(badaddr(curaddr,len) == 0) {
                    107:                        writes("\nVDDC controller no. "); writed(vddcno);
                    108:                        writes(" at address ");
                    109:                        curaddr -= IOBASE;
                    110:                        writeh(curaddr);
                    111:                        VDDCBASE[vddcno].online = 1;
                    112:                        nvddc++; }
                    113:        }
                    114:        writes("\n"); writed(nvddc); writes(" VDDC controller(s) found");
                    115:        return(nvddc);
                    116: }
                    117: /*     Routine to map VDDC
                    118: */
                    119: m_vddc()
                    120: {      long r12, phys_pg, pte, old_pte, which1;
                    121: 
                    122:        phys_pg = ((VDDCBASE[cont].devaddr + IOBASE) >> PGSHIFT) & 0x3fffff;
                    123: 
                    124:        /* 1st physical page of VDDC in IO space */
                    125:        pte = phys_pg | PG_KW | PG_V | PG_NC;
                    126:        fix_pte(SBR,unused,&old_pte,pte);
                    127: 
                    128:        /* Base Virtual addr of VDDC */
                    129:        VDDCbase = (unused << PGSHIFT) | (VDDCBASE[cont].devaddr & 0x3ff);
                    130: 
                    131:        asm("mfpr $SLR,r12");
                    132:        r12++;
                    133:        asm("mtpr r12,$SLR");
                    134:        unused++;               /* Next unused PTE in system map */
                    135: }
                    136: whonline()
                    137: {      register struct DEVPAR *dp;
                    138:        register long unit;
1.1.1.2 ! root      139:        *((long *)(VDDCbase + 0xc)) = 0xffffffff;
        !           140:        if (*((long *)(VDDCbase + 0xc)) != 0xffffffff){
        !           141:                writes("\n\nController ");writed(cont);writes(" is a VSMD");
        !           142:                vddc_ctlr(INITIALIZE,unit);
        !           143:                }
        !           144:        else {
        !           145:                writes("\n\nController ");writed(cont);writes(" is a VSMD-E");
        !           146:                *((long *)(VDDCbase + 0x40)) = 0x33061;
        !           147:                vddc_ctlr(INITIALIZE,unit);
        !           148:                }
1.1       root      149:        for(unit=0;devpar[unit+type*5].nocyl != 0;unit++) {
                    150:                Probe = 1;
                    151:                devpar[unit+type*5].alive = 1;
1.1.1.2 ! root      152:                vddc_ctlr(CONFIG,unit);
        !           153:                if (!vddc_op(R_DATA,unit,0,1,&iob0)){
        !           154:                        devpar[unit+type*5].alive = 0; }
        !           155:                else {
        !           156:                        Probe = 0;
        !           157:                        }
1.1       root      158:        }
                    159:        Probe = 0;
                    160: }
                    161: 
                    162: /* 
                    163:        ******************************************************
                    164:                Routine to sent one of the following control
1.1.1.2 ! root      165:        command to VDDC : start drives, stop drives, 
1.1       root      166:        initialize controller, diagnose, Configure drive,
                    167:        status.
                    168:        op       : one of the above opcode
                    169:        dev      : device selected
                    170:        Returns 1 if command successfully completed.
                    171:        ******************************************************
                    172: */
                    173: vddc_ctlr(op,dev)
                    174: unsigned short op;
                    175: char dev;
                    176: {      long trailer[5];
                    177:        register long notrailer, noword;
                    178:        register struct DEVPAR *dp;
                    179:        unsigned short format_data[512];
                    180: 
                    181:        dp = &devpar[dev+type*5];
                    182:        notrailer = 0;
                    183:        switch  (op) {
                    184:                case START_DR :
                    185:                        break;
                    186:                case STOP_DR :
                    187:                        break;
                    188:                case CONFIG:
                    189:                        trailer[0] = dp->nocyl;
                    190:                        trailer[1] = dp->nohead;
1.1.1.2 ! root      191:                        trailer[2] = dp->secs_trak;
        !           192:                        trailer[3] = 0;
        !           193:                        notrailer = 4;
1.1       root      194:                        break;
                    195:                case STATUS:
                    196:                        setup_dcb(&dcb,op,dev,notrailer,trailer);
                    197:                        sento_vddc(&dcb);
                    198:                        return(mdcb.ctlr_stat);
                    199:                case INITIALIZE:
                    200:                        break;
                    201:                case DIAGNOSE:
                    202:                        break;
                    203:        }
                    204:        setup_dcb(&dcb,op,dev,notrailer,trailer);
                    205:        return(sento_vddc(&dcb));       /* Return 1 if O.K */
                    206: }
                    207: 
                    208: 
                    209: /* 
                    210:        ******************************************************
                    211:                Routine to read/write N block from/to disk
                    212:        op       : opcode, READ or WRITE
                    213:        dev      : device selected
                    214:        blkno    : Logical block no. (1024bytes/blk) to access
                    215:        no_blks  : no. of blocks to access
                    216:        buf_adr  : Memory address
                    217:        Returns 1 if command successfully completed.
                    218:        ******************************************************
                    219: */
                    220: vddc_op(op,dev,blkno,no_blks,buf_adr)
                    221: unsigned short op;
                    222: char *buf_adr;
                    223: long no_blks, blkno;
                    224: {      long trailer[3], nosec_cyl, secno;
                    225:        long cyl_no, trak_no, sector_no;
1.1.1.2 ! root      226:        char uf0,uf3;
1.1       root      227:        register struct DEVPAR *dp;
1.1.1.2 ! root      228:        uf0 = 0x0;
        !           229:        uf3 = 0xc0;
1.1       root      230:        if (!devpar[dev+type*5].alive) {
                    231:                writes("\n...Unit "); writed(dev);
                    232:                writes(" is not online\n");
                    233:                return(0); }
                    234:        dp = &devpar[dev+type*5];
                    235:        /* Setup trailer words */
                    236:        nosec_cyl = dp->notraks * dp->secs_trak;        /* No of sectors/cyl */
                    237:        secno = blkno*(BLKSIZ/dp->sector_siz);   /* Abs. sector no. to access */
                    238: 
                    239:        if ( (cyl_no=secno/nosec_cyl)>dp->nocyl ) {
                    240:                if (!Probe) { writes("...Cylinder no "); writed(cyl_no);
                    241:                                writes(", too large\n"); return(0); }
                    242:                }
                    243:        secno = secno%nosec_cyl;
                    244:        trak_no = secno/dp->secs_trak;
                    245:        sector_no = secno%dp->secs_trak;
                    246: 
                    247:        trailer[0] = (long)buf_adr;
                    248:        trailer[1] = no_blks * (BLKSIZ/2);      /* Unit is in word size */
1.1.1.2 ! root      249:        if (cyl_no > dp->nocyl-2) {
        !           250:           trailer[2]=(cyl_no&0xfff)|(sector_no<<16)|(trak_no<<24)|(uf3<<12);
        !           251:        }
        !           252:        else {  
        !           253:           trailer[2]=(cyl_no&0xfff)|(sector_no<<16)|(trak_no<<24)|(uf0<<12);
        !           254:        }
1.1       root      255:        setup_dcb(&dcb,op,dev,3,trailer);
                    256:        return(sento_vddc(&dcb));       /* Return 1 if O.K */
                    257: }
1.1.1.2 ! root      258: /*
        !           259:        write or read to/from specific cylinder, track, sector
        !           260: */
        !           261: vddc_op2(op,dev,cyl,trk,sec,no_blks,buf_adr)
        !           262: unsigned short op;
        !           263: char *buf_adr;
        !           264: long no_blks, cyl, trk, sec;
        !           265: {
        !           266:        long trailer[3];
        !           267:        char uf0;
        !           268: 
        !           269:        uf0 = 0x0;
        !           270:        trailer[0] = (long)buf_adr;
        !           271:        trailer[1] = no_blks * (BLKSIZ/2);
        !           272:        trailer[2] = (cyl & 0xfff)|(sec << 16)|(trk << 24)|(uf0 << 12);
        !           273:        setup_dcb(&dcb,op,dev,3,trailer);
        !           274:        return(sento_vddc(&dcb));
        !           275: }
        !           276: /*
        !           277:        seek to a specific cylinder, track, sector
        !           278: */
        !           279: vddc_op3(op,dev,cyl,trk,sec)
        !           280: unsigned short op;
        !           281: long  cyl, trk, sec;
        !           282: {
        !           283:        long trailer[1];
        !           284:        char uf0;
        !           285: 
        !           286:        uf0 = 0x0;
        !           287:        trailer[0] = (cyl & 0xfff)|(sec << 16)|(trk << 24)|(uf0 << 12);
        !           288:        setup_dcb(&dcb,op,dev,1,trailer);
        !           289:        return(sento_vddc(&dcb));
        !           290: }
1.1       root      291: /*     *********************
                    292:        Reset VDDC controller
                    293:        *********************
                    294: */
                    295: vddc_reset()
                    296: {
                    297:        *((char *)(VDDCbase + 4)) = 1;  /* reset VDDC */
                    298:        DELAY(0x1f0000);                /* wait for 3 seconds */
                    299:        return(1);
                    300: }
                    301: vddc_init()
                    302: {
                    303: }
                    304: /*     Routine to fill DCB
                    305: */
                    306: setup_dcb(dcb,opcode,devno,notrailer,trailer)
                    307: struct DCB *dcb;
                    308: unsigned short opcode;
                    309: char devno, notrailer;
                    310: long *trailer;
                    311: {      register long ix, *r12;
                    312:        dcb->nxt_dcb = NO_CHAIN;
1.1.1.2 ! root      313:        dcb->int_flags = (unsigned short)INT_DONE;
1.1       root      314:        dcb->opcode = opcode;
                    315:        dcb->dcb_stat = 0;                      /* Clear DCB status */
                    316:        dcb->dev_sel = (char)devno & 0x3;       /* Device selected */
                    317:        dcb->trail_wcnt = notrailer;            /* No. of trailer words */
                    318:        r12 = (long *)dcb->trailer;
                    319:        for (ix=0;ix<notrailer;ix++) r12[ix] = trailer[ix];
                    320: }
                    321: 
                    322: 
                    323: /*     
                    324:        Routine to initiate a command to VDDC after DCB is set up
                    325:        Input : vdcb = pointer to DCB structure
                    326: */
                    327: TO_VDDC(vdcb)
                    328: struct DCB *vdcb;
                    329: {
                    330:        mdcb.fdcb_adr = (long)vdcb;             /* Set 1st DCB address */
                    331:        mdcb.dcb_active = mdcb.dcb_int = mdcb.ctlr_stat = 0;
                    332:        INT_VDDC();
                    333: }
                    334: INT_VDDC()
                    335: {
                    336:        register long r12, r11, r10;
                    337:        r12 = (((long)&mdcb) >> 16) & 0xffff; 
                    338:        r11 = ((long)&mdcb) & 0xffff;
                    339:        r10 = VDDCbase;
                    340:        asm("movow r12,(r10)");
                    341:        asm("movow r11,2(r10)");
                    342: }
                    343: /* 
                    344:        **********************************************************
                    345:        Routine to set up, sent command packet to UDC and check
                    346:        status packet received from UDC. Return 0 if error occured
                    347:        **********************************************************
                    348: */
                    349: sento_vddc(vdcb)
                    350: struct DCB *vdcb;
                    351: {
                    352:        Vdone = 0;
                    353:        TO_VDDC(vdcb);          /* Sent command to vddc */
                    354:        if (Multi) return(1);
                    355:        if (!vddc_wait()) return(0);
                    356:        return(chk_vddcstat(vdcb));
                    357: }
                    358: 
                    359: 
                    360: /*     **************************************************
                    361:        Routine to poll for completion interrupt from VDDC
                    362:        **************************************************
                    363: */
                    364: vddc_wait()
                    365: {      register long cnt;
1.1.1.2 ! root      366:        cnt = 0xfff00;
1.1       root      367:        while (!Vdone) {        /* Wait for completion interrupt */
                    368:                if (--cnt <= 0) {
1.1.1.2 ! root      369:                        if (!Probe) 
1.1       root      370:                         writes("\n...time out, lost completion interrupt..\n");
                    371:                        return(0); }
                    372:                }
                    373:        return(1);
                    374: }
                    375: 
                    376: 
                    377: /*     *****************************************************
                    378:        Routine to check completion status returned from VDDC
                    379:        return 1 : status OK; command completed
                    380:               0 : Command did not completed
                    381:        *****************************************************
                    382: */
                    383: chk_vddcstat(vdcb)
                    384: struct DCB *vdcb;
                    385: {
                    386:        if (mdcb.dcb_int != (long)vdcb) {
                    387:                writes("\n...Unsolicited DCB address, expected ");
                    388:                writeh((long)vdcb); writes(", actual ");
                    389:                writeh(mdcb.dcb_int); writes("\n"); 
                    390:                return(0); }
                    391:        if (((vdcb->dcb_stat&0xf0000000) != DCB_DONE) ||
                    392:                (vdcb->dcb_stat&ANY_ERROR)) {
                    393:                prt_vddcstat(vdcb->dcb_stat);
1.1.1.2 ! root      394:                if (vdcb->dcb_stat&HARD_ERROR) return(0);
1.1       root      395:                }
                    396:        return(1);
                    397: }
                    398: 
                    399: /*     ***********************
                    400:        Routine to print status 
                    401:        ***********************
                    402: */
                    403: prt_vddcstat(stat)
                    404: long stat;
                    405: {
                    406:        if (Probe) return;
                    407:        if (stat&SOFT_ERROR) {
                    408:                writes("\n...soft error ");
                    409:                writeh(stat&SOFTERR_MASK);
                    410:                }
                    411:            else {
                    412:                if (stat&HARD_ERROR) {
                    413:                        writes("\n...hard error ");
                    414:                        writeh(stat&HARDERR_MASK); }
                    415:                    else 
                    416:                        if (stat&DATA_CORRECT) {
                    417:                            writes("\n...Controller performed data correction");
                    418:                                writeh(stat&HARDERR_MASK); }
                    419:            }
                    420:        writec('\n');
                    421: }
                    422: /*     VDDC interrupt handler 
                    423: */
                    424: vddc_hdlr()
                    425: {
                    426:        Vdone = 1;    /* Command done, received interrupt */
                    427: }
                    428: Vddchdlr()
                    429: {      asm(".align 2");
                    430:        asm(".globl vddchdlr");
                    431: asm("vddchdlr:");
                    432:        asm("svpctx");   
                    433:        vddc_hdlr();            /* VDDC handler */
                    434:        asm("ldpctx");   
                    435:        asm("rei");
                    436: }

unix.superglobalmegacorp.com

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