Annotation of cci/d/ioex/vddc.c, revision 1.1

1.1     ! root        1: 
        !             2: /*
        !             3:  *     Base of share memory for VDDC is at : 0x2000 (0x2X00)
        !             4:  *             X is switch selectable. 
        !             5:  *     The following configuration is assumed on VDDC :
        !             6:  *             FSD0          : device 0
        !             7:  *             FSD1          : device 1
        !             8:  *             SMD0          : device 2
        !             9:  *             SMD1          : device 3
        !            10:  */
        !            11: 
        !            12: #define  SBR           0
        !            13: #define  PGSHIFT       10
        !            14: #include "pte.h"
        !            15: #include "vddc.h"
        !            16: 
        !            17: /*     **********************
        !            18:        parameters for FSD,SMD
        !            19:        **********************
        !            20: */
        !            21: #define        NOUNIT          4
        !            22: struct DEVPAR devpar[NOUNIT+1] = {
        !            23:        823,10,10,32,512,0,"FSD",       /* FSD */
        !            24:        823,10,10,32,512,0,"FSD",       /* FSD */
        !            25:        823,19,19,32,512,0,"SMD",       /* SMD */
        !            26:        823,19,19,32,512,0,"SMD",       /* SMD */
        !            27:        0,0,0,0,0,0,"   "
        !            28: };
        !            29: 
        !            30: /*     VDDC Master DCB packet  */
        !            31: struct MDCB mdcb;
        !            32: 
        !            33: /*     VDDC DCB        */
        !            34: struct DCB dcb;
        !            35: 
        !            36: long VDDCbase;         /* Virtual addrss of VDDC */
        !            37: long Vdone;            /* Flag polled for status packet */
        !            38: long Format = 0;       /* If set, VDDC is formatting, wait longer ! */
        !            39: long Probe = 0;                /* If set do not print error message */
        !            40: extern long unused, iob0, Multi, IOinit;
        !            41: 
        !            42: vddc()
        !            43: {      register long r12;
        !            44:        long oldvec;
        !            45: 
        !            46:        Probe = 0;
        !            47:        m_vddc();               /* Map VDDC */
        !            48: 
        !            49:        /* Set handler for VDDC interrupt */
        !            50:        asm("movab vddchdlr,r12");
        !            51:        set_handler(VDDCVEC,&oldvec,r12);
        !            52: 
        !            53:        /* Reset UDC controller */
        !            54:        if ( vddc_reset()==0 )  {
        !            55:                writes("\n** Cannot reset VDDC controller \n");
        !            56:                return(0);
        !            57:                }
        !            58:        writes("\nVDDC controller is at "); writeh(VDDCBASE);
        !            59:        whonline();
        !            60:        return(1);
        !            61: }
        !            62: 
        !            63: 
        !            64: /*     Routine to map VDDC
        !            65: */
        !            66: m_vddc()
        !            67: {      long r12, phys_pg, pte, old_pte, which1;
        !            68: 
        !            69:        phys_pg = ((VDDCBASE+IOBASE) >> PGSHIFT) & 0x3fffff;
        !            70:                                /* 1st physical page of VDDC in IO space */
        !            71:        pte = phys_pg | PG_KW | PG_V | PG_NC;
        !            72:        fix_pte(SBR,unused,&old_pte,pte);
        !            73: 
        !            74:        /* Base Virtual addr of VDDC */
        !            75:        VDDCbase = (unused << PGSHIFT);
        !            76: 
        !            77:        asm("mfpr $SLR,r12");
        !            78:        r12++;
        !            79:        asm("mtpr r12,$SLR");
        !            80:        unused++;               /* Next unused PTE in system map */
        !            81: }
        !            82: 
        !            83: whonline()
        !            84: {      register struct DEVPAR *dp;
        !            85:        register long unit;
        !            86:        for(unit=0;devpar[unit].nocyl != 0;unit++) {
        !            87:                Probe = 1;
        !            88:                devpar[unit].alive = 1;
        !            89:                if (!vddc_op(RD_DATA,unit,0,1,&iob0)) devpar[unit].alive = 0; 
        !            90:                        else {  /* Unit is on line */
        !            91:                                /* Execute configure command */
        !            92:                                Probe = 0;
        !            93:                                vddc_ctlr(CONFIG,unit);
        !            94:                                writes("\n\t"); writes(devpar[unit].name);
        !            95:                                writes(" is on unit "); writed(unit);
        !            96:                                writec('\n');
        !            97:                                } 
        !            98:        }
        !            99:        Probe = 0;
        !           100: }
        !           101: 
        !           102: /* 
        !           103:        ******************************************************
        !           104:                Routine to sent one of the following control
        !           105:        command to VDDC : Format, start drives, stop drives, 
        !           106:        initialize controller, diagnose, Configure drive,
        !           107:        status.
        !           108:        op       : one of the above opcode
        !           109:        dev      : device selected
        !           110:        Returns 1 if command successfully completed.
        !           111:        ******************************************************
        !           112: */
        !           113: vddc_ctlr(op,dev)
        !           114: unsigned short op;
        !           115: char dev;
        !           116: {      long trailer[5];
        !           117:        register long notrailer, noword;
        !           118:        register struct DEVPAR *dp;
        !           119:        unsigned short format_data[512];
        !           120: 
        !           121:        dp = &devpar[dev];
        !           122:        notrailer = 0;
        !           123:        switch  (op) {
        !           124:                case FORMAT :
        !           125:                        for (noword=0;noword<512;noword++)
        !           126:                                format_data[noword] = 0xabababab;
        !           127:                        trailer[0] = (long)format_data;
        !           128:                        trailer[1] = dp->nocyl*dp->nohead*dp->secs_trak;
        !           129:                        trailer[2] = 0;         /* Start from log. sector 0 */
        !           130:                        trailer[3] = 0;
        !           131:                        notrailer = 4;
        !           132:                        Format = 1;
        !           133:                        setup_dcb(&dcb,op,dev,notrailer,trailer);
        !           134:                        noword=sento_vddc(&dcb);        /* Return 1 if O.K */
        !           135:                        Format = 0;
        !           136:                        return(noword);
        !           137:                        break;
        !           138:                case START_DR :
        !           139:                        break;
        !           140:                case STOP_DR :
        !           141:                        break;
        !           142:                case CONFIG:
        !           143:                        trailer[0] = dp->nocyl;
        !           144:                        trailer[1] = dp->nohead;
        !           145:                        notrailer = 2;
        !           146:                        break;
        !           147:                case STATUS:
        !           148:                        setup_dcb(&dcb,op,dev,notrailer,trailer);
        !           149:                        sento_vddc(&dcb);
        !           150:                        return(mdcb.ctlr_stat);
        !           151:                case INITIALIZE:
        !           152:                        break;
        !           153:                case DIAGNOSE:
        !           154:                        break;
        !           155:        }
        !           156:        setup_dcb(&dcb,op,dev,notrailer,trailer);
        !           157:        return(sento_vddc(&dcb));       /* Return 1 if O.K */
        !           158: }
        !           159: 
        !           160: 
        !           161: /* 
        !           162:        ******************************************************
        !           163:                Routine to read/write N block from/to disk
        !           164:        op       : opcode, READ or WRITE
        !           165:        dev      : device selected
        !           166:        blkno    : Logical block no. (1024bytes/blk) to access
        !           167:        no_blks  : no. of blocks to access
        !           168:        buf_adr  : Memory address
        !           169:        Returns 1 if command successfully completed.
        !           170:        ******************************************************
        !           171: */
        !           172: vddc_op(op,dev,blkno,no_blks,buf_adr)
        !           173: unsigned short op;
        !           174: char dev, *buf_adr;
        !           175: long no_blks, blkno;
        !           176: {      long trailer[3], nosec_cyl, secno;
        !           177:        long cyl_no, trak_no, sector_no;
        !           178:        register struct DEVPAR *dp;
        !           179: 
        !           180:        if (!devpar[dev].alive) {
        !           181:                writes("\nUnit "); writed(dev);
        !           182:                writes(" is not online..\n");
        !           183:                return(0); }
        !           184:        dp = &devpar[dev];
        !           185:        /* Setup trailer words */
        !           186:        nosec_cyl = dp->notraks * dp->secs_trak;        /* No of sectors/cyl */
        !           187:        secno = blkno*(BLKSIZ/dp->sector_siz);   /* Abs. sector no. to access */
        !           188: 
        !           189:        if ( (cyl_no=secno/nosec_cyl)>dp->nocyl ) {
        !           190:                if (!Probe) { writes("Cylinder no "); writed(cyl_no);
        !           191:                                writes(", too large\n"); return(0); }
        !           192:                }
        !           193:        secno = secno%nosec_cyl;
        !           194:        trak_no = secno/dp->secs_trak;
        !           195:        sector_no = secno%dp->secs_trak;
        !           196: 
        !           197:        trailer[0] = (long)buf_adr;
        !           198:        trailer[1] = no_blks * (BLKSIZ/2);      /* Unit is in word size */
        !           199:        trailer[2] = (cyl_no&0xfff)|(sector_no<<16)|(trak_no<<24);
        !           200:        if (!IOinit) {
        !           201:                if (op==(unsigned short)RD_DATA) writec('R');
        !           202:                        else writec('W'); 
        !           203:                /* writeh(blkno); writec('/'); writeh(no_blks); writec('/');
        !           204:                writeh(trailer[2]); */
        !           205:                }
        !           206:        setup_dcb(&dcb,op,dev,3,trailer);
        !           207:        return(sento_vddc(&dcb));       /* Return 1 if O.K */
        !           208: }
        !           209: 
        !           210: 
        !           211: /*     *********************
        !           212:        Reset VDDC controller.
        !           213:        *********************
        !           214: */
        !           215: vddc_reset()
        !           216: {      register long cnt;
        !           217: 
        !           218:        *((char *)(VDDCbase + 4)) = 1;          /* Reset VDDC */
        !           219:        DELAY(0x1f0000);                        /* Wait for 3 seconds */
        !           220:        return(1);
        !           221: }
        !           222: 
        !           223: 
        !           224: /*     Routine to fill DCB
        !           225: */
        !           226: setup_dcb(dcb,opcode,devno,notrailer,trailer)
        !           227: struct DCB *dcb;
        !           228: unsigned short opcode;
        !           229: char devno, notrailer;
        !           230: long *trailer;
        !           231: {      register long ix, *r12;
        !           232: 
        !           233:        dcb->nxt_dcb = NO_CHAIN;
        !           234:        dcb->int_flags = (unsigned short)INT_SUCCESS;
        !           235:        dcb->opcode = opcode;
        !           236:        dcb->dcb_stat = 0;                      /* Clear DCB status */
        !           237:        dcb->dev_sel = (char)devno & 0x3;       /* Device selected */
        !           238:        dcb->trail_wcnt = notrailer;            /* No. of trailer words */
        !           239:        r12 = (long *)dcb->trailer;
        !           240:        for (ix=0;ix<notrailer;ix++) r12[ix] = trailer[ix];
        !           241: }
        !           242: 
        !           243: 
        !           244: /*     
        !           245:        Routine to initiate a command to VDDC after DCB is set up
        !           246:        Input : vdcb = pointer to DCB structure
        !           247: */
        !           248: TO_VDDC(vdcb)
        !           249: struct DCB *vdcb;
        !           250: {
        !           251:        mdcb.fdcb_adr = (long)vdcb;             /* Set 1st DCB address */
        !           252:        mdcb.dcb_active = mdcb.dcb_int = mdcb.ctlr_stat = 0;
        !           253:        INT_VDDC();                             /* Interrupt VDDC */
        !           254: }
        !           255: 
        !           256: INT_VDDC()
        !           257: {      register long r12, r11, r10;
        !           258: 
        !           259:        r12 = (((long)&mdcb) >> 16) & 0xffff;
        !           260:        r11 = ((long)&mdcb) & 0xffff;
        !           261:        r10 = VDDCbase;
        !           262:        asm("movow r12,(r10)");
        !           263:        asm("movow r11,2(r10)");
        !           264: }
        !           265: 
        !           266: 
        !           267: /* 
        !           268:        **********************************************************
        !           269:        Routine to set up, sent command packet to UDC and check
        !           270:        status packet received from UDC. Return 0 if error occured
        !           271:        **********************************************************
        !           272: */
        !           273: sento_vddc(vdcb)
        !           274: struct DCB *vdcb;
        !           275: {
        !           276:        Vdone = 0;
        !           277:        TO_VDDC(vdcb);          /* Sent command to vddc */
        !           278:        if (Multi) return(1);
        !           279:        if (!vddc_wait()) return(0);
        !           280:        return(chk_vddcstat(vdcb));
        !           281: }
        !           282: 
        !           283: 
        !           284: /*     **************************************************
        !           285:        Routine to poll for completion interrupt from VDDC
        !           286:        **************************************************
        !           287: */
        !           288: vddc_wait()
        !           289: {      register long cnt;
        !           290: 
        !           291:        if (Format)  { cnt = 0xfffffff0;
        !           292:                        writes("\nVDDC formatting..."); }
        !           293:                else cnt = 0xfff00;
        !           294:        while (!Vdone) {        /* Wait for completion interrupt */
        !           295:                if (Format) writec('f');
        !           296:                if (--cnt <= 0) {
        !           297:                        if (!Probe)
        !           298:                            writes("\ntime out, lost completion interrupt..\n");
        !           299:                        return(0); }
        !           300:                }
        !           301:        return(1);
        !           302: }
        !           303: 
        !           304: 
        !           305: /*     *****************************************************
        !           306:        Routine to check completion status returned from VDDC
        !           307:        return 1 : status OK; command completed
        !           308:               0 : Command did not completed
        !           309:        *****************************************************
        !           310: */
        !           311: chk_vddcstat(vdcb)
        !           312: struct DCB *vdcb;
        !           313: {
        !           314:        if (mdcb.dcb_int != (long)vdcb) {
        !           315:                writes("\nUnsolicited DCB address, expected ");
        !           316:                writeh((long)vdcb); writes(", actual ");
        !           317:                writeh(mdcb.dcb_int); writes("\n"); 
        !           318:                return(0); }
        !           319:        if (((vdcb->dcb_stat&0xf0000000) != DCB_DONE) ||
        !           320:                (vdcb->dcb_stat&ANY_ERROR)) {
        !           321:                prt_vddcstat(vdcb->dcb_stat);
        !           322:                return(0);
        !           323:                }
        !           324:        return(1);
        !           325: }
        !           326: 
        !           327: /*     ***********************
        !           328:        Routine to print status 
        !           329:        ***********************
        !           330: */
        !           331: prt_vddcstat(stat)
        !           332: long stat;
        !           333: {
        !           334:        if (Probe) return;
        !           335:        if (stat&SOFT_ERROR) {
        !           336:                writes("\nsoft error ");
        !           337:                writeh((stat&SOFTERR_MASK)>>8);
        !           338:                }
        !           339:            else {
        !           340:                if (stat&HARD_ERROR) {
        !           341:                        writes("\nhard error ");
        !           342:                        writeh(stat&HARDERR_MASK); }
        !           343:                    else 
        !           344:                        if (stat&DATA_CORRECT) {
        !           345:                               writes("\nController performed data correction");
        !           346:                                writeh(stat&HARDERR_MASK); }
        !           347:            }
        !           348:        writec('\n');
        !           349: }
        !           350: 
        !           351: 
        !           352: 
        !           353: /*     VDDC interrupt handler 
        !           354: */
        !           355: vddc_hdlr()
        !           356: {
        !           357:        Vdone = 1;    /* Command done, received interrupt */
        !           358: }
        !           359: 
        !           360: Vddchdlr()
        !           361: {      long dummy;
        !           362:        asm(".align 2");
        !           363: asm("vddchdlr:");
        !           364:        asm("svpctx");
        !           365:        vddc_hdlr();            /* VDDC handler */
        !           366:        asm("ldpctx");
        !           367:        asm("rei");
        !           368: }
        !           369: 

unix.superglobalmegacorp.com

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