xref: /csrg-svn/sys/tahoe/stand/xpformat.c (revision 25931)
1*25931Ssam /*	xpformat.c	1.2	86/01/21	*/
225874Ssam /*
325874Ssam /* format disk on Xylogics controller - fsd/smd/fujitsu type */
425874Ssam /**/
525874Ssam 
625874Ssam #include "../machine/mtpr.h"
725874Ssam #include "param.h"
825874Ssam #include "inode.h"
925874Ssam #include "saio.h"
1025874Ssam 
11*25931Ssam #include "../tahoevba/vbaparam.h"
1225874Ssam #include "../tahoevba/xpreg.h"
1325874Ssam 
1425874Ssam char disk[10] ;			/* disk type (smd/fsd/fuj) */
1525874Ssam char drive[10] ;		/* drive number */
1625874Ssam char start[10];
1725874Ssam char buf[512];			/* format data buffer */
1825874Ssam 
1925874Ssam int vdebug = 1;
2025874Ssam 
2125874Ssam long	xpstand[] = {
2225874Ssam 		0x0fee40 };
2325874Ssam 
2425874Ssam struct	xp_iopb *iopb = &iopbx;
2525874Ssam int dsktype;
2625874Ssam int nsect,ncyl,ntrack;
2725874Ssam 
2825874Ssam #define XY_SHORT(x)	(short)((((x) >> 8) & 0xff) + (((x) << 8) & 0xff00))
2925874Ssam #define	b_cylin b_resid
3025874Ssam int xytimeout;
3125874Ssam #define POLLTILLDONE(x) { xytimeout = 1000*(x); \
3225874Ssam 			while (xpaddr->xpcsr & XP_GBSY) { \
3325874Ssam 				DELAY(1000); \
3425874Ssam 				xytimeout--; \
3525874Ssam 				if (xytimeout <= 0) { \
3625874Ssam 					printf("XY timeout\n"); \
3725874Ssam 					return(0); \
3825874Ssam 				} \
3925874Ssam 			} \
4025874Ssam 		}
4125874Ssam 
main()4225874Ssam main()
4325874Ssam {
4425874Ssam 	int j, c, i, n;
4525874Ssam 
4625874Ssam 	printf("Drive type [fsd/smd/fuj]: ");
4725874Ssam 	gets(disk);
4825874Ssam 	printf("Drive number [0-3]: ");
4925874Ssam 	gets(drive);
5025874Ssam 	j = number(drive);
5125874Ssam 	if ((strcmp(disk,"fsd") || strcmp(disk,"smd") ||
5225874Ssam 	     strcmp(disk,"fuj")) && ( j <= 3))
5325874Ssam 	{
5425874Ssam 		if (xpstart(disk,j) == 0) {
5525874Ssam 			printf("Initialization failed (drive not ready?), giving up!\n");
5625874Ssam 			return;
5725874Ssam 		}
5825874Ssam 		printf("Type  <return> to start formatting ");
5925874Ssam 		gets(start);
6025874Ssam 		if (xpformat(disk,j));
6125874Ssam 			printf("Formatting completed. \n");
6225874Ssam 	}
6325874Ssam 	else if (j>3) printf("Illegal drive number\n");
6425874Ssam 	     else printf("Illegal drive type\n");
6525874Ssam }
6625874Ssam 
number(response)6725874Ssam int number (response)
6825874Ssam char *response;
6925874Ssam {
7025874Ssam 	int	i, j;
7125874Ssam 
7225874Ssam 	j = 0;	/* Total */
7325874Ssam 	while (*response == ' ' || *response == '\t') response++;
7425874Ssam 	while (*response >= '0' && *response <= '9') {
7525874Ssam 		j = j*10 + *response - '0';
7625874Ssam 		response++;
7725874Ssam 	}
7825874Ssam 	return (j);
7925874Ssam }
8025874Ssam 
xpstart(disk,unit)8125874Ssam xpstart(disk,unit)
8225874Ssam char *disk;
8325874Ssam int unit;
8425874Ssam {
8525874Ssam 	struct xpdevice *xpaddr;
8625874Ssam 	int ret;
8725874Ssam 
8825874Ssam 	/*
8925874Ssam 	 * Check if a drive is really there. (NOP selects the drive and
9025874Ssam 	 * returns DRDY status
9125874Ssam 	 */
9225874Ssam 	xpmkiopb(XP_NOP,unit,0,0,0,0,0,0);
9325874Ssam 	iopb->io_comm &= ~XP_IEN;		/* disable interrupts */
9425874Ssam 
95*25931Ssam 	xpaddr = (struct xpdevice *)(xpstand[0] + VBIOBASE); /* formatting on cntl 0  */
9625874Ssam 	ret = xpaddr->xpreset;			/* reset controller */
9725874Ssam 	DELAY(400);				/* wait 400 ns */
9825874Ssam 	xpdgo(xpaddr,iopb);	/* start the controller */
9925874Ssam 	DELAY(200);	/* wait 200 ns before checking CSR for completion */
10025874Ssam 
10125874Ssam 	POLLTILLDONE(1)
10225874Ssam 	DELAY(200);
10325874Ssam 	uncache((char *)&iopb->io_status);
10425874Ssam 	if ((XY_SHORT(iopb->io_status) != 5) ||  /* 5 = no errors, xy450, DONE */
10525874Ssam 		!(xpaddr->xpcsr & XP_DRDY) ||	/* drive is not ready */
10625874Ssam 		(xpaddr->xpcsr & (XP_ERR | XP_DERR))) { /* errors? */
10725874Ssam 			printf("XY start error. Status = %x, xpcsr= %x\n",
10825874Ssam 				XY_SHORT(iopb->io_status),xpaddr->xpcsr);
10925874Ssam 		return(0);
11025874Ssam 	}
11125874Ssam 	/*
11225874Ssam 	 * now set the drive size parameters in the controller
11325874Ssam 	*/
11425874Ssam 	if (strcmp(disk,"fsd")) {
11525874Ssam 		xpmkiopb(XP_DSIZE,unit,9,822,31,0,0,0); /* 160M fsd */
11625874Ssam 		dsktype = 0;
11725874Ssam 		nsect = 32;
11825874Ssam 		ncyl = 823;
11925874Ssam 		ntrack = 10;
12025874Ssam 	}
12125874Ssam 	else
12225874Ssam 	  if (strcmp(disk,"smd")) {
12325874Ssam 		xpmkiopb(XP_DSIZE,unit,18,822,31,0,0,0x40); /* 300M smd */
12425874Ssam 		dsktype = 0x40;
12525874Ssam 		nsect = 32;
12625874Ssam 		ncyl = 823;
12725874Ssam 		ntrack = 19;
12825874Ssam 	  }
12925874Ssam 	  else {
13025874Ssam 		xpmkiopb(XP_DSIZE,unit,19,841,45,0,0,0x80);  /* 474M Fujitsu */
13125874Ssam 		dsktype = 0x80;
13225874Ssam 		nsect = 46;
13325874Ssam 		ncyl = 842;
13425874Ssam 		ntrack = 20;
13525874Ssam 	       }
13625874Ssam 	iopb->io_comm &= ~XP_IEN;	/* disable interrupts */
13725874Ssam 	xpdgo(xpaddr,iopb);
13825874Ssam 	DELAY(200);
13925874Ssam 
14025874Ssam 	POLLTILLDONE(1)
14125874Ssam 	DELAY(200);
14225874Ssam 	uncache((char *)&iopb->io_status);
14325874Ssam 	if ((XY_SHORT(iopb->io_status) != 5) || 		/* errors */
14425874Ssam 		!(xpaddr->xpcsr & XP_DRDY) ||
14525874Ssam 		(xpaddr->xpcsr & (XP_ERR | XP_DERR)))
14625874Ssam 	{
14725874Ssam 		printf("XY set size error. status= %x, drive $d, type %s\n",
14825874Ssam 			XY_SHORT(iopb->io_status),unit,disk);
14925874Ssam 		return(0);
15025874Ssam 	}
15125874Ssam 	else return(1);
15225874Ssam }
15325874Ssam 
xpformat(disk,unit)15425874Ssam xpformat(disk,unit)
15525874Ssam char disk[10];
15625874Ssam int unit;
15725874Ssam {
15825874Ssam 	struct xpdevice *xpaddr;
15925874Ssam 	int i,j,flag;
16025874Ssam 
161*25931Ssam 	xpaddr = (struct xpdevice *)(xpstand[0] + VBIOBASE); /* formatting on cntl 0  */
16225874Ssam 	xpmkiopb(XP_FORMAT,unit,0,0,0,nsect,0,dsktype);
16325874Ssam 	for (i=0; i<ncyl; i++) {
16425874Ssam 		iopb->io_comm &= ~XP_IEN;	/* disable interrupts */
16525874Ssam 		iopb->io_status = 0;
16625874Ssam 		iopb->io_sect = 0;
16725874Ssam 		iopb->io_scnt = XY_SHORT(nsect*ntrack);
16825874Ssam 		iopb->io_cyl = XY_SHORT(i);
16925874Ssam 		iopb->io_head = 0;
17025874Ssam 		xpdgo(xpaddr,iopb);
17125874Ssam 		DELAY(200);
17225874Ssam 
17325874Ssam 		POLLTILLDONE(1*60)
17425874Ssam 		DELAY(200);
17525874Ssam 		uncache((char *)&iopb->io_status);
17625874Ssam 		if ((XY_SHORT(iopb->io_status) != 5) ||
17725874Ssam 			(xpaddr->xpcsr & (XP_ERR | XP_DERR)) )
17825874Ssam 		{
17925874Ssam 			printf("XY format error %x, drive $d, type %s\n",
18025874Ssam 				XY_SHORT(iopb->io_status),unit,disk);
18125874Ssam 			return(0);
18225874Ssam 		}
18325874Ssam 		printf(".");
18425874Ssam 	}
18525874Ssam 	return(1);
18625874Ssam }
18725874Ssam 
strcmp(str1,str2)18825874Ssam strcmp(str1,str2)
18925874Ssam char *str1;
19025874Ssam char *str2;
19125874Ssam {
19225874Ssam 
19325874Ssam 	while (*str1++ && *str2++ )
19425874Ssam 		if (*str1 != *str2) return(0) ;
19525874Ssam 	return(1);
19625874Ssam }
19725874Ssam 
19825874Ssam /*
19925874Ssam  * Now all ready to go, stuff the registers.
20025874Ssam  */
xpdgo(xpaddr,iopb)20125874Ssam xpdgo(xpaddr, iopb)
20225874Ssam 	register struct xpdevice *xpaddr;
20325874Ssam 	register struct xp_iopb *iopb;
20425874Ssam {
20525874Ssam 	movob(&xpaddr->xpmrel, (u_char)((int)iopb >> 24));
20625874Ssam 	DELAY(5);
20725874Ssam 	movob(&xpaddr->xplrel, (u_char)((int)iopb >> 16));
20825874Ssam 	DELAY(5);
20925874Ssam 	movob(&xpaddr->xpmba, (u_char)((int)iopb >> 8));
21025874Ssam 	DELAY(5);
21125874Ssam 	movob(&xpaddr->xplba, (u_char)((int)iopb));
21225874Ssam 	DELAY(5);
21325874Ssam 	movob(&xpaddr->xpcsr, XP_GBSY) ;
21425874Ssam }
21525874Ssam 
21625874Ssam /*
21725874Ssam  * Fill the iopb with the appropriate data.
21825874Ssam  */
xpmkiopb(cmd,unit,head,cylinder,sector,scount,baddr,xptype)21925874Ssam xpmkiopb(cmd,unit,head,cylinder,sector,scount,baddr,xptype)
22025874Ssam   unsigned int cmd, unit, head, cylinder, sector, scount, xptype;
22125874Ssam   caddr_t baddr;
22225874Ssam {
22325874Ssam 	iopb->io_comm = cmd | XP_RELO ;
22425874Ssam 	iopb->io_imode = XPM_ASR | XPM_EEF | XPM_ECC;
22525874Ssam 	iopb->io_throt = XPT_T128;
22625874Ssam 	iopb->io_drive = xptype | unit;
22725874Ssam 	iopb->io_head = head;
22825874Ssam 	iopb->io_sect = sector;
22925874Ssam 	iopb->io_cyl = XY_SHORT(cylinder);
23025874Ssam 	iopb->io_scnt = XY_SHORT(scount);
23125874Ssam 	iopb->io_mladdr = XY_SHORT((int)baddr & 0xffff);
23225874Ssam 	iopb->io_mhaddr = XY_SHORT(((int)baddr >> 16) & 0xffff);
23325874Ssam 	iopb->io_status = 0;
23425874Ssam }
235