|
|
1.1 ! root 1: #include "../machine/mtpr.h" ! 2: #include "../h/param.h" ! 3: #include "../h/inode.h" ! 4: #include "../vba/udc.h" ! 5: #include "../h/fs.h" ! 6: #include "saio.h" ! 7: ! 8: #ifdef NOIO ! 9: #define MEMDISK 0x80000 /* Memory mapped disk at 1/2 Mega */ ! 10: #endif ! 11: ! 12: /* Some I/O addresses used to generate pulses for scopes */ ! 13: #define OUT1 0xffffb034 ! 14: #define OUT2 0xffffb018 ! 15: #define OUT3 0xffffb020 ! 16: #define OUT4 0xffffb004 ! 17: #define OUT5 0xffffb024 ! 18: #define OUT6 0xffffb00c ! 19: #define OUT7 0xffffb02c ! 20: ! 21: #define IN1 0xffffb030 ! 22: #define IN2 0xffffb03c ! 23: #define IN3 0xffffb004 ! 24: #define IN4 0xffffb00c ! 25: #define IN5 0xffffb02c ! 26: ! 27: #undef scope_in ! 28: #undef scope_out ! 29: #define scope_out(x) movob (0, OUT/**/x) ! 30: #define scope_in(x) dummy = *(char *)(IN/**/x) ! 31: ! 32: /* ! 33: * Universal disk controller driver for the Motorola M68000/IPC. ! 34: * Stand-alone version (no interrupts, etc.) ! 35: */ ! 36: ! 37: ! 38: static struct UDPAC udpkt = { ! 39: 2, 0, 21, 0, 0, 0, 0, SECTSIZ, {0, 0}, 0, 0, 3 ! 40: } ; ! 41: ! 42: long udstd[] = { /* May be used some day to boot from any of ! 43: * several UDC controllers */ ! 44: 0xf0000 ! 45: }; ! 46: ! 47: /***************************************************** ! 48: /* ! 49: /*The next layout of major/minor number assignments are for the UDC ! 50: /*devices. ! 51: /* ! 52: /* 1 ! 53: /* 5 8 7 4 3 2 0 ! 54: /* +----------------+-----+-+-+-----+ ! 55: /* | Major device # | |D|R| FLS | ! 56: /* +----------------+-----+-+-+-----+ ! 57: /* | | |_____ File system # ( 0-7 ) ! 58: /* | |_________ Fixed (0) or removable(1) media ! 59: /* |___________ Drive # (0-1) ! 60: /* ! 61: /* For the floppy drives, the major / minor assignment will be ! 62: /* 1 ! 63: /* 5 8 7 4 3 2 0 ! 64: /* +----------------+-----+---+-----+ ! 65: /* | 4 | | D | FLS | ! 66: /* +----------------+-----+---+-----+ ! 67: /* | |_____ File system # ( 0-7 ) ! 68: /* |____________ Drive # (0-3) ! 69: /* ! 70: /****************************************************/ ! 71: ! 72: #define UDCUNIT(x) ((minor(x) & 0x18) >> 3) ! 73: ! 74: udstrategy(io, func) ! 75: register struct iob *io; ! 76: long func; /* Known to be 'read' */ ! 77: { ! 78: ! 79: register unit = io->i_unit; ! 80: register bn = io->i_bn; ! 81: register char *cntaddr ; ! 82: register char *addr ; ! 83: register timeout , retries , i; ! 84: #ifdef NOIO ! 85: register int *memory = (int *)(bn*1024 + MEMDISK); ! 86: #endif ! 87: ! 88: cntaddr = (char *)(udstd[0] + IOBASE); /* Booting from cntrlr 0 */ ! 89: /* ! 90: * prepare a command packet for the controller. ! 91: */ ! 92: retries = 3; ! 93: loop: ! 94: #ifndef NOIO ! 95: #ifndef SIMIO ! 96: if (cntaddr[OB1]) { ! 97: printf("UDC controller not ready, %x=%x\n",OB1+cntaddr, ! 98: cntaddr[OB1] & 0xff); ! 99: return(0); ! 100: } ! 101: #endif ! 102: #endif ! 103: udpkt._pkid = 0xAA ; ! 104: udpkt._pkdev = UDCUNIT(unit); ! 105: if (io->i_ino.i_dev == 3) udpkt._pkdev += 4; /* Floppy */ ! 106: udpkt._pkmem[0] = (((long)io->i_ma) >> 16) & 0xffff; ! 107: udpkt._pkmem[1] = ((long)io->i_ma) & 0xffff; ! 108: if (func == READ) { ! 109: udpkt._pkcmd = UDREAD ; ! 110: udpkt._pkfnc = UDWTRY ; ! 111: } else { ! 112: udpkt._pkcmd = UDWRITE ; ! 113: udpkt._pkfnc = UDWSECT ; ! 114: } ! 115: udpkt._psecno = bn * (DEV_BSIZE/SECTSIZ); ! 116: udpkt._pkcnt = (io->i_cc + SECTSIZ-1)/SECTSIZ ; ! 117: if (movep21(&udpkt,cntaddr+0x105,sizeof(udpkt) )) { ! 118: #ifndef NOIO ! 119: #ifndef SIMIO ! 120: cntaddr[OB1] = (char)0x80 ; /* signal packet transmitted */ ! 121: cntaddr[IB2] = (char)0 ; /* clear ACK/NAK field */ ! 122: cntaddr[INT] = (char)0x0 ; /* interrupt the controller */ ! 123: scope_out(1); ! 124: #else ! 125: dskio(&udpkt); ! 126: #endif ! 127: #endif ! 128: } ! 129: else { ! 130: printf ("Wrong command packet arrived at UDC\n"); ! 131: printf ("Original UDC\n"); ! 132: for (i = 0; i < sizeof(udpkt); i++ ) ! 133: printf(" %0x\t%0x\n", ((char *)&udpkt)[i*2] & 0xff, ! 134: cntaddr[0x105+i*2] & 0xff); ! 135: } ! 136: /* ! 137: * ! 138: * Wait until done (no interrupts now). ! 139: * ! 140: */ ! 141: wait: ! 142: #ifndef SIMIO ! 143: #ifndef NOIO ! 144: timeout = 100; ! 145: while (cntaddr[IB2] != (char)0x06 && cntaddr[IB2] != (char)0x15) { ! 146: /************** ! 147: DELAY(10000); ! 148: timeout--; ! 149: if (timeout <= 0) { ! 150: printf("UDC controller timeout\n"); ! 151: return(0); ! 152: } ! 153: *****************/ ! 154: } ! 155: scope_out(2); ! 156: if (cntaddr[IB2] == (char)0x15) { ! 157: if (retries-- < 0) { ! 158: printf("Too many NAK from UDC - give up\n"); ! 159: return(0); ! 160: } else goto loop; ! 161: } ! 162: ! 163: while (cntaddr[IB1] != (char)DEVRDY) ! 164: /* DELAY (10000); /* Wait for his response */; ! 165: scope_out(3); ! 166: ! 167: ! 168: /* Ignore unsolicited status messages */ ! 169: if (cntaddr[PKID] != (char)udpkt._pkid && cntaddr[PKSTT] == (char)0x80) ! 170: { ! 171: cntaddr[IB1] = (char)0; ! 172: cntaddr[OB2] = (char)6; ! 173: cntaddr[INT] = (char)0x80; ! 174: goto loop; ! 175: } ! 176: if (cntaddr[PKID] != (char)udpkt._pkid || ! 177: cntaddr[PKDEV] != (char)udpkt._pkdev || ! 178: cntaddr[PKLEN] != (char)19 || ! 179: cntaddr[PKCMD] != (char)udpkt._pkcmd || ! 180: cntaddr[PKSTT] != (char)0x70 || /* Command completion */ ! 181: cntaddr[STAT1] != (char)0 || ! 182: cntaddr[STAT2] != (char)0 ) { ! 183: printf ("Strange status from UDC:\n"); ! 184: printf("Packet id=%x,unit=%x,original command=%x,status type=%x,status=%x\n", ! 185: cntaddr[PKID] & 0xff, ! 186: cntaddr[PKDEV] & 0xff, ! 187: cntaddr[PKCMD] & 0xff, ! 188: cntaddr[PKSTT] & 0xff, ! 189: (cntaddr[STAT1]*256+cntaddr[STAT2]) & 0xffff); ! 190: if (cntaddr[PKLEN] > 9) { ! 191: printf("More response info : "); ! 192: for (i=1; i<=cntaddr[PKLEN]-9; i++) ! 193: printf("%x ", cntaddr[STAT2+2*i] & 0xff); ! 194: printf("\n"); ! 195: } ! 196: cntaddr[IB1] = (char)0; ! 197: cntaddr[OB2] = (char)6; ! 198: cntaddr[INT] = (char)0x80; ! 199: return(0); ! 200: } else { ! 201: cntaddr[IB1] = (char)0; ! 202: cntaddr[OB2] = (char)6; ! 203: cntaddr[INT] = (char)0x80; ! 204: scope_out(4); ! 205: mtpr (0, PADC); /* So data will come in right */ ! 206: return(io->i_cc); ! 207: } ! 208: #else ! 209: for (i=0; i<io->i_cc/4; i++) ! 210: ((int *)io->i_buf)[i] = *memory++; ! 211: return(io->i_cc); ! 212: #endif ! 213: #else ! 214: while (udpkt._pkfnc != 0x7f) ; /* wait for completion */ ! 215: return(io->i_cc); ! 216: #endif ! 217: ! 218: } ! 219: ! 220: /* ! 221: * Transfer a 21 bytes packet to the controller. ! 222: * the message is written to odd addresses, starting from ! 223: * the given address. ! 224: * For reliability, read it back and see if it's the same. If not, ! 225: * return an error code. ! 226: */ ! 227: movep21(src, dest,cnt) ! 228: ! 229: char *src, *dest; ! 230: int cnt; ! 231: { ! 232: #ifndef NOIO ! 233: #ifndef SIMIO ! 234: register char *running_src, *running_dest; ! 235: register long running_cnt; ! 236: ! 237: running_src = src; ! 238: running_dest = dest; ! 239: running_cnt = cnt; ! 240: ! 241: for (; running_cnt>0; running_cnt--) { ! 242: *running_dest++ = *running_src++; ! 243: running_dest++; ! 244: } ! 245: running_src = src; ! 246: running_dest = dest; ! 247: running_cnt = cnt; ! 248: for (; running_cnt>0; running_cnt--) { ! 249: if (*running_dest++ != *running_src++) return(0); ! 250: running_dest++; ! 251: } ! 252: return(1); ! 253: #endif ! 254: #endif ! 255: } ! 256: ! 257: udopen(io) ! 258: struct iob *io; ! 259: { ! 260: register char *cntaddr; ! 261: /* ! 262: * Just clean up any junk in the controller's response buffers. ! 263: */ ! 264: #ifndef NOIO ! 265: #ifndef SIMIO ! 266: cntaddr = (char *)(udstd[0] + IOBASE); /* Booting from cntrlr 0 */ ! 267: while (cntaddr[IB1] == (char)DEVRDY) { ! 268: cntaddr[IB1] = (char)0; ! 269: cntaddr[OB2] = (char)0x06; /* ACK */ ! 270: cntaddr[INT] = (char)0; /* Force him to listen and to respond */ ! 271: DELAY(50000); ! 272: } ! 273: #endif ! 274: #endif ! 275: } ! 276: #ifdef SIMIO ! 277: dskio(addr) ! 278: { ! 279: asm(".byte 0x2"); ! 280: } ! 281: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.