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