This source file includes following definitions.
- fdcprobe
- fdcattach
- fddprint
- fdcresult
- out_fdc
- fdcstart
- fdcstatus
- fdcpseudointr
- fdcintr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h>
48 #include <sys/file.h>
49 #include <sys/ioctl.h>
50 #include <sys/device.h>
51 #include <sys/disklabel.h>
52 #include <sys/dkstat.h>
53 #include <sys/disk.h>
54 #include <sys/buf.h>
55 #include <sys/malloc.h>
56 #include <sys/uio.h>
57 #include <sys/mtio.h>
58 #include <sys/syslog.h>
59 #include <sys/queue.h>
60 #include <sys/timeout.h>
61
62 #include <machine/cpu.h>
63 #include <machine/bus.h>
64 #include <machine/conf.h>
65 #include <machine/intr.h>
66 #include <machine/ioctl_fd.h>
67
68 #include <dev/isa/isavar.h>
69 #include <dev/isa/isadmavar.h>
70 #include <dev/isa/fdreg.h>
71
72 #if defined(__i386__) || defined(__amd64__)
73 #include <dev/ic/mc146818reg.h>
74 #include <i386/isa/nvram.h>
75 #endif
76
77 #include <dev/isa/fdlink.h>
78
79 #include "fd.h"
80
81
82 int fdcprobe(struct device *, void *, void *);
83 void fdcattach(struct device *, struct device *, void *);
84
85 struct cfattach fdc_ca = {
86 sizeof(struct fdc_softc), fdcprobe, fdcattach
87 };
88
89 struct cfdriver fdc_cd = {
90 NULL, "fdc", DV_DULL
91 };
92
93 int fddprint(void *, const char *);
94 int fdcintr(void *);
95
96 int
97 fdcprobe(parent, match, aux)
98 struct device *parent;
99 void *match, *aux;
100 {
101 register struct isa_attach_args *ia = aux;
102 bus_space_tag_t iot;
103 bus_space_handle_t ioh;
104 bus_space_handle_t ioh_ctl;
105 int rv;
106
107 iot = ia->ia_iot;
108 rv = 0;
109
110
111 if (bus_space_map(iot, ia->ia_iobase, FDC_NPORT, 0, &ioh))
112 return 0;
113 if (bus_space_map(iot, ia->ia_iobase + FDCTL_OFFSET,
114 FDCTL_NPORT, 0, &ioh_ctl))
115 return 0;
116
117
118 bus_space_write_1(iot, ioh, fdout, 0);
119 delay(100);
120 bus_space_write_1(iot, ioh, fdout, FDO_FRST);
121
122
123 if (out_fdc(iot, ioh, NE7CMD_SPECIFY) < 0)
124 goto out;
125 out_fdc(iot, ioh, 0xdf);
126 out_fdc(iot, ioh, 2);
127
128 rv = 1;
129 ia->ia_iosize = FDC_NPORT;
130 ia->ia_msize = 0;
131
132 out:
133 bus_space_unmap(iot, ioh, FDC_NPORT);
134 bus_space_unmap(iot, ioh_ctl, FDCTL_NPORT);
135 return rv;
136 }
137
138 void
139 fdcattach(parent, self, aux)
140 struct device *parent, *self;
141 void *aux;
142 {
143 struct fdc_softc *fdc = (void *)self;
144 bus_space_tag_t iot;
145 bus_space_handle_t ioh;
146 bus_space_handle_t ioh_ctl;
147 struct isa_attach_args *ia = aux;
148 struct fdc_attach_args fa;
149 int type;
150
151 iot = ia->ia_iot;
152
153
154 if (bus_space_map(iot, ia->ia_iobase, FDC_NPORT, 0, &ioh) ||
155 bus_space_map(iot, ia->ia_iobase + FDCTL_OFFSET,
156 FDCTL_NPORT, 0, &ioh_ctl))
157 panic("fdcattach: couldn't map I/O ports");
158
159 fdc->sc_iot = iot;
160 fdc->sc_ioh = ioh;
161 fdc->sc_ioh_ctl = ioh_ctl;
162
163 fdc->sc_drq = ia->ia_drq;
164 fdc->sc_state = DEVIDLE;
165 TAILQ_INIT(&fdc->sc_link.fdlink.sc_drives);
166
167 printf("\n");
168
169 fdc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
170 IPL_BIO, fdcintr, fdc, fdc->sc_dev.dv_xname);
171
172 #if defined(__i386__) || defined(__amd64__)
173
174
175
176
177 if (fdc->sc_dev.dv_unit == 0)
178 type = mc146818_read(NULL, NVRAM_DISKETTE);
179 else
180 #endif
181 type = -1;
182
183 timeout_set(&fdc->fdcpseudointr_to, fdcpseudointr, fdc);
184
185
186 for (fa.fa_drive = 0; fa.fa_drive < 4; fa.fa_drive++) {
187 fa.fa_flags = 0;
188 fa.fa_type = 0;
189 #if NFD > 0
190 if (type >= 0 && fa.fa_drive < 2)
191 fa.fa_deftype = fd_nvtotype(fdc->sc_dev.dv_xname,
192 type, fa.fa_drive);
193 else
194 #endif
195 fa.fa_deftype = NULL;
196 (void)config_found(self, (void *)&fa, fddprint);
197 }
198 }
199
200
201
202
203
204
205
206
207 int
208 fddprint(aux, fdc)
209 void *aux;
210 const char *fdc;
211 {
212 register struct fdc_attach_args *fa = aux;
213
214 if (!fdc)
215 printf(" drive %d", fa->fa_drive);
216 return QUIET;
217 }
218
219 int
220 fdcresult(fdc)
221 struct fdc_softc *fdc;
222 {
223 bus_space_tag_t iot = fdc->sc_iot;
224 bus_space_handle_t ioh = fdc->sc_ioh;
225 u_char i;
226 int j = 100000, n = 0;
227
228 for (; j; j--) {
229 i = bus_space_read_1(iot, ioh, fdsts) &
230 (NE7_DIO | NE7_RQM | NE7_CB);
231 if (i == NE7_RQM)
232 return n;
233 if (i == (NE7_DIO | NE7_RQM | NE7_CB)) {
234 if (n >= sizeof(fdc->sc_status)) {
235 log(LOG_ERR, "fdcresult: overrun\n");
236 return -1;
237 }
238 fdc->sc_status[n++] =
239 bus_space_read_1(iot, ioh, fddata);
240 }
241 delay(10);
242 }
243 return -1;
244 }
245
246 int
247 out_fdc(iot, ioh, x)
248 bus_space_tag_t iot;
249 bus_space_handle_t ioh;
250 u_char x;
251 {
252 int i = 100000;
253
254 while ((bus_space_read_1(iot, ioh, fdsts) & NE7_DIO) && i-- > 0);
255 if (i <= 0)
256 return -1;
257 while ((bus_space_read_1(iot, ioh, fdsts) & NE7_RQM) == 0 && i-- > 0);
258 if (i <= 0)
259 return -1;
260 bus_space_write_1(iot, ioh, fddata, x);
261 return 0;
262 }
263
264 void
265 fdcstart(fdc)
266 struct fdc_softc *fdc;
267 {
268
269 #ifdef DIAGNOSTIC
270
271
272 if (fdc->sc_state != DEVIDLE) {
273 printf("fdcstart: not idle\n");
274 return;
275 }
276 #endif
277 (void) fdcintr(fdc);
278 }
279
280 void
281 fdcstatus(dv, n, s)
282 struct device *dv;
283 int n;
284 char *s;
285 {
286 struct fdc_softc *fdc = (void *)dv->dv_parent;
287
288 if (n == 0) {
289 out_fdc(fdc->sc_iot, fdc->sc_ioh, NE7CMD_SENSEI);
290 (void) fdcresult(fdc);
291 n = 2;
292 }
293
294 printf("%s: %s", dv->dv_xname, s);
295
296 switch (n) {
297 case 0:
298 printf("\n");
299 break;
300 case 2:
301 printf(" (st0 %b cyl %d)\n",
302 fdc->sc_status[0], NE7_ST0BITS,
303 fdc->sc_status[1]);
304 break;
305 case 7:
306 printf(" (st0 %b st1 %b st2 %b cyl %d head %d sec %d)\n",
307 fdc->sc_status[0], NE7_ST0BITS,
308 fdc->sc_status[1], NE7_ST1BITS,
309 fdc->sc_status[2], NE7_ST2BITS,
310 fdc->sc_status[3], fdc->sc_status[4], fdc->sc_status[5]);
311 break;
312 #ifdef DIAGNOSTIC
313 default:
314 printf("\nfdcstatus: weird size");
315 break;
316 #endif
317 }
318 }
319
320 void
321 fdcpseudointr(arg)
322 void *arg;
323 {
324 int s;
325
326
327 s = splbio();
328 (void) fdcintr(arg);
329 splx(s);
330 }
331
332 int
333 fdcintr(arg)
334 void *arg;
335 {
336 #if NFD > 0
337 struct fdc_softc *fdc = arg;
338 extern int fdintr(struct fdc_softc *);
339
340
341 return (fdintr(fdc));
342 #else
343 printf("fdcintr: got interrupt, but no devices!\n");
344 return (1);
345 #endif
346 }