1*25931Ssam /* udcformat.c 1.2 86/01/21 */
225872Ssam /* format disk - cmd/smd type */
325872Ssam
425872Ssam #include "../machine/mtpr.h"
525872Ssam
625872Ssam #include "param.h"
725872Ssam #include "inode.h"
825872Ssam #include "fs.h"
925872Ssam
10*25931Ssam #include "../tahoevba/vbaparam.h"
1125872Ssam #include "../tahoevba/udc.h"
1225872Ssam
1325872Ssam #include "saio.h"
1425872Ssam
1525872Ssam char disk[50] = "xmd(00,000)";
1625872Ssam
main()1725872Ssam main()
1825872Ssam {
1925872Ssam int j, c, i, n;
2025872Ssam char buf[50];
2125872Ssam int output;
2225872Ssam
2325872Ssam do {
2425872Ssam printf("Device to format: ");
2525872Ssam gets(disk);
2625872Ssam output = open(disk, 1);
2725872Ssam if (output <= 0) printf("Cannot open disk\n", disk);
2825872Ssam /* dummy call just to get to the local strategy routine */
2925872Ssam else {
3025872Ssam printf("Type <return> to start formatting ");
3125872Ssam gets(buf);
3225872Ssam write(output,buf,0);
3325872Ssam printf("Formatting completed. \n");
3425872Ssam }
3525872Ssam } while (output <= 0);
3625872Ssam
3725872Ssam }
3825872Ssam
3925872Ssam /*
4025872Ssam * Universal disk controller driver for the Motorola M68000/IPC.
4125872Ssam * Stand-alone version (no interrupts, etc.)
4225872Ssam */
4325872Ssam
4425872Ssam
4525872Ssam static struct UDPAC udpkt = {
4625872Ssam 2, 0, 21, 0, 0, 0, 0, SECTSIZ, {0, 0}, 0, 0, 3
4725872Ssam } ;
4825872Ssam
4925872Ssam long udstd[] = { /* May be used some day to boot from any of
5025872Ssam * several UDC controllers */
5125872Ssam 0xf0000
5225872Ssam };
5325872Ssam
5425872Ssam /*****************************************************
5525872Ssam /*
5625872Ssam /*The next layout of major/minor number assignments are for the UDC
5725872Ssam /*devices.
5825872Ssam /*
5925872Ssam /* 1
6025872Ssam /* 5 8 7 4 3 2 0
6125872Ssam /* +----------------+-----+-+-+-----+
6225872Ssam /* | Major device # | |D|R| FLS |
6325872Ssam /* +----------------+-----+-+-+-----+
6425872Ssam /* | | |_____ File system # ( 0-7 )
6525872Ssam /* | |_________ Fixed (0) or removable(1) media
6625872Ssam /* |___________ Drive # (0-1)
6725872Ssam /*
6825872Ssam /* For the floppy drives, the major / minor assignment will be
6925872Ssam /* 1
7025872Ssam /* 5 8 7 4 3 2 0
7125872Ssam /* +----------------+-----+---+-----+
7225872Ssam /* | 4 | | D | FLS |
7325872Ssam /* +----------------+-----+---+-----+
7425872Ssam /* | |_____ File system # ( 0-7 )
7525872Ssam /* |____________ Drive # (0-3)
7625872Ssam /*
7725872Ssam /****************************************************/
7825872Ssam
7925872Ssam #define UDCUNIT(x) ((minor(x) & 0x18) >> 3)
8025872Ssam
udstrategy(io,func)8125872Ssam udstrategy(io, func)
8225872Ssam register struct iob *io;
8325872Ssam long func; /* Known to be 'read' */
8425872Ssam {
8525872Ssam
8625872Ssam register unit = io->i_unit;
8725872Ssam register bn = io->i_bn;
8825872Ssam register char *cntaddr ;
8925872Ssam register char *addr ;
9025872Ssam register timeout , retries , i;
9125872Ssam
92*25931Ssam cntaddr = (char *)(udstd[0] + VBIOBASE); /* Booting from cntrlr 0 */
9325872Ssam /*
9425872Ssam * prepare a command packet for the controller.
9525872Ssam */
9625872Ssam retries = 3;
9725872Ssam loop:
9825872Ssam if (cntaddr[OB1]) {
9925872Ssam printf("UDC controller not ready, %x=%x\n",OB1+cntaddr,
10025872Ssam cntaddr[OB1] & 0xff);
10125872Ssam return(0);
10225872Ssam }
10325872Ssam udpkt._pksiz = 7 ;
10425872Ssam udpkt._pkid = 0xAA ;
10525872Ssam udpkt._pkdev = UDCUNIT(unit);
10625872Ssam udpkt._pkcmd = 0x40; /* control command */
10725872Ssam if (io->i_ino.i_dev == 1) {
10825872Ssam udpkt._pkdev += 4; /* Floppy */
10925872Ssam udpkt._pkfnc = 2; /* format floppy */
11025872Ssam }
11125872Ssam else udpkt._pkfnc = 2; /* format disk */
11225872Ssam udpkt._pkcnt = 3 << 8; /* EOT (sort of) */
11325872Ssam if (movep21(&udpkt,cntaddr+0x105,7)) {
11425872Ssam cntaddr[OB1] = (char)0x80 ; /* signal packet transmitted */
11525872Ssam cntaddr[IB2] = (char)0 ; /* clear ACK/NAK field */
11625872Ssam cntaddr[INT] = (char)0x0 ; /* interrupt the controller */
11725872Ssam }
11825872Ssam else {
11925872Ssam printf ("Wrong command packet arrived at UDC\n");
12025872Ssam printf ("Original UDC\n");
12125872Ssam for (i = 0; i < sizeof(udpkt); i++ )
12225872Ssam printf(" %0x\t%0x\n", ((char *)&udpkt)[i*2] & 0xff,
12325872Ssam cntaddr[0x105+i*2] & 0xff);
12425872Ssam }
12525872Ssam /*
12625872Ssam *
12725872Ssam * Wait until done (no interrupts now).
12825872Ssam *
12925872Ssam */
13025872Ssam wait:
13125872Ssam timeout = 10000;
13225872Ssam while (cntaddr[IB2] != (char)0x06 && cntaddr[IB2] != (char)0x15) {
13325872Ssam /**************
13425872Ssam DELAY(10000);
13525872Ssam timeout--;
13625872Ssam if (timeout <= 0) {
13725872Ssam printf("UDC controller timeout\n");
13825872Ssam return(0);
13925872Ssam }
14025872Ssam *****************/
14125872Ssam }
14225872Ssam udpkt._pksiz = 21;
14325872Ssam if (cntaddr[IB2] == (char)0x15) {
14425872Ssam if (retries-- < 0) {
14525872Ssam printf("Too many NAK from UDC - give up\n");
14625872Ssam return(0);
14725872Ssam } else goto loop;
14825872Ssam }
14925872Ssam
15025872Ssam while (cntaddr[IB1] != (char)DEVRDY)
15125872Ssam /* DELAY (10000); /* Wait for his response */;
15225872Ssam
15325872Ssam
15425872Ssam /* Ignore unsolicited status messages */
15525872Ssam if (cntaddr[PKID] != (char)udpkt._pkid && cntaddr[PKSTT] == (char)0x80)
15625872Ssam {
15725872Ssam cntaddr[IB1] = (char)0;
15825872Ssam cntaddr[OB2] = (char)6;
15925872Ssam cntaddr[INT] = (char)0x80;
16025872Ssam goto loop;
16125872Ssam }
16225872Ssam if (cntaddr[PKID] != (char)udpkt._pkid ||
16325872Ssam cntaddr[PKDEV] != (char)udpkt._pkdev ||
16425872Ssam cntaddr[PKLEN] != (char)19 ||
16525872Ssam cntaddr[PKCMD] != (char)udpkt._pkcmd ||
16625872Ssam cntaddr[PKSTT] != (char)0x70 || /* Command completion */
16725872Ssam cntaddr[STAT1] != (char)0 ||
16825872Ssam cntaddr[STAT2] != (char)0 ) {
16925872Ssam printf ("Strange status from UDC:\n");
17025872Ssam printf("Packet id=%x,unit=%x,original command=%x,status type=%x,status=%x\n",
17125872Ssam cntaddr[PKID] & 0xff,
17225872Ssam cntaddr[PKDEV] & 0xff,
17325872Ssam cntaddr[PKCMD] & 0xff,
17425872Ssam cntaddr[PKSTT] & 0xff,
17525872Ssam (cntaddr[STAT1]*256+cntaddr[STAT2]) & 0xffff);
17625872Ssam if (cntaddr[PKLEN] > 9) {
17725872Ssam printf("More response info : ");
17825872Ssam for (i=1; i<=cntaddr[PKLEN]-9; i++)
17925872Ssam printf("%x ", cntaddr[STAT2+2*i] & 0xff);
18025872Ssam printf("\n");
18125872Ssam }
18225872Ssam cntaddr[IB1] = (char)0;
18325872Ssam cntaddr[OB2] = (char)6;
18425872Ssam cntaddr[INT] = (char)0x80;
18525872Ssam return(0);
18625872Ssam } else {
18725872Ssam cntaddr[IB1] = (char)0;
18825872Ssam cntaddr[OB2] = (char)6;
18925872Ssam cntaddr[INT] = (char)0x80;
19025872Ssam mtpr(PADC, 0); /* So data will come in right */
19125872Ssam return(io->i_cc);
19225872Ssam }
19325872Ssam }
19425872Ssam
19525872Ssam /*
19625872Ssam * Transfer a 21 bytes packet to the controller.
19725872Ssam * the message is written to odd addresses, starting from
19825872Ssam * the given address.
19925872Ssam * For reliability, read it back and see if it's the same. If not,
20025872Ssam * return an error code.
20125872Ssam */
movep21(src,dest,cnt)20225872Ssam movep21(src, dest,cnt)
20325872Ssam
20425872Ssam char *src, *dest;
20525872Ssam int cnt;
20625872Ssam {
20725872Ssam register char *running_src, *running_dest;
20825872Ssam register long running_cnt;
20925872Ssam
21025872Ssam running_src = src;
21125872Ssam running_dest = dest;
21225872Ssam running_cnt = cnt;
21325872Ssam
21425872Ssam for (; running_cnt>0; running_cnt--) {
21525872Ssam *running_dest++ = *running_src++;
21625872Ssam running_dest++;
21725872Ssam }
21825872Ssam running_src = src;
21925872Ssam running_dest = dest;
22025872Ssam running_cnt = cnt;
22125872Ssam for (; running_cnt>0; running_cnt--) {
22225872Ssam if (*running_dest++ != *running_src++) return(0);
22325872Ssam running_dest++;
22425872Ssam }
22525872Ssam return(1);
22625872Ssam }
22725872Ssam
22825872Ssam udopen(io)
22925872Ssam struct iob *io;
23025872Ssam {
23125872Ssam register char *cntaddr;
23225872Ssam /*
23325872Ssam * Just clean up any junk in the controller's response buffers.
23425872Ssam */
235*25931Ssam cntaddr = (char *)(udstd[0] + VBIOBASE); /* Booting from cntrlr 0 */
23625872Ssam while (cntaddr[IB1] == (char)DEVRDY) {
23725872Ssam cntaddr[IB1] = (char)0;
23825872Ssam cntaddr[OB2] = (char)0x06; /* ACK */
23925872Ssam cntaddr[INT] = (char)0; /* Force him to listen and respond */
24025872Ssam DELAY(50000);
24125872Ssam }
24225872Ssam }
243