|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.