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

1.1     ! root        1: /*
        !             2:  *     Base of share memory for UDC is at : 0xff0000
        !             3:  *
        !             4:  *     The following configuration is required on UDC :
        !             5:  *             SMD           : device 0
        !             6:  *             CMD_fixed     : device 2
        !             7:  *             CMD_removable : device 3
        !             8:  *             Floppy0       : device 4
        !             9:  *             Floppy1       : device 5
        !            10:  */
        !            11: 
        !            12: #define  SBR           0
        !            13: #define  PGSHIFT       10
        !            14: #include "pte.h"
        !            15: #include "udc.h"
        !            16: 
        !            17: 
        !            18: /*     UDC command packet      */
        !            19: struct UDPAC udpac = {
        !            20:        2, 0, 21, 0, 0, 0, 0, SECTSIZ, 0, 0, 0, 3
        !            21: };
        !            22: 
        !            23: 
        !            24: /*     UDC status packet       */
        !            25: struct UDSPAC udspac = {
        !            26:        2, 0, 9, 0, 0, 0, 0, 3
        !            27: };
        !            28: long IObase;           /* Virtual addrss of UDC shares memory */
        !            29: long Uack;             /* Flag polled for UDC acknowlege */
        !            30: long Udone;            /* Flag polled for status packet */
        !            31: long Probe = 0;                /* If set do not print error message */
        !            32: extern long unused, iob0, iob2, iob4;
        !            33: 
        !            34: udc()
        !            35: {      register long r12;
        !            36:        long oldvec;
        !            37: 
        !            38:        writes("\n      ** UDC test **\n");
        !            39:        Probe = 0;
        !            40:        m_udc();                /* Map UDC */
        !            41: 
        !            42:        /* Set handler for UDC interrupt */
        !            43:        asm("movab udhdlr,r12");
        !            44:        set_handler(UDCVEC,&oldvec,r12);
        !            45: 
        !            46:        /* Reset UDC controller */
        !            47:        if ( udc_reset()==0 )  {
        !            48:                writes("\n** Cannot reset UDC controller \n");
        !            49:                return;  }
        !            50:        u_ex();
        !            51: }
        !            52: 
        !            53: 
        !            54: /*     Routine to map UDC
        !            55: */
        !            56: m_udc()
        !            57: {      long r12, phys_pg, pte, old_pte, which1;
        !            58: 
        !            59:        phys_pg = ((UBASE+IOBASE) >> PGSHIFT) & 0x3fffff;
        !            60:                                /* 1st physical page of UDC in IO space */
        !            61:        pte = phys_pg | PG_KW | PG_V | PG_NC;
        !            62:        fix_pte(SBR,unused,&old_pte,pte);
        !            63: 
        !            64:        /* Base addr of common buffer */
        !            65:        IObase = (unused << PGSHIFT);
        !            66: 
        !            67:        asm("mfpr $SLR,r12");
        !            68:        r12++;
        !            69:        asm("mtpr r12,$SLR");
        !            70:        unused++;               /* Next unused PTE in system map */
        !            71: }
        !            72: 
        !            73: 
        !            74: 
        !            75: /*     *********************
        !            76:        Reset UDC controller.
        !            77:        *********************
        !            78: */
        !            79: udc_reset()
        !            80: {      register long cnt;
        !            81: 
        !            82:        IPC_RESET;
        !            83:        DELAY(0x1f0000);                /* Wait for 3 seconds */
        !            84:        cnt = RETRY;
        !            85:        while (RD_MCSENT != READY)
        !            86:                { DELAY(0x40000);
        !            87:                  if (--cnt == 0) return(0); }
        !            88:        return(1);
        !            89: }
        !            90: 
        !            91: 
        !            92: /*     *********************************
        !            93:        Routine to copy from disk to disk
        !            94:        *********************************
        !            95: */
        !            96: cpy_dd(sdev, ddev, sblk, dblk, noblk)
        !            97: char sdev, ddev;
        !            98: long sblk, dblk, noblk;
        !            99: {      
        !           100:        long  s_begsec, d_begsec;
        !           101:        long ndatablks, s_nsblk, d_nsblk, blk;
        !           102: 
        !           103: for(blk=sblk;blk<=(sblk+noblk);blk++)
        !           104:        {
        !           105:        /* Read 1 block (1K) of data */
        !           106:        if (disk_rw(READ,sdev,blk,1,&iob0)==0) return(0);
        !           107:            else writec('R');
        !           108: 
        !           109:        /* Write data */
        !           110:        if (disk_rw(WRITE,ddev,dblk,1,&iob0)==0) return(0);
        !           111:            else {  writec('W');
        !           112:                    dblk++;   }
        !           113:        }
        !           114: }
        !           115: 
        !           116: 
        !           117: 
        !           118: /* 
        !           119:        ******************************************
        !           120:        Routine to read/write N block from/to disk
        !           121:        ******************************************
        !           122: */
        !           123: disk_rw(op,dev,blkno,no_blks,buf_adr)
        !           124: char op, dev;
        !           125: long no_blks, blkno;
        !           126: char *buf_adr;
        !           127: {      long  begsec;
        !           128:        long nblks, nsblk;
        !           129: 
        !           130:        nblks = (no_blks*BLKSIZ)/UDC_BLKLEN;    /* no of blocks to be read */
        !           131:        nsblk = BLKSIZ/SECTSIZ;         /* no of sects/logical blk on dev */
        !           132: 
        !           133:        begsec = (long)(blkno * nsblk);   /* begin sector no. */
        !           134:        if (op==READ) {
        !           135:           writec('.');
        !           136:           return(disk_op(dev,UDREAD,UDWTRY,nblks,buf_adr,begsec));
        !           137:           }
        !           138:         else {
        !           139:           writec(',');
        !           140:           return(disk_op(dev,UDWRITE,UDWCMP,nblks,buf_adr,begsec));
        !           141:           }
        !           142: }
        !           143: 
        !           144: 
        !           145: /* 
        !           146:        **********************************************************
        !           147:        Routine to set up, sent command packet to UDC and check
        !           148:        status packet received from UDC. Return 0 if error occured
        !           149:        **********************************************************
        !           150: */
        !           151: disk_op(disk_no,cmd,func,noblk,buf_adr,beg_sctno)
        !           152: char cmd, disk_no, func;
        !           153: long noblk;
        !           154: char *buf_adr;
        !           155: long beg_sctno;
        !           156: {
        !           157: 
        !           158:        udpac.pkdev = disk_no;
        !           159:        udpac.pkcmd = cmd;
        !           160:        udpac.pkfnc = func;
        !           161:        udpac.pkcnt = noblk;
        !           162:        udpac.pbsiz = UDC_BLKLEN;       /* 256 for UDC/FDC */
        !           163: 
        !           164:        udpac.pkmem[0] = (short)(((long)buf_adr >> 16) & 0xffff);
        !           165:        udpac.pkmem[1] = (short)((long)buf_adr & 0xffff);
        !           166: 
        !           167:        udpac.psecno[0] = (short)((beg_sctno >> 16) & 0xffff);
        !           168:        udpac.psecno[1] = (short)(beg_sctno & 0xffff);
        !           169:        udpac.etx = (char)0x3;
        !           170: 
        !           171:        return(TP((char *)&udpac,disk_no));
        !           172: }
        !           173: 
        !           174: 
        !           175: /*     ******************************************************
        !           176:        Transfer a 21 bytes packet to the controller.
        !           177:        the message is written to odd addresses, starting from
        !           178:        the given address.
        !           179:        ******************************************************
        !           180: */
        !           181: movep21(src, dest,cnt)
        !           182: char   *src, *dest;
        !           183: int cnt;
        !           184: {
        !           185:        for (; cnt>0; cnt--) {
        !           186:                *dest++ = *src++;
        !           187:                dest++;
        !           188:        }
        !           189: }
        !           190: 
        !           191: 
        !           192: 
        !           193: /*     ***************************************
        !           194:        Read status packet from the controller.
        !           195:        Only read from odd addresses.
        !           196:        ***************************************
        !           197: */
        !           198: rdspac(src, dest,cnt)
        !           199: char   *src, *dest;
        !           200: int cnt;
        !           201: {
        !           202:        for (; cnt>0; cnt--) {
        !           203:                *dest++ = *src++;
        !           204:                src++;
        !           205:        }
        !           206: }
        !           207: 
        !           208: 
        !           209: /*     ******************************************************
        !           210:        Transmit packet UDC controller and check return status 
        !           211:        ******************************************************
        !           212: */
        !           213: TP(packet,disk_no)
        !           214: char *packet, disk_no;
        !           215: {      long cnt, retry;
        !           216:        char *src, ack, stat, get_ack(), chk_stat();
        !           217: 
        !           218:        cnt = retry = 0;
        !           219: again:
        !           220:        Uack = Udone = 0;
        !           221:        if (udc_ready()) sent_pck(packet);
        !           222:                else { writes("\nUDC not ready, did a reset..");
        !           223:                        return(0); }
        !           224:        switch (ack = get_ack()) {
        !           225:                case PCK_OK  : break;
        !           226:                case RETRANS : { if (++cnt<10) goto again;
        !           227:                                else { writes("IPC ack error\n"); 
        !           228:                                       return(0); }
        !           229:                               }
        !           230:                default   : { writes("\ndid not get ACK\n");
        !           231:                           return(0); }
        !           232:                }
        !           233: wtspk:
        !           234:        if (stat_wait()==0) {           /* Wait for status packet */
        !           235:                IPC_RESET;
        !           236:                return(0); }
        !           237:        rdspac((char *)IPC_PCK,(char *)&udspac,9);      /* Get packet */
        !           238: 
        !           239:        switch (stat=chk_stat(disk_no))  {
        !           240:                case 0 : break;
        !           241:                case 1 : {
        !           242:                        writes("\nTP : unsolicited status packet !");
        !           243:                        prt_stat();
        !           244:                        goto invlspk; }
        !           245:                case 2 : {
        !           246:                        writes("\nTP : unexpected dev_no in status_pkt !");
        !           247:                        prt_stat();
        !           248:                        goto invlspk; }
        !           249:                case 3 : {
        !           250:                        if (!Probe) { 
        !           251:                                writes("\nTP : command didnot complete !");
        !           252:                                prt_stat(); }
        !           253:                        goto end; }
        !           254:                }
        !           255:        ipc_ack(PCK_OK);
        !           256:        return(1);
        !           257: invlspk:
        !           258:        if ((++retry) > 10) goto end;   /* Too many errors */   
        !           259:        ipc_ack(RETRANS);               /* Retransmit packet */
        !           260:        goto wtspk;                     /* go wait for status packet */ 
        !           261: end:
        !           262:        ipc_ack(PCK_OK);
        !           263:        return(0);
        !           264: }
        !           265: 
        !           266: 
        !           267: /*     ***************************
        !           268:        Routine to get ACK from UDC
        !           269:        ***************************
        !           270: */
        !           271: char get_ack()
        !           272: {      char ack;
        !           273:        register long cnt;
        !           274: 
        !           275:        cnt = 0xfff00;
        !           276:        while (Uack==0)  {      /* Wait for Ack */
        !           277:                if (--cnt <= 0) {
        !           278:                        writes("\ntime out on Uack..\n");
        !           279:                        return(0); }
        !           280:                }
        !           281:        ack=RD_IPCACK;
        !           282:        if ((ack==PCK_OK) || (ack==RETRANS)) return(ack);    /* received ACK */
        !           283:        return(0);
        !           284: }
        !           285: 
        !           286: /*     ******************************************
        !           287:        Routine to poll for status packet from UDC
        !           288:        ******************************************
        !           289: */
        !           290: stat_wait()
        !           291: {      register long cnt;
        !           292: 
        !           293:        cnt = 0xfff00;
        !           294:        while (!Udone) {        /* Wait for completion interrupt */
        !           295:                if (--cnt <= 0) {
        !           296:                        writes("\ntime out on Udone..\n");
        !           297:                        return(0); }
        !           298:                }
        !           299:        return(1);
        !           300: }
        !           301: 
        !           302: 
        !           303: /*     ****************************************
        !           304:        Routine to check status packet from UDC
        !           305:        return 0 : status OK; command completed
        !           306:               1 : Unsolicited packet
        !           307:               2 : Status from unexpected device
        !           308:               3 : Command did not completed
        !           309:        ****************************************
        !           310: */
        !           311: char chk_stat(devno)
        !           312: char devno;
        !           313: {
        !           314:        if (udspac.id == (char)0xff) return((char)1);   /* unsolicited packet */
        !           315:        if (udspac.dev != devno) return((char)2);
        !           316:        if ((udspac.stype!=0x70) || (udspac.stat!=0)) return((char)3);
        !           317:        return((char)0);
        !           318: }
        !           319: 
        !           320: /*     ***********************
        !           321:        Routine to print status 
        !           322:        ***********************
        !           323: */
        !           324: prt_stat()
        !           325: {
        !           326:        writes("\nDevice no.  : "); writeh((long)udspac.dev);
        !           327:        writes("\nStatus type : ");
        !           328:        writeh((long)udspac.stype); 
        !           329:        writes("\nStatus code : ");
        !           330:        writeh((long)udspac.stat);
        !           331:        writec('\n');
        !           332: }
        !           333: 
        !           334: 
        !           335: /*     **************************************
        !           336:        Routine to sent a command paket to UDC
        !           337:        **************************************
        !           338: */
        !           339: sent_pck(packet)
        !           340: char *packet;
        !           341: {
        !           342:        movep21(packet, (char *)MC_PCK,21);
        !           343:        WR_MCSENT(0x80);        /* User packet placed */
        !           344:        WR_IPCACK(0);   /* Reset for results of packet format test by IPC */
        !           345:        IPC_INT;                /* Interrupt IPC */
        !           346: }
        !           347: 
        !           348: /*     **************************************************
        !           349:        Routine to check if UDC is ready to receive packet
        !           350:        if not then reset UDC and return 0
        !           351:        **************************************************
        !           352: */
        !           353: udc_ready()
        !           354: {      long cnt;
        !           355: 
        !           356:        cnt = RETRY;
        !           357:        while (RD_MCSENT != READY)
        !           358:                { DELAY(1000);
        !           359:                  if (--cnt==0) { writes("\nTP : time out\n"); goto end; }
        !           360:                }
        !           361:        return(1);
        !           362: end:
        !           363:        IPC_RESET;
        !           364:        return(0);
        !           365: }
        !           366: 
        !           367: /*     *****************************************************
        !           368:        Routine to acknowlege status packet received from UDC 
        !           369:        *****************************************************
        !           370: */
        !           371: ipc_ack(stat)
        !           372: char stat;
        !           373: {
        !           374:        WR_IPCSENT(0);                  /* Packet processed */
        !           375:        WR_MCACK(stat);                 /* Packet status */
        !           376:        IPC_INT;
        !           377: }
        !           378: 
        !           379: /*     UDC interrupt handler 
        !           380: */
        !           381: ud_hdlr()
        !           382: {
        !           383:        if (RD_IPCACK != 0) {  Uack = 1;        /* received ACK */
        !           384:                         }
        !           385:        if ((RD_IPCSENT&0xff) == 0x80) { 
        !           386:                        Udone = 1;    /* Status packet placed */
        !           387:                        }
        !           388: }
        !           389: 
        !           390: Udchdlr()
        !           391: {      long dummy;
        !           392:        asm(".align 2");
        !           393: asm("udhdlr:");
        !           394:        asm("svpctx");
        !           395:        ud_hdlr();              /* UDC handler */
        !           396:        asm("ldpctx");
        !           397:        asm("rei");
        !           398: }
        !           399: 

unix.superglobalmegacorp.com

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