1 /* udcformat.c 1.2 86/01/21 */ 2 /* format disk - cmd/smd type */ 3 4 #include "../machine/mtpr.h" 5 6 #include "param.h" 7 #include "inode.h" 8 #include "fs.h" 9 10 #include "../tahoevba/vbaparam.h" 11 #include "../tahoevba/udc.h" 12 13 #include "saio.h" 14 15 char disk[50] = "xmd(00,000)"; 16 17 main() 18 { 19 int j, c, i, n; 20 char buf[50]; 21 int output; 22 23 do { 24 printf("Device to format: "); 25 gets(disk); 26 output = open(disk, 1); 27 if (output <= 0) printf("Cannot open disk\n", disk); 28 /* dummy call just to get to the local strategy routine */ 29 else { 30 printf("Type <return> to start formatting "); 31 gets(buf); 32 write(output,buf,0); 33 printf("Formatting completed. \n"); 34 } 35 } while (output <= 0); 36 37 } 38 39 /* 40 * Universal disk controller driver for the Motorola M68000/IPC. 41 * Stand-alone version (no interrupts, etc.) 42 */ 43 44 45 static struct UDPAC udpkt = { 46 2, 0, 21, 0, 0, 0, 0, SECTSIZ, {0, 0}, 0, 0, 3 47 } ; 48 49 long udstd[] = { /* May be used some day to boot from any of 50 * several UDC controllers */ 51 0xf0000 52 }; 53 54 /***************************************************** 55 /* 56 /*The next layout of major/minor number assignments are for the UDC 57 /*devices. 58 /* 59 /* 1 60 /* 5 8 7 4 3 2 0 61 /* +----------------+-----+-+-+-----+ 62 /* | Major device # | |D|R| FLS | 63 /* +----------------+-----+-+-+-----+ 64 /* | | |_____ File system # ( 0-7 ) 65 /* | |_________ Fixed (0) or removable(1) media 66 /* |___________ Drive # (0-1) 67 /* 68 /* For the floppy drives, the major / minor assignment will be 69 /* 1 70 /* 5 8 7 4 3 2 0 71 /* +----------------+-----+---+-----+ 72 /* | 4 | | D | FLS | 73 /* +----------------+-----+---+-----+ 74 /* | |_____ File system # ( 0-7 ) 75 /* |____________ Drive # (0-3) 76 /* 77 /****************************************************/ 78 79 #define UDCUNIT(x) ((minor(x) & 0x18) >> 3) 80 81 udstrategy(io, func) 82 register struct iob *io; 83 long func; /* Known to be 'read' */ 84 { 85 86 register unit = io->i_unit; 87 register bn = io->i_bn; 88 register char *cntaddr ; 89 register char *addr ; 90 register timeout , retries , i; 91 92 cntaddr = (char *)(udstd[0] + VBIOBASE); /* Booting from cntrlr 0 */ 93 /* 94 * prepare a command packet for the controller. 95 */ 96 retries = 3; 97 loop: 98 if (cntaddr[OB1]) { 99 printf("UDC controller not ready, %x=%x\n",OB1+cntaddr, 100 cntaddr[OB1] & 0xff); 101 return(0); 102 } 103 udpkt._pksiz = 7 ; 104 udpkt._pkid = 0xAA ; 105 udpkt._pkdev = UDCUNIT(unit); 106 udpkt._pkcmd = 0x40; /* control command */ 107 if (io->i_ino.i_dev == 1) { 108 udpkt._pkdev += 4; /* Floppy */ 109 udpkt._pkfnc = 2; /* format floppy */ 110 } 111 else udpkt._pkfnc = 2; /* format disk */ 112 udpkt._pkcnt = 3 << 8; /* EOT (sort of) */ 113 if (movep21(&udpkt,cntaddr+0x105,7)) { 114 cntaddr[OB1] = (char)0x80 ; /* signal packet transmitted */ 115 cntaddr[IB2] = (char)0 ; /* clear ACK/NAK field */ 116 cntaddr[INT] = (char)0x0 ; /* interrupt the controller */ 117 } 118 else { 119 printf ("Wrong command packet arrived at UDC\n"); 120 printf ("Original UDC\n"); 121 for (i = 0; i < sizeof(udpkt); i++ ) 122 printf(" %0x\t%0x\n", ((char *)&udpkt)[i*2] & 0xff, 123 cntaddr[0x105+i*2] & 0xff); 124 } 125 /* 126 * 127 * Wait until done (no interrupts now). 128 * 129 */ 130 wait: 131 timeout = 10000; 132 while (cntaddr[IB2] != (char)0x06 && cntaddr[IB2] != (char)0x15) { 133 /************** 134 DELAY(10000); 135 timeout--; 136 if (timeout <= 0) { 137 printf("UDC controller timeout\n"); 138 return(0); 139 } 140 *****************/ 141 } 142 udpkt._pksiz = 21; 143 if (cntaddr[IB2] == (char)0x15) { 144 if (retries-- < 0) { 145 printf("Too many NAK from UDC - give up\n"); 146 return(0); 147 } else goto loop; 148 } 149 150 while (cntaddr[IB1] != (char)DEVRDY) 151 /* DELAY (10000); /* Wait for his response */; 152 153 154 /* Ignore unsolicited status messages */ 155 if (cntaddr[PKID] != (char)udpkt._pkid && cntaddr[PKSTT] == (char)0x80) 156 { 157 cntaddr[IB1] = (char)0; 158 cntaddr[OB2] = (char)6; 159 cntaddr[INT] = (char)0x80; 160 goto loop; 161 } 162 if (cntaddr[PKID] != (char)udpkt._pkid || 163 cntaddr[PKDEV] != (char)udpkt._pkdev || 164 cntaddr[PKLEN] != (char)19 || 165 cntaddr[PKCMD] != (char)udpkt._pkcmd || 166 cntaddr[PKSTT] != (char)0x70 || /* Command completion */ 167 cntaddr[STAT1] != (char)0 || 168 cntaddr[STAT2] != (char)0 ) { 169 printf ("Strange status from UDC:\n"); 170 printf("Packet id=%x,unit=%x,original command=%x,status type=%x,status=%x\n", 171 cntaddr[PKID] & 0xff, 172 cntaddr[PKDEV] & 0xff, 173 cntaddr[PKCMD] & 0xff, 174 cntaddr[PKSTT] & 0xff, 175 (cntaddr[STAT1]*256+cntaddr[STAT2]) & 0xffff); 176 if (cntaddr[PKLEN] > 9) { 177 printf("More response info : "); 178 for (i=1; i<=cntaddr[PKLEN]-9; i++) 179 printf("%x ", cntaddr[STAT2+2*i] & 0xff); 180 printf("\n"); 181 } 182 cntaddr[IB1] = (char)0; 183 cntaddr[OB2] = (char)6; 184 cntaddr[INT] = (char)0x80; 185 return(0); 186 } else { 187 cntaddr[IB1] = (char)0; 188 cntaddr[OB2] = (char)6; 189 cntaddr[INT] = (char)0x80; 190 mtpr(PADC, 0); /* So data will come in right */ 191 return(io->i_cc); 192 } 193 } 194 195 /* 196 * Transfer a 21 bytes packet to the controller. 197 * the message is written to odd addresses, starting from 198 * the given address. 199 * For reliability, read it back and see if it's the same. If not, 200 * return an error code. 201 */ 202 movep21(src, dest,cnt) 203 204 char *src, *dest; 205 int cnt; 206 { 207 register char *running_src, *running_dest; 208 register long running_cnt; 209 210 running_src = src; 211 running_dest = dest; 212 running_cnt = cnt; 213 214 for (; running_cnt>0; running_cnt--) { 215 *running_dest++ = *running_src++; 216 running_dest++; 217 } 218 running_src = src; 219 running_dest = dest; 220 running_cnt = cnt; 221 for (; running_cnt>0; running_cnt--) { 222 if (*running_dest++ != *running_src++) return(0); 223 running_dest++; 224 } 225 return(1); 226 } 227 228 udopen(io) 229 struct iob *io; 230 { 231 register char *cntaddr; 232 /* 233 * Just clean up any junk in the controller's response buffers. 234 */ 235 cntaddr = (char *)(udstd[0] + VBIOBASE); /* Booting from cntrlr 0 */ 236 while (cntaddr[IB1] == (char)DEVRDY) { 237 cntaddr[IB1] = (char)0; 238 cntaddr[OB2] = (char)0x06; /* ACK */ 239 cntaddr[INT] = (char)0; /* Force him to listen and respond */ 240 DELAY(50000); 241 } 242 } 243