xref: /csrg-svn/sys/tahoe/stand/udcformat.c (revision 25931)
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