1 /* xpformat.c 1.2 86/01/21 */ 2 /* 3 /* format disk on Xylogics controller - fsd/smd/fujitsu type */ 4 /**/ 5 6 #include "../machine/mtpr.h" 7 #include "param.h" 8 #include "inode.h" 9 #include "saio.h" 10 11 #include "../tahoevba/vbaparam.h" 12 #include "../tahoevba/xpreg.h" 13 14 char disk[10] ; /* disk type (smd/fsd/fuj) */ 15 char drive[10] ; /* drive number */ 16 char start[10]; 17 char buf[512]; /* format data buffer */ 18 19 int vdebug = 1; 20 21 long xpstand[] = { 22 0x0fee40 }; 23 24 struct xp_iopb *iopb = &iopbx; 25 int dsktype; 26 int nsect,ncyl,ntrack; 27 28 #define XY_SHORT(x) (short)((((x) >> 8) & 0xff) + (((x) << 8) & 0xff00)) 29 #define b_cylin b_resid 30 int xytimeout; 31 #define POLLTILLDONE(x) { xytimeout = 1000*(x); \ 32 while (xpaddr->xpcsr & XP_GBSY) { \ 33 DELAY(1000); \ 34 xytimeout--; \ 35 if (xytimeout <= 0) { \ 36 printf("XY timeout\n"); \ 37 return(0); \ 38 } \ 39 } \ 40 } 41 42 main() 43 { 44 int j, c, i, n; 45 46 printf("Drive type [fsd/smd/fuj]: "); 47 gets(disk); 48 printf("Drive number [0-3]: "); 49 gets(drive); 50 j = number(drive); 51 if ((strcmp(disk,"fsd") || strcmp(disk,"smd") || 52 strcmp(disk,"fuj")) && ( j <= 3)) 53 { 54 if (xpstart(disk,j) == 0) { 55 printf("Initialization failed (drive not ready?), giving up!\n"); 56 return; 57 } 58 printf("Type <return> to start formatting "); 59 gets(start); 60 if (xpformat(disk,j)); 61 printf("Formatting completed. \n"); 62 } 63 else if (j>3) printf("Illegal drive number\n"); 64 else printf("Illegal drive type\n"); 65 } 66 67 int number (response) 68 char *response; 69 { 70 int i, j; 71 72 j = 0; /* Total */ 73 while (*response == ' ' || *response == '\t') response++; 74 while (*response >= '0' && *response <= '9') { 75 j = j*10 + *response - '0'; 76 response++; 77 } 78 return (j); 79 } 80 81 xpstart(disk,unit) 82 char *disk; 83 int unit; 84 { 85 struct xpdevice *xpaddr; 86 int ret; 87 88 /* 89 * Check if a drive is really there. (NOP selects the drive and 90 * returns DRDY status 91 */ 92 xpmkiopb(XP_NOP,unit,0,0,0,0,0,0); 93 iopb->io_comm &= ~XP_IEN; /* disable interrupts */ 94 95 xpaddr = (struct xpdevice *)(xpstand[0] + VBIOBASE); /* formatting on cntl 0 */ 96 ret = xpaddr->xpreset; /* reset controller */ 97 DELAY(400); /* wait 400 ns */ 98 xpdgo(xpaddr,iopb); /* start the controller */ 99 DELAY(200); /* wait 200 ns before checking CSR for completion */ 100 101 POLLTILLDONE(1) 102 DELAY(200); 103 uncache((char *)&iopb->io_status); 104 if ((XY_SHORT(iopb->io_status) != 5) || /* 5 = no errors, xy450, DONE */ 105 !(xpaddr->xpcsr & XP_DRDY) || /* drive is not ready */ 106 (xpaddr->xpcsr & (XP_ERR | XP_DERR))) { /* errors? */ 107 printf("XY start error. Status = %x, xpcsr= %x\n", 108 XY_SHORT(iopb->io_status),xpaddr->xpcsr); 109 return(0); 110 } 111 /* 112 * now set the drive size parameters in the controller 113 */ 114 if (strcmp(disk,"fsd")) { 115 xpmkiopb(XP_DSIZE,unit,9,822,31,0,0,0); /* 160M fsd */ 116 dsktype = 0; 117 nsect = 32; 118 ncyl = 823; 119 ntrack = 10; 120 } 121 else 122 if (strcmp(disk,"smd")) { 123 xpmkiopb(XP_DSIZE,unit,18,822,31,0,0,0x40); /* 300M smd */ 124 dsktype = 0x40; 125 nsect = 32; 126 ncyl = 823; 127 ntrack = 19; 128 } 129 else { 130 xpmkiopb(XP_DSIZE,unit,19,841,45,0,0,0x80); /* 474M Fujitsu */ 131 dsktype = 0x80; 132 nsect = 46; 133 ncyl = 842; 134 ntrack = 20; 135 } 136 iopb->io_comm &= ~XP_IEN; /* disable interrupts */ 137 xpdgo(xpaddr,iopb); 138 DELAY(200); 139 140 POLLTILLDONE(1) 141 DELAY(200); 142 uncache((char *)&iopb->io_status); 143 if ((XY_SHORT(iopb->io_status) != 5) || /* errors */ 144 !(xpaddr->xpcsr & XP_DRDY) || 145 (xpaddr->xpcsr & (XP_ERR | XP_DERR))) 146 { 147 printf("XY set size error. status= %x, drive $d, type %s\n", 148 XY_SHORT(iopb->io_status),unit,disk); 149 return(0); 150 } 151 else return(1); 152 } 153 154 xpformat(disk,unit) 155 char disk[10]; 156 int unit; 157 { 158 struct xpdevice *xpaddr; 159 int i,j,flag; 160 161 xpaddr = (struct xpdevice *)(xpstand[0] + VBIOBASE); /* formatting on cntl 0 */ 162 xpmkiopb(XP_FORMAT,unit,0,0,0,nsect,0,dsktype); 163 for (i=0; i<ncyl; i++) { 164 iopb->io_comm &= ~XP_IEN; /* disable interrupts */ 165 iopb->io_status = 0; 166 iopb->io_sect = 0; 167 iopb->io_scnt = XY_SHORT(nsect*ntrack); 168 iopb->io_cyl = XY_SHORT(i); 169 iopb->io_head = 0; 170 xpdgo(xpaddr,iopb); 171 DELAY(200); 172 173 POLLTILLDONE(1*60) 174 DELAY(200); 175 uncache((char *)&iopb->io_status); 176 if ((XY_SHORT(iopb->io_status) != 5) || 177 (xpaddr->xpcsr & (XP_ERR | XP_DERR)) ) 178 { 179 printf("XY format error %x, drive $d, type %s\n", 180 XY_SHORT(iopb->io_status),unit,disk); 181 return(0); 182 } 183 printf("."); 184 } 185 return(1); 186 } 187 188 strcmp(str1,str2) 189 char *str1; 190 char *str2; 191 { 192 193 while (*str1++ && *str2++ ) 194 if (*str1 != *str2) return(0) ; 195 return(1); 196 } 197 198 /* 199 * Now all ready to go, stuff the registers. 200 */ 201 xpdgo(xpaddr, iopb) 202 register struct xpdevice *xpaddr; 203 register struct xp_iopb *iopb; 204 { 205 movob(&xpaddr->xpmrel, (u_char)((int)iopb >> 24)); 206 DELAY(5); 207 movob(&xpaddr->xplrel, (u_char)((int)iopb >> 16)); 208 DELAY(5); 209 movob(&xpaddr->xpmba, (u_char)((int)iopb >> 8)); 210 DELAY(5); 211 movob(&xpaddr->xplba, (u_char)((int)iopb)); 212 DELAY(5); 213 movob(&xpaddr->xpcsr, XP_GBSY) ; 214 } 215 216 /* 217 * Fill the iopb with the appropriate data. 218 */ 219 xpmkiopb(cmd,unit,head,cylinder,sector,scount,baddr,xptype) 220 unsigned int cmd, unit, head, cylinder, sector, scount, xptype; 221 caddr_t baddr; 222 { 223 iopb->io_comm = cmd | XP_RELO ; 224 iopb->io_imode = XPM_ASR | XPM_EEF | XPM_ECC; 225 iopb->io_throt = XPT_T128; 226 iopb->io_drive = xptype | unit; 227 iopb->io_head = head; 228 iopb->io_sect = sector; 229 iopb->io_cyl = XY_SHORT(cylinder); 230 iopb->io_scnt = XY_SHORT(scount); 231 iopb->io_mladdr = XY_SHORT((int)baddr & 0xffff); 232 iopb->io_mhaddr = XY_SHORT(((int)baddr >> 16) & 0xffff); 233 iopb->io_status = 0; 234 } 235