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