Commit | Line | Data |
---|---|---|
1a9cb196 | 1 | /* xpformat.c 1.2 86/01/21 */ |
a877b33b SL |
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 | ||
1a9cb196 | 11 | #include "../tahoevba/vbaparam.h" |
a877b33b SL |
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 | ||
1a9cb196 | 95 | xpaddr = (struct xpdevice *)(xpstand[0] + VBIOBASE); /* formatting on cntl 0 */ |
a877b33b SL |
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 | ||
1a9cb196 | 161 | xpaddr = (struct xpdevice *)(xpstand[0] + VBIOBASE); /* formatting on cntl 0 */ |
a877b33b SL |
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 | } |