rf.c revision 1.3 1 1.3 lukem /* $NetBSD: rf.c,v 1.3 2003/07/14 15:47:26 lukem Exp $ */
2 1.1 ragge /*
3 1.1 ragge * Copyright (c) 2002 Jochen Kunz.
4 1.1 ragge * All rights reserved.
5 1.1 ragge *
6 1.1 ragge * Redistribution and use in source and binary forms, with or without
7 1.1 ragge * modification, are permitted provided that the following conditions
8 1.1 ragge * are met:
9 1.1 ragge * 1. Redistributions of source code must retain the above copyright
10 1.1 ragge * notice, this list of conditions and the following disclaimer.
11 1.1 ragge * 2. Redistributions in binary form must reproduce the above copyright
12 1.1 ragge * notice, this list of conditions and the following disclaimer in the
13 1.1 ragge * documentation and/or other materials provided with the distribution.
14 1.1 ragge * 3. The name of Jochen Kunz may not be used to endorse or promote
15 1.1 ragge * products derived from this software without specific prior
16 1.1 ragge * written permission.
17 1.1 ragge *
18 1.1 ragge * THIS SOFTWARE IS PROVIDED BY JOCHEN KUNZ
19 1.1 ragge * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 1.1 ragge * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 1.1 ragge * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JOCHEN KUNZ
22 1.1 ragge * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 1.1 ragge * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 1.1 ragge * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 1.1 ragge * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 1.1 ragge * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 1.1 ragge * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 1.1 ragge * POSSIBILITY OF SUCH DAMAGE.
29 1.1 ragge */
30 1.1 ragge
31 1.1 ragge /*
32 1.1 ragge TODO:
33 1.1 ragge - Better LBN bound checking, block padding for SD disks.
34 1.1 ragge - Formating / "Set Density"
35 1.1 ragge - Better error handling / detaild error reason reportnig.
36 1.1 ragge */
37 1.3 lukem
38 1.3 lukem #include <sys/cdefs.h>
39 1.3 lukem __KERNEL_RCSID(0, "$NetBSD: rf.c,v 1.3 2003/07/14 15:47:26 lukem Exp $");
40 1.1 ragge
41 1.1 ragge /* autoconfig stuff */
42 1.1 ragge #include <sys/param.h>
43 1.1 ragge #include <sys/device.h>
44 1.1 ragge #include <sys/conf.h>
45 1.1 ragge #include "locators.h"
46 1.1 ragge #include "ioconf.h"
47 1.1 ragge
48 1.1 ragge /* bus_space / bus_dma */
49 1.1 ragge #include <machine/bus.h>
50 1.1 ragge
51 1.1 ragge /* UniBus / QBus specific stuff */
52 1.1 ragge #include <dev/qbus/ubavar.h>
53 1.1 ragge
54 1.1 ragge /* disk interface */
55 1.1 ragge #include <sys/types.h>
56 1.1 ragge #include <sys/disklabel.h>
57 1.1 ragge #include <sys/disk.h>
58 1.1 ragge
59 1.1 ragge /* general system data and functions */
60 1.1 ragge #include <sys/systm.h>
61 1.1 ragge #include <sys/ioctl.h>
62 1.1 ragge #include <sys/ioccom.h>
63 1.1 ragge
64 1.1 ragge /* physio / buffer handling */
65 1.1 ragge #include <sys/buf.h>
66 1.1 ragge
67 1.1 ragge /* tsleep / sleep / wakeup */
68 1.1 ragge #include <sys/proc.h>
69 1.1 ragge /* hz for above */
70 1.1 ragge #include <sys/kernel.h>
71 1.1 ragge
72 1.1 ragge /* bitdefinitions for RX211 */
73 1.1 ragge #include <dev/qbus/rfreg.h>
74 1.1 ragge
75 1.1 ragge
76 1.1 ragge #define RFS_DENS 0x0001 /* single or double density */
77 1.1 ragge #define RFS_AD 0x0002 /* density auto detect */
78 1.1 ragge #define RFS_NOTINIT 0x0000 /* not initialized */
79 1.1 ragge #define RFS_PROBING 0x0010 /* density detect / verify started */
80 1.1 ragge #define RFS_FBUF 0x0020 /* Fill Buffer */
81 1.1 ragge #define RFS_EBUF 0x0030 /* Empty Buffer */
82 1.1 ragge #define RFS_WSEC 0x0040 /* Write Sector */
83 1.1 ragge #define RFS_RSEC 0x0050 /* Read Sector */
84 1.1 ragge #define RFS_SMD 0x0060 /* Set Media Density */
85 1.1 ragge #define RFS_RSTAT 0x0070 /* Read Status */
86 1.1 ragge #define RFS_WDDS 0x0080 /* Write Deleted Data Sector */
87 1.1 ragge #define RFS_REC 0x0090 /* Read Error Code */
88 1.1 ragge #define RFS_IDLE 0x00a0 /* controller is idle */
89 1.1 ragge #define RFS_CMDS 0x00f0 /* command mask */
90 1.1 ragge #define RFS_SETCMD(rf, state) ((rf) = ((rf) & ~RFS_CMDS) | (state))
91 1.1 ragge
92 1.1 ragge
93 1.1 ragge
94 1.1 ragge /* autoconfig stuff */
95 1.1 ragge static int rfc_match(struct device *, struct cfdata *, void *);
96 1.1 ragge static void rfc_attach(struct device *, struct device *, void *);
97 1.1 ragge static int rf_match(struct device *, struct cfdata *, void *);
98 1.1 ragge static void rf_attach(struct device *, struct device *, void *);
99 1.1 ragge static int rf_print(void *, const char *);
100 1.1 ragge
101 1.1 ragge /* device interfce functions / interface to disk(9) */
102 1.1 ragge dev_type_open(rfopen);
103 1.1 ragge dev_type_close(rfclose);
104 1.1 ragge dev_type_read(rfread);
105 1.1 ragge dev_type_write(rfwrite);
106 1.1 ragge dev_type_ioctl(rfioctl);
107 1.1 ragge dev_type_strategy(rfstrategy);
108 1.1 ragge dev_type_dump(rfdump);
109 1.1 ragge dev_type_size(rfsize);
110 1.1 ragge
111 1.1 ragge
112 1.1 ragge /* Entries in block and character major device number switch table. */
113 1.1 ragge const struct bdevsw rf_bdevsw = {
114 1.1 ragge rfopen,
115 1.1 ragge rfclose,
116 1.1 ragge rfstrategy,
117 1.1 ragge rfioctl,
118 1.1 ragge rfdump,
119 1.1 ragge rfsize,
120 1.1 ragge D_DISK
121 1.1 ragge };
122 1.1 ragge
123 1.1 ragge const struct cdevsw rf_cdevsw = {
124 1.1 ragge rfopen,
125 1.1 ragge rfclose,
126 1.1 ragge rfread,
127 1.1 ragge rfwrite,
128 1.1 ragge rfioctl,
129 1.1 ragge nostop,
130 1.1 ragge notty,
131 1.1 ragge nopoll,
132 1.1 ragge nommap,
133 1.1 ragge nokqfilter,
134 1.1 ragge D_DISK
135 1.1 ragge };
136 1.1 ragge
137 1.1 ragge
138 1.1 ragge
139 1.1 ragge struct rfc_softc {
140 1.1 ragge struct device sc_dev; /* common device data */
141 1.1 ragge struct device *sc_childs[2]; /* child devices */
142 1.1 ragge struct evcnt sc_intr_count; /* Interrupt counter for statistics */
143 1.1 ragge struct buf *sc_curbuf; /* buf that is currently in work */
144 1.1 ragge bus_space_tag_t sc_iot; /* bus_space IO tag */
145 1.1 ragge bus_space_handle_t sc_ioh; /* bus_space IO handle */
146 1.1 ragge bus_dma_tag_t sc_dmat; /* bus_dma DMA tag */
147 1.1 ragge bus_dmamap_t sc_dmam; /* bus_dma DMA map */
148 1.1 ragge caddr_t sc_bufidx; /* current position in buffer data */
149 1.1 ragge int sc_curchild; /* child whos bufq is in work */
150 1.1 ragge int sc_bytesleft; /* bytes left to transfer */
151 1.1 ragge u_int8_t type; /* controller type, 1 or 2 */
152 1.1 ragge };
153 1.1 ragge
154 1.1 ragge
155 1.1 ragge
156 1.1 ragge CFATTACH_DECL(
157 1.1 ragge rfc,
158 1.1 ragge sizeof(struct rfc_softc),
159 1.1 ragge rfc_match,
160 1.1 ragge rfc_attach,
161 1.1 ragge NULL,
162 1.1 ragge NULL
163 1.1 ragge );
164 1.1 ragge
165 1.1 ragge
166 1.1 ragge
167 1.1 ragge struct rf_softc {
168 1.1 ragge struct device sc_dev; /* common device data */
169 1.1 ragge struct disk sc_disk; /* common disk device data */
170 1.1 ragge struct bufq_state sc_bufq; /* queue of pending transfers */
171 1.1 ragge int sc_state; /* state of drive */
172 1.1 ragge int sc_open; /* simultaneous opens */
173 1.1 ragge u_int8_t sc_dnum; /* drive number, 0 or 1 */
174 1.1 ragge };
175 1.1 ragge
176 1.1 ragge
177 1.1 ragge
178 1.1 ragge CFATTACH_DECL(
179 1.1 ragge rf,
180 1.1 ragge sizeof(struct rf_softc),
181 1.1 ragge rf_match,
182 1.1 ragge rf_attach,
183 1.1 ragge NULL,
184 1.1 ragge NULL
185 1.1 ragge );
186 1.1 ragge
187 1.1 ragge
188 1.1 ragge
189 1.1 ragge struct rfc_attach_args {
190 1.1 ragge u_int8_t type; /* controller type, 1 or 2 */
191 1.1 ragge u_int8_t dnum; /* drive number, 0 or 1 */
192 1.1 ragge };
193 1.1 ragge
194 1.1 ragge
195 1.1 ragge
196 1.1 ragge struct dkdriver rfdkdriver = {
197 1.1 ragge rfstrategy
198 1.1 ragge };
199 1.1 ragge
200 1.1 ragge
201 1.1 ragge
202 1.1 ragge /* helper functions */
203 1.1 ragge int rfc_sendcmd(struct rfc_softc *, int, int, int);
204 1.1 ragge static void rfc_intr(void *);
205 1.1 ragge
206 1.1 ragge
207 1.1 ragge
208 1.1 ragge /*
209 1.1 ragge * Issue a reset command to the controller and look for the bits in
210 1.1 ragge * RX2CS and RX2ES.
211 1.1 ragge * RX2CS_RX02 and / or RX2CS_DD can be set,
212 1.1 ragge * RX2ES has to be set, all other bits must be 0
213 1.1 ragge */
214 1.1 ragge int
215 1.1 ragge rfc_match(struct device *parent, struct cfdata *match, void *aux)
216 1.1 ragge {
217 1.1 ragge struct uba_attach_args *ua = aux;
218 1.1 ragge int i;
219 1.1 ragge
220 1.1 ragge /* Issue reset command. */
221 1.1 ragge bus_space_write_2(ua->ua_iot, ua->ua_ioh, RX2CS, RX2CS_INIT);
222 1.1 ragge /* Wait for the controller to become ready, that is when
223 1.1 ragge * RX2CS_DONE, RX2ES_RDY and RX2ES_ID are set. */
224 1.1 ragge for (i = 0 ; i < 20 ; i++) {
225 1.1 ragge if ((bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2CS)
226 1.1 ragge & RX2CS_DONE) != 0
227 1.1 ragge && (bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2ES)
228 1.1 ragge & (RX2ES_RDY | RX2ES_ID)) != 0)
229 1.1 ragge break;
230 1.1 ragge DELAY(100000); /* wait 100ms */
231 1.1 ragge }
232 1.1 ragge /*
233 1.1 ragge * Give up if the timeout has elapsed
234 1.1 ragge * and the controller is not ready.
235 1.1 ragge */
236 1.1 ragge if (i >= 20)
237 1.1 ragge return(0);
238 1.1 ragge /*
239 1.1 ragge * Issue a Read Status command with interrupt enabled.
240 1.1 ragge * The uba(4) driver wants to catch the interrupt to get the
241 1.1 ragge * interrupt vector and level of the device
242 1.1 ragge */
243 1.1 ragge bus_space_write_2(ua->ua_iot, ua->ua_ioh, RX2CS,
244 1.1 ragge RX2CS_RSTAT | RX2CS_IE);
245 1.1 ragge /*
246 1.1 ragge * Wait for command to finish, ignore errors and
247 1.1 ragge * abort if the controller does not respond within the timeout
248 1.1 ragge */
249 1.1 ragge for (i = 0 ; i < 20 ; i++) {
250 1.1 ragge if ((bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2CS)
251 1.1 ragge & (RX2CS_DONE | RX2CS_IE)) != 0
252 1.1 ragge && (bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2ES)
253 1.1 ragge & RX2ES_RDY) != 0 )
254 1.1 ragge return(1);
255 1.1 ragge DELAY(100000); /* wait 100ms */
256 1.1 ragge }
257 1.1 ragge return(0);
258 1.1 ragge }
259 1.1 ragge
260 1.1 ragge
261 1.1 ragge
262 1.1 ragge /* #define RX02_PROBE 1 */
263 1.1 ragge #ifdef RX02_PROBE
264 1.1 ragge /*
265 1.1 ragge * Probe the density of an inserted floppy disk.
266 1.1 ragge * This is done by reading a sector from disk.
267 1.1 ragge * Return -1 on error, 0 on SD and 1 on DD.
268 1.1 ragge */
269 1.1 ragge int rfcprobedens(struct rfc_softc *, int);
270 1.1 ragge int
271 1.1 ragge rfcprobedens(struct rfc_softc *rfc_sc, int dnum)
272 1.1 ragge {
273 1.1 ragge int dens_flag;
274 1.1 ragge int i;
275 1.1 ragge
276 1.1 ragge dens_flag = 0;
277 1.1 ragge do {
278 1.1 ragge bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS,
279 1.1 ragge RX2CS_RSEC | (dens_flag == 0 ? 0 : RX2CS_DD)
280 1.1 ragge | (dnum == 0 ? 0 : RX2CS_US));
281 1.1 ragge /*
282 1.1 ragge * Transfer request set?
283 1.1 ragge * Wait 50us, the controller needs this time to setle
284 1.1 ragge */
285 1.1 ragge DELAY(50);
286 1.1 ragge if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
287 1.1 ragge & RX2CS_TR) == 0) {
288 1.1 ragge printf("%s: did not respond to Read Sector CMD(1)\n",
289 1.1 ragge rfc_sc->sc_dev.dv_xname);
290 1.1 ragge return(-1);
291 1.1 ragge }
292 1.1 ragge bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2SA, 1);
293 1.1 ragge /* Wait 50us, the controller needs this time to setle */
294 1.1 ragge DELAY(50);
295 1.1 ragge if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
296 1.1 ragge & RX2CS_TR) == 0) {
297 1.1 ragge printf("%s: did not respond to Read Sector CMD(2)\n",
298 1.1 ragge rfc_sc->sc_dev.dv_xname);
299 1.1 ragge return(-1);
300 1.1 ragge }
301 1.1 ragge bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2TA, 1);
302 1.1 ragge /* Wait for the command to finish */
303 1.1 ragge for (i = 0 ; i < 200 ; i++) {
304 1.1 ragge if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
305 1.1 ragge RX2CS) & RX2CS_DONE) != 0)
306 1.1 ragge break;
307 1.1 ragge DELAY(10000); /* wait 10ms */
308 1.1 ragge }
309 1.1 ragge if (i >= 200) {
310 1.1 ragge printf("%s: did not respond to Read Sector CMD(3)\n",
311 1.1 ragge rfc_sc->sc_dev.dv_xname);
312 1.1 ragge return(-1);
313 1.1 ragge }
314 1.1 ragge if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
315 1.1 ragge & RX2CS_ERR) == 0)
316 1.1 ragge return(dens_flag);
317 1.1 ragge } while (rfc_sc->type == 2 && dens_flag++ == 0);
318 1.1 ragge return(-1);
319 1.1 ragge }
320 1.1 ragge #endif /* RX02_PROBE */
321 1.1 ragge
322 1.1 ragge
323 1.1 ragge
324 1.1 ragge void
325 1.1 ragge rfc_attach(struct device *parent, struct device *self, void *aux)
326 1.1 ragge {
327 1.1 ragge struct rfc_softc *rfc_sc = (struct rfc_softc *)self;
328 1.1 ragge struct uba_attach_args *ua = aux;
329 1.1 ragge struct rfc_attach_args rfc_aa;
330 1.1 ragge int i;
331 1.1 ragge
332 1.1 ragge rfc_sc->sc_iot = ua->ua_iot;
333 1.1 ragge rfc_sc->sc_ioh = ua->ua_ioh;
334 1.1 ragge rfc_sc->sc_dmat = ua->ua_dmat;
335 1.1 ragge rfc_sc->sc_curbuf = NULL;
336 1.1 ragge /* Tell the QBus busdriver about our interrupt handler. */
337 1.1 ragge uba_intr_establish(ua->ua_icookie, ua->ua_cvec, rfc_intr, rfc_sc,
338 1.1 ragge &rfc_sc->sc_intr_count);
339 1.1 ragge /* Attach to the interrupt counter, see evcnt(9) */
340 1.1 ragge evcnt_attach_dynamic(&rfc_sc->sc_intr_count, EVCNT_TYPE_INTR,
341 1.1 ragge ua->ua_evcnt, rfc_sc->sc_dev.dv_xname, "intr");
342 1.1 ragge /* get a bus_dma(9) handle */
343 1.1 ragge i = bus_dmamap_create(rfc_sc->sc_dmat, RX2_BYTE_DD, 1, RX2_BYTE_DD, 0,
344 1.1 ragge BUS_DMA_ALLOCNOW, &rfc_sc->sc_dmam);
345 1.1 ragge if (i != 0) {
346 1.2 wiz printf("rfc_attach: Error creating bus DMA map: %d\n", i);
347 1.1 ragge return;
348 1.1 ragge }
349 1.1 ragge
350 1.1 ragge /* Issue reset command. */
351 1.1 ragge bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, RX2CS_INIT);
352 1.1 ragge /*
353 1.1 ragge * Wait for the controller to become ready, that is when
354 1.1 ragge * RX2CS_DONE, RX2ES_RDY and RX2ES_ID are set.
355 1.1 ragge */
356 1.1 ragge for (i = 0 ; i < 20 ; i++) {
357 1.1 ragge if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
358 1.1 ragge & RX2CS_DONE) != 0
359 1.1 ragge && (bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2ES)
360 1.1 ragge & (RX2ES_RDY | RX2ES_ID)) != 0)
361 1.1 ragge break;
362 1.1 ragge DELAY(100000); /* wait 100ms */
363 1.1 ragge }
364 1.1 ragge /*
365 1.1 ragge * Give up if the timeout has elapsed
366 1.1 ragge * and the controller is not ready.
367 1.1 ragge */
368 1.1 ragge if (i >= 20) {
369 1.1 ragge printf(": did not respond to INIT CMD\n");
370 1.1 ragge return;
371 1.1 ragge }
372 1.1 ragge /* Is ths a RX01 or a RX02? */
373 1.1 ragge if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
374 1.1 ragge & RX2CS_RX02) != 0) {
375 1.1 ragge rfc_sc->type = 2;
376 1.1 ragge rfc_aa.type = 2;
377 1.1 ragge } else {
378 1.1 ragge rfc_sc->type = 1;
379 1.1 ragge rfc_aa.type = 1;
380 1.1 ragge }
381 1.1 ragge printf(": RX0%d\n", rfc_sc->type);
382 1.1 ragge
383 1.1 ragge #ifndef RX02_PROBE
384 1.1 ragge /*
385 1.1 ragge * Bouth disk drievs and the controller are one physical unit.
386 1.1 ragge * If we found the controller, there will be bouth disk drievs.
387 1.1 ragge * So attach them.
388 1.1 ragge */
389 1.1 ragge rfc_aa.dnum = 0;
390 1.1 ragge rfc_sc->sc_childs[0] = config_found(&rfc_sc->sc_dev, &rfc_aa,rf_print);
391 1.1 ragge rfc_aa.dnum = 1;
392 1.1 ragge rfc_sc->sc_childs[1] = config_found(&rfc_sc->sc_dev, &rfc_aa,rf_print);
393 1.1 ragge #else /* RX02_PROBE */
394 1.1 ragge /*
395 1.1 ragge * There are clones of the DEC RX system with standard shugart
396 1.1 ragge * interface. In this case we can not be sure that there are
397 1.1 ragge * bouth disk drievs. So we want to do a detection of attached
398 1.1 ragge * drives. This is done by reading a sector from disk. This means
399 1.1 ragge * that there must be a formated disk in the drive at boot time.
400 1.1 ragge * This is bad, but I did not find an other way to detect the
401 1.1 ragge * (non)existence of a floppy drive.
402 1.1 ragge */
403 1.1 ragge if (rfcprobedens(rfc_sc, 0) >= 0) {
404 1.1 ragge rfc_aa.dnum = 0;
405 1.1 ragge rfc_sc->sc_childs[0] = config_found(&rfc_sc->sc_dev, &rfc_aa,
406 1.1 ragge rf_print);
407 1.1 ragge } else
408 1.1 ragge rfc_sc->sc_childs[0] = NULL;
409 1.1 ragge if (rfcprobedens(rfc_sc, 1) >= 0) {
410 1.1 ragge rfc_aa.dnum = 1;
411 1.1 ragge rfc_sc->sc_childs[1] = config_found(&rfc_sc->sc_dev, &rfc_aa,
412 1.1 ragge rf_print);
413 1.1 ragge } else
414 1.1 ragge rfc_sc->sc_childs[1] = NULL;
415 1.1 ragge #endif /* RX02_PROBE */
416 1.1 ragge return;
417 1.1 ragge }
418 1.1 ragge
419 1.1 ragge
420 1.1 ragge
421 1.1 ragge int
422 1.1 ragge rf_match(struct device *parent, struct cfdata *match, void *aux)
423 1.1 ragge {
424 1.1 ragge struct rfc_attach_args *rfc_aa = aux;
425 1.1 ragge
426 1.1 ragge /*
427 1.1 ragge * Only attach if the locator is wildcarded or
428 1.1 ragge * if the specified locator addresses the current device.
429 1.1 ragge */
430 1.1 ragge if (match->cf_loc[RFCCF_DRIVE] == RFCCF_DRIVE_DEFAULT ||
431 1.1 ragge match->cf_loc[RFCCF_DRIVE] == rfc_aa->dnum)
432 1.1 ragge return(1);
433 1.1 ragge return(0);
434 1.1 ragge }
435 1.1 ragge
436 1.1 ragge
437 1.1 ragge
438 1.1 ragge void
439 1.1 ragge rf_attach(struct device *parent, struct device *self, void *aux)
440 1.1 ragge {
441 1.1 ragge struct rf_softc *rf_sc = (struct rf_softc *)self;
442 1.1 ragge struct rfc_attach_args *rfc_aa = (struct rfc_attach_args *)aux;
443 1.1 ragge struct rfc_softc *rfc_sc;
444 1.1 ragge struct disklabel *dl;
445 1.1 ragge
446 1.1 ragge rfc_sc = (struct rfc_softc *)rf_sc->sc_dev.dv_parent;
447 1.1 ragge rf_sc->sc_dnum = rfc_aa->dnum;
448 1.1 ragge rf_sc->sc_state = 0;
449 1.1 ragge rf_sc->sc_open = 0;
450 1.1 ragge rf_sc->sc_disk.dk_name = rf_sc->sc_dev.dv_xname;
451 1.1 ragge rf_sc->sc_disk.dk_driver = &rfdkdriver;
452 1.1 ragge disk_attach(&rf_sc->sc_disk);
453 1.1 ragge dl = rf_sc->sc_disk.dk_label;
454 1.1 ragge dl->d_type = DTYPE_FLOPPY; /* drive type */
455 1.1 ragge dl->d_magic = DISKMAGIC; /* the magic number */
456 1.1 ragge dl->d_magic2 = DISKMAGIC;
457 1.1 ragge dl->d_typename[0] = 'R';
458 1.1 ragge dl->d_typename[1] = 'X';
459 1.1 ragge dl->d_typename[2] = '0';
460 1.1 ragge dl->d_typename[3] = rfc_sc->type == 1 ? '1' : '2'; /* type name */
461 1.1 ragge dl->d_typename[4] = '\0';
462 1.1 ragge dl->d_secsize = DEV_BSIZE; /* bytes per sector */
463 1.1 ragge /*
464 1.1 ragge * Fill in some values to have a initialized data structure. Some
465 1.1 ragge * values will be reset by rfopen() depending on the actual density.
466 1.1 ragge */
467 1.1 ragge dl->d_nsectors = RX2_SECTORS; /* sectors per track */
468 1.1 ragge dl->d_ntracks = 1; /* tracks per cylinder */
469 1.1 ragge dl->d_ncylinders = RX2_TRACKS; /* cylinders per unit */
470 1.1 ragge dl->d_secpercyl = RX2_SECTORS; /* sectors per cylinder */
471 1.1 ragge dl->d_secperunit = RX2_SECTORS * RX2_TRACKS; /* sectors per unit */
472 1.1 ragge dl->d_rpm = 360; /* rotational speed */
473 1.1 ragge dl->d_interleave = 1; /* hardware sector interleave */
474 1.1 ragge /* number of partitions in following */
475 1.1 ragge dl->d_npartitions = MAXPARTITIONS;
476 1.1 ragge dl->d_bbsize = 0; /* size of boot area at sn0, bytes */
477 1.1 ragge dl->d_sbsize = 0; /* max size of fs superblock, bytes */
478 1.1 ragge /* number of sectors in partition */
479 1.1 ragge dl->d_partitions[0].p_size = 501;
480 1.1 ragge dl->d_partitions[0].p_offset = 0; /* starting sector */
481 1.1 ragge dl->d_partitions[0].p_fsize = 0; /* fs basic fragment size */
482 1.1 ragge dl->d_partitions[0].p_fstype = 0; /* fs type */
483 1.1 ragge dl->d_partitions[0].p_frag = 0; /* fs fragments per block */
484 1.1 ragge dl->d_partitions[1].p_size = RX2_SECTORS * RX2_TRACKS / 2;
485 1.1 ragge dl->d_partitions[1].p_offset = 0; /* starting sector */
486 1.1 ragge dl->d_partitions[1].p_fsize = 0; /* fs basic fragment size */
487 1.1 ragge dl->d_partitions[1].p_fstype = 0; /* fs type */
488 1.1 ragge dl->d_partitions[1].p_frag = 0; /* fs fragments per block */
489 1.1 ragge dl->d_partitions[2].p_size = RX2_SECTORS * RX2_TRACKS;
490 1.1 ragge dl->d_partitions[2].p_offset = 0; /* starting sector */
491 1.1 ragge dl->d_partitions[2].p_fsize = 0; /* fs basic fragment size */
492 1.1 ragge dl->d_partitions[2].p_fstype = 0; /* fs type */
493 1.1 ragge dl->d_partitions[2].p_frag = 0; /* fs fragments per block */
494 1.1 ragge bufq_alloc(&rf_sc->sc_bufq, BUFQ_DISKSORT | BUFQ_SORT_CYLINDER);
495 1.1 ragge printf("\n");
496 1.1 ragge return;
497 1.1 ragge }
498 1.1 ragge
499 1.1 ragge
500 1.1 ragge
501 1.1 ragge int
502 1.1 ragge rf_print(void *aux, const char *name)
503 1.1 ragge {
504 1.1 ragge struct rfc_attach_args *rfc_aa = aux;
505 1.1 ragge
506 1.1 ragge if (name != NULL)
507 1.1 ragge aprint_normal("RX0%d at %s", rfc_aa->type, name);
508 1.1 ragge aprint_normal(" drive %d", rfc_aa->dnum);
509 1.1 ragge return(UNCONF);
510 1.1 ragge }
511 1.1 ragge
512 1.1 ragge
513 1.1 ragge
514 1.1 ragge /* Send a command to the controller */
515 1.1 ragge int
516 1.1 ragge rfc_sendcmd(struct rfc_softc *rfc_sc, int cmd, int data1, int data2)
517 1.1 ragge {
518 1.1 ragge
519 1.1 ragge /* Write command to CSR. */
520 1.1 ragge bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, cmd);
521 1.1 ragge /* Wait 50us, the controller needs this time to setle. */
522 1.1 ragge DELAY(50);
523 1.1 ragge /* Write parameter 1 to DBR */
524 1.1 ragge if ((cmd & RX2CS_FC) != RX2CS_RSTAT) {
525 1.1 ragge /* Transfer request set? */
526 1.1 ragge if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
527 1.1 ragge & RX2CS_TR) == 0) {
528 1.1 ragge printf("%s: did not respond to CMD %x (1)\n",
529 1.1 ragge rfc_sc->sc_dev.dv_xname, cmd);
530 1.1 ragge return(-1);
531 1.1 ragge }
532 1.1 ragge bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2DB,
533 1.1 ragge data1);
534 1.1 ragge }
535 1.1 ragge /* Write parameter 2 to DBR */
536 1.1 ragge if ((cmd & RX2CS_FC) <= RX2CS_RSEC || (cmd & RX2CS_FC) == RX2CS_WDDS) {
537 1.1 ragge /* Wait 50us, the controller needs this time to setle. */
538 1.1 ragge DELAY(50);
539 1.1 ragge /* Transfer request set? */
540 1.1 ragge if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
541 1.1 ragge & RX2CS_TR) == 0) {
542 1.1 ragge printf("%s: did not respond to CMD %x (2)\n",
543 1.1 ragge rfc_sc->sc_dev.dv_xname, cmd);
544 1.1 ragge return(-1);
545 1.1 ragge }
546 1.1 ragge bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2DB,
547 1.1 ragge data2);
548 1.1 ragge }
549 1.1 ragge return(1);
550 1.1 ragge }
551 1.1 ragge
552 1.1 ragge
553 1.1 ragge
554 1.1 ragge void
555 1.1 ragge rfstrategy(struct buf *buf)
556 1.1 ragge {
557 1.1 ragge struct rf_softc *rf_sc;
558 1.1 ragge struct rfc_softc *rfc_sc;
559 1.1 ragge int i;
560 1.1 ragge
561 1.1 ragge i = DISKUNIT(buf->b_dev);
562 1.1 ragge if (i >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[i]) == NULL) {
563 1.1 ragge buf->b_flags |= B_ERROR;
564 1.1 ragge buf->b_error = ENXIO;
565 1.1 ragge biodone(buf);
566 1.1 ragge return;
567 1.1 ragge }
568 1.1 ragge rfc_sc = (struct rfc_softc *)rf_sc->sc_dev.dv_parent;
569 1.1 ragge /* We are going to operate on a non open dev? PANIC! */
570 1.1 ragge if (rf_sc->sc_open == 0)
571 1.1 ragge panic("rfstrategy: can not operate on non-open drive %s (1)",
572 1.1 ragge rf_sc->sc_dev.dv_xname);
573 1.1 ragge if (buf->b_bcount == 0) {
574 1.1 ragge biodone(buf);
575 1.1 ragge return;
576 1.1 ragge }
577 1.1 ragge /*
578 1.1 ragge * BUFQ_PUT() operates on b_rawblkno. rfstrategy() gets
579 1.1 ragge * only b_blkno that is partition relative. As a floppy does not
580 1.1 ragge * have partitions b_rawblkno == b_blkno.
581 1.1 ragge */
582 1.1 ragge buf->b_rawblkno = buf->b_blkno;
583 1.1 ragge /*
584 1.1 ragge * from sys/kern/subr_disk.c:
585 1.1 ragge * Seek sort for disks. We depend on the driver which calls us using
586 1.1 ragge * b_resid as the current cylinder number.
587 1.1 ragge */
588 1.1 ragge i = splbio();
589 1.1 ragge if (rfc_sc->sc_curbuf == NULL) {
590 1.1 ragge rfc_sc->sc_curchild = rf_sc->sc_dnum;
591 1.1 ragge rfc_sc->sc_curbuf = buf;
592 1.1 ragge rfc_sc->sc_bufidx = buf->b_un.b_addr;
593 1.1 ragge rfc_sc->sc_bytesleft = buf->b_bcount;
594 1.1 ragge rfc_intr(rfc_sc);
595 1.1 ragge } else {
596 1.1 ragge buf->b_resid = buf->b_blkno / RX2_SECTORS;
597 1.1 ragge BUFQ_PUT(&rf_sc->sc_bufq, buf);
598 1.1 ragge rfc_sc->sc_curbuf->b_resid = 0;
599 1.1 ragge }
600 1.1 ragge splx(i);
601 1.1 ragge return;
602 1.1 ragge }
603 1.1 ragge
604 1.1 ragge
605 1.1 ragge
606 1.1 ragge void
607 1.1 ragge rfc_intr(void *intarg)
608 1.1 ragge {
609 1.1 ragge struct rfc_softc *rfc_sc = intarg;
610 1.1 ragge struct rf_softc *rf_sc;
611 1.1 ragge struct rf_softc *other_drive;
612 1.1 ragge int i;
613 1.1 ragge
614 1.1 ragge rf_sc = (struct rf_softc *)rfc_sc->sc_childs[rfc_sc->sc_curchild];
615 1.1 ragge /*
616 1.1 ragge * First clean up from previous command...
617 1.1 ragge */
618 1.1 ragge switch (rf_sc->sc_state & RFS_CMDS) {
619 1.1 ragge case RFS_PROBING: /* density detect / verify started */
620 1.1 ragge disk_unbusy(&rf_sc->sc_disk, 0, 1);
621 1.1 ragge if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
622 1.1 ragge & RX2CS_ERR) == 0) {
623 1.1 ragge RFS_SETCMD(rf_sc->sc_state, RFS_IDLE);
624 1.1 ragge wakeup(rf_sc);
625 1.1 ragge } else {
626 1.1 ragge if (rfc_sc->type == 2
627 1.1 ragge && (rf_sc->sc_state & RFS_DENS) == 0
628 1.1 ragge && (rf_sc->sc_state & RFS_AD) != 0) {
629 1.1 ragge /* retry at DD */
630 1.1 ragge rf_sc->sc_state |= RFS_DENS;
631 1.1 ragge disk_busy(&rf_sc->sc_disk);
632 1.1 ragge if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE
633 1.1 ragge | RX2CS_DD | (rf_sc->sc_dnum == 0
634 1.1 ragge ? 0 : RX2CS_US), 1, 1) < 0) {
635 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
636 1.1 ragge RFS_SETCMD(rf_sc->sc_state,
637 1.1 ragge RFS_NOTINIT);
638 1.1 ragge wakeup(rf_sc);
639 1.1 ragge }
640 1.1 ragge } else {
641 1.1 ragge printf("%s: density error.\n",
642 1.1 ragge rf_sc->sc_dev.dv_xname);
643 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
644 1.1 ragge RFS_SETCMD(rf_sc->sc_state, RFS_NOTINIT);
645 1.1 ragge wakeup(rf_sc);
646 1.1 ragge }
647 1.1 ragge }
648 1.1 ragge return;
649 1.1 ragge case RFS_IDLE: /* controller is idle */
650 1.1 ragge if (rfc_sc->sc_curbuf->b_bcount
651 1.1 ragge % ((rf_sc->sc_state & RFS_DENS) == 0
652 1.1 ragge ? RX2_BYTE_SD : RX2_BYTE_DD) != 0) {
653 1.1 ragge /*
654 1.1 ragge * can only handle blocks that are a multiple of the
655 1.1 ragge * physical block size
656 1.1 ragge */
657 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
658 1.1 ragge break;
659 1.1 ragge }
660 1.1 ragge RFS_SETCMD(rf_sc->sc_state, (rfc_sc->sc_curbuf->b_flags
661 1.1 ragge & B_READ) != 0 ? RFS_RSEC : RFS_FBUF);
662 1.1 ragge break;
663 1.1 ragge case RFS_RSEC: /* Read Sector */
664 1.1 ragge disk_unbusy(&rf_sc->sc_disk, 0, 1);
665 1.1 ragge /* check for errors */
666 1.1 ragge if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
667 1.1 ragge & RX2CS_ERR) != 0) {
668 1.1 ragge /* should do more verbose error reporting */
669 1.1 ragge printf("rfc_intr: Error while reading secotr: %x\n",
670 1.1 ragge bus_space_read_2(rfc_sc->sc_iot,
671 1.1 ragge rfc_sc->sc_ioh, RX2ES) );
672 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
673 1.1 ragge break;
674 1.1 ragge }
675 1.1 ragge RFS_SETCMD(rf_sc->sc_state, RFS_EBUF);
676 1.1 ragge break;
677 1.1 ragge case RFS_WSEC: /* Write Sector */
678 1.1 ragge i = (rf_sc->sc_state & RFS_DENS) == 0
679 1.1 ragge ? RX2_BYTE_SD : RX2_BYTE_DD;
680 1.1 ragge disk_unbusy(&rf_sc->sc_disk, i, 0);
681 1.1 ragge /* check for errors */
682 1.1 ragge if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
683 1.1 ragge & RX2CS_ERR) != 0) {
684 1.1 ragge /* should do more verbose error reporting */
685 1.1 ragge printf("rfc_intr: Error while writing secotr: %x\n",
686 1.1 ragge bus_space_read_2(rfc_sc->sc_iot,
687 1.1 ragge rfc_sc->sc_ioh, RX2ES) );
688 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
689 1.1 ragge break;
690 1.1 ragge }
691 1.1 ragge if (rfc_sc->sc_bytesleft > i) {
692 1.1 ragge rfc_sc->sc_bytesleft -= i;
693 1.1 ragge rfc_sc->sc_bufidx += i;
694 1.1 ragge } else {
695 1.1 ragge biodone(rfc_sc->sc_curbuf);
696 1.1 ragge rfc_sc->sc_curbuf = BUFQ_GET(&rf_sc->sc_bufq);
697 1.1 ragge if (rfc_sc->sc_curbuf != NULL) {
698 1.1 ragge rfc_sc->sc_bufidx =
699 1.1 ragge rfc_sc->sc_curbuf->b_un.b_addr;
700 1.1 ragge rfc_sc->sc_bytesleft =
701 1.1 ragge rfc_sc->sc_curbuf->b_bcount;
702 1.1 ragge } else {
703 1.1 ragge RFS_SETCMD(rf_sc->sc_state, RFS_IDLE);
704 1.1 ragge /*
705 1.1 ragge * Switch to the other drive if there where
706 1.1 ragge * buffers queued while we where working on
707 1.1 ragge * the buffer queue of this drive
708 1.1 ragge */
709 1.1 ragge other_drive = (struct rf_softc *)
710 1.1 ragge rfc_sc->sc_childs[
711 1.1 ragge rfc_sc->sc_curchild == 0 ? 1 : 0];
712 1.1 ragge if (other_drive != NULL && BUFQ_PEEK(
713 1.1 ragge &other_drive->sc_bufq) != NULL) {
714 1.1 ragge rfc_sc->sc_curchild =
715 1.1 ragge rfc_sc->sc_curchild == 0 ? 1 : 0;
716 1.1 ragge rf_sc = other_drive;
717 1.1 ragge rfc_sc->sc_curbuf =
718 1.1 ragge BUFQ_GET(&rf_sc->sc_bufq);
719 1.1 ragge rfc_sc->sc_bufidx =
720 1.1 ragge rfc_sc->sc_curbuf->b_un.b_addr;
721 1.1 ragge rfc_sc->sc_bytesleft =
722 1.1 ragge rfc_sc->sc_curbuf->b_bcount;
723 1.1 ragge } else
724 1.1 ragge return;
725 1.1 ragge }
726 1.1 ragge }
727 1.1 ragge RFS_SETCMD(rf_sc->sc_state,
728 1.1 ragge (rfc_sc->sc_curbuf->b_flags & B_READ) != 0
729 1.1 ragge ? RFS_RSEC : RFS_FBUF);
730 1.1 ragge break;
731 1.1 ragge case RFS_FBUF: /* Fill Buffer */
732 1.1 ragge disk_unbusy(&rf_sc->sc_disk, 0, 0);
733 1.1 ragge /* check for errors */
734 1.1 ragge if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
735 1.1 ragge & RX2CS_ERR) != 0) {
736 1.1 ragge /* should do more verbose error reporting */
737 1.1 ragge printf("rfc_intr: Error while DMA: %x\n",
738 1.1 ragge bus_space_read_2(rfc_sc->sc_iot,
739 1.1 ragge rfc_sc->sc_ioh, RX2ES));
740 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
741 1.1 ragge }
742 1.1 ragge bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
743 1.1 ragge RFS_SETCMD(rf_sc->sc_state, RFS_WSEC);
744 1.1 ragge break;
745 1.1 ragge case RFS_EBUF: /* Empty Buffer */
746 1.1 ragge i = (rf_sc->sc_state & RFS_DENS) == 0
747 1.1 ragge ? RX2_BYTE_SD : RX2_BYTE_DD;
748 1.1 ragge disk_unbusy(&rf_sc->sc_disk, i, 1);
749 1.1 ragge /* check for errors */
750 1.1 ragge if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS)
751 1.1 ragge & RX2CS_ERR) != 0) {
752 1.1 ragge /* should do more verbose error reporting */
753 1.1 ragge printf("rfc_intr: Error while DMA: %x\n",
754 1.1 ragge bus_space_read_2(rfc_sc->sc_iot,
755 1.1 ragge rfc_sc->sc_ioh, RX2ES));
756 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
757 1.1 ragge }
758 1.1 ragge bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
759 1.1 ragge if (rfc_sc->sc_bytesleft > i) {
760 1.1 ragge rfc_sc->sc_bytesleft -= i;
761 1.1 ragge rfc_sc->sc_bufidx += i;
762 1.1 ragge } else {
763 1.1 ragge biodone(rfc_sc->sc_curbuf);
764 1.1 ragge rfc_sc->sc_curbuf = BUFQ_GET(&rf_sc->sc_bufq);
765 1.1 ragge if (rfc_sc->sc_curbuf != NULL) {
766 1.1 ragge rfc_sc->sc_bufidx =
767 1.1 ragge rfc_sc->sc_curbuf->b_un.b_addr;
768 1.1 ragge rfc_sc->sc_bytesleft =
769 1.1 ragge rfc_sc->sc_curbuf->b_bcount;
770 1.1 ragge } else {
771 1.1 ragge RFS_SETCMD(rf_sc->sc_state, RFS_IDLE);
772 1.1 ragge /*
773 1.1 ragge * Switch to the other drive if there where
774 1.1 ragge * buffers queued while we where working on
775 1.1 ragge * the buffer queue of this drive
776 1.1 ragge */
777 1.1 ragge other_drive = (struct rf_softc *)
778 1.1 ragge rfc_sc->sc_childs[
779 1.1 ragge rfc_sc->sc_curchild == 0 ? 1 : 0];
780 1.1 ragge if (other_drive != NULL && BUFQ_PEEK(
781 1.1 ragge &other_drive->sc_bufq) != NULL) {
782 1.1 ragge rfc_sc->sc_curchild =
783 1.1 ragge rfc_sc->sc_curchild == 0 ? 1 : 0;
784 1.1 ragge rf_sc = other_drive;
785 1.1 ragge rfc_sc->sc_curbuf =
786 1.1 ragge BUFQ_GET(&rf_sc->sc_bufq);
787 1.1 ragge rfc_sc->sc_bufidx =
788 1.1 ragge rfc_sc->sc_curbuf->b_un.b_addr;
789 1.1 ragge rfc_sc->sc_bytesleft =
790 1.1 ragge rfc_sc->sc_curbuf->b_bcount;
791 1.1 ragge } else
792 1.1 ragge return;
793 1.1 ragge }
794 1.1 ragge }
795 1.1 ragge RFS_SETCMD(rf_sc->sc_state,
796 1.1 ragge (rfc_sc->sc_curbuf->b_flags & B_READ) != 0
797 1.1 ragge ? RFS_RSEC : RFS_FBUF);
798 1.1 ragge break;
799 1.1 ragge case RFS_NOTINIT: /* Controller is idle and density is not detected. */
800 1.1 ragge case RFS_SMD: /* Set Media Density */
801 1.1 ragge case RFS_RSTAT: /* Read Status */
802 1.1 ragge case RFS_WDDS: /* Write Deleted Data Sector */
803 1.1 ragge case RFS_REC: /* Read Error Code */
804 1.1 ragge default:
805 1.1 ragge panic("Impossible state in rfc_intr(1).\n");
806 1.1 ragge }
807 1.1 ragge
808 1.1 ragge if ((rfc_sc->sc_curbuf->b_flags & B_ERROR) != 0) {
809 1.1 ragge rfc_sc->sc_curbuf->b_error = EIO;
810 1.1 ragge biodone(rfc_sc->sc_curbuf);
811 1.1 ragge rfc_sc->sc_curbuf = NULL;
812 1.1 ragge RFS_SETCMD(rf_sc->sc_state, RFS_NOTINIT);
813 1.1 ragge return;
814 1.1 ragge }
815 1.1 ragge
816 1.1 ragge /*
817 1.1 ragge * ... then initiate next command.
818 1.1 ragge */
819 1.1 ragge switch (rf_sc->sc_state & RFS_CMDS) {
820 1.1 ragge case RFS_NOTINIT: /* Controller is idle and density is not detected. */
821 1.1 ragge case RFS_PROBING: /* density detect / verify started */
822 1.1 ragge case RFS_IDLE: /* controller is idle */
823 1.1 ragge panic("Impossible state in rfc_intr(2).\n");
824 1.1 ragge break;
825 1.1 ragge case RFS_EBUF: /* Empty Buffer */
826 1.1 ragge i = bus_dmamap_load(rfc_sc->sc_dmat, rfc_sc->sc_dmam,
827 1.1 ragge rfc_sc->sc_bufidx, (rf_sc->sc_state & RFS_DENS) == 0
828 1.1 ragge ? RX2_BYTE_SD : RX2_BYTE_DD, rfc_sc->sc_curbuf->b_proc,
829 1.1 ragge BUS_DMA_NOWAIT);
830 1.1 ragge if (i != 0) {
831 1.2 wiz printf("rfc_intr: Error while loading bus DMA map: "
832 1.1 ragge "%d\n", i);
833 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
834 1.1 ragge break;
835 1.1 ragge }
836 1.1 ragge disk_busy(&rf_sc->sc_disk);
837 1.1 ragge if (rfc_sendcmd(rfc_sc, RX2CS_EBUF | RX2CS_IE
838 1.1 ragge | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD)
839 1.1 ragge | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
840 1.1 ragge | ((rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0x30000)>>4),
841 1.1 ragge ((rf_sc->sc_state & RFS_DENS) == 0
842 1.1 ragge ? RX2_BYTE_SD : RX2_BYTE_DD) / 2,
843 1.1 ragge rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0xffff) < 0) {
844 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
845 1.1 ragge bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
846 1.1 ragge }
847 1.1 ragge break;
848 1.1 ragge case RFS_FBUF: /* Fill Buffer */
849 1.1 ragge i = bus_dmamap_load(rfc_sc->sc_dmat, rfc_sc->sc_dmam,
850 1.1 ragge rfc_sc->sc_bufidx, (rf_sc->sc_state & RFS_DENS) == 0
851 1.1 ragge ? RX2_BYTE_SD : RX2_BYTE_DD,
852 1.1 ragge rfc_sc->sc_curbuf->b_proc, BUS_DMA_NOWAIT);
853 1.1 ragge if (i != 0) {
854 1.2 wiz printf("rfc_intr: Error while loading bus DMA map: "
855 1.1 ragge "%d\n", i);
856 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
857 1.1 ragge break;
858 1.1 ragge }
859 1.1 ragge disk_busy(&rf_sc->sc_disk);
860 1.1 ragge if (rfc_sendcmd(rfc_sc, RX2CS_FBUF | RX2CS_IE
861 1.1 ragge | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD)
862 1.1 ragge | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
863 1.1 ragge | ((rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0x30000)>>4),
864 1.1 ragge ((rf_sc->sc_state & RFS_DENS) == 0
865 1.1 ragge ? RX2_BYTE_SD : RX2_BYTE_DD) / 2,
866 1.1 ragge rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0xffff) < 0) {
867 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
868 1.1 ragge bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
869 1.1 ragge }
870 1.1 ragge break;
871 1.1 ragge case RFS_WSEC: /* Write Sector */
872 1.1 ragge i = (rfc_sc->sc_curbuf->b_bcount - rfc_sc->sc_bytesleft
873 1.1 ragge + rfc_sc->sc_curbuf->b_blkno * DEV_BSIZE) /
874 1.1 ragge ((rf_sc->sc_state & RFS_DENS) == 0
875 1.1 ragge ? RX2_BYTE_SD : RX2_BYTE_DD);
876 1.1 ragge if (i > RX2_TRACKS * RX2_SECTORS) {
877 1.1 ragge rfc_sc->sc_curbuf->b_resid = rfc_sc->sc_bytesleft;
878 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
879 1.1 ragge }
880 1.1 ragge disk_busy(&rf_sc->sc_disk);
881 1.1 ragge if (rfc_sendcmd(rfc_sc, RX2CS_WSEC | RX2CS_IE
882 1.1 ragge | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
883 1.1 ragge | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD),
884 1.1 ragge i % RX2_SECTORS + 1, i / RX2_SECTORS) < 0) {
885 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
886 1.1 ragge }
887 1.1 ragge break;
888 1.1 ragge case RFS_RSEC: /* Read Sector */
889 1.1 ragge i = (rfc_sc->sc_curbuf->b_bcount - rfc_sc->sc_bytesleft
890 1.1 ragge + rfc_sc->sc_curbuf->b_blkno * DEV_BSIZE) /
891 1.1 ragge ((rf_sc->sc_state & RFS_DENS) == 0
892 1.1 ragge ? RX2_BYTE_SD : RX2_BYTE_DD);
893 1.1 ragge if (i > RX2_TRACKS * RX2_SECTORS) {
894 1.1 ragge rfc_sc->sc_curbuf->b_resid = rfc_sc->sc_bytesleft;
895 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
896 1.1 ragge }
897 1.1 ragge disk_busy(&rf_sc->sc_disk);
898 1.1 ragge if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE
899 1.1 ragge | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
900 1.1 ragge | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD),
901 1.1 ragge i % RX2_SECTORS + 1, i / RX2_SECTORS) < 0) {
902 1.1 ragge rfc_sc->sc_curbuf->b_flags |= B_ERROR;
903 1.1 ragge }
904 1.1 ragge break;
905 1.1 ragge case RFS_SMD: /* Set Media Density */
906 1.1 ragge case RFS_RSTAT: /* Read Status */
907 1.1 ragge case RFS_WDDS: /* Write Deleted Data Sector */
908 1.1 ragge case RFS_REC: /* Read Error Code */
909 1.1 ragge default:
910 1.1 ragge panic("Impossible state in rfc_intr(3).\n");
911 1.1 ragge }
912 1.1 ragge
913 1.1 ragge if ((rfc_sc->sc_curbuf->b_flags & B_ERROR) != 0) {
914 1.1 ragge rfc_sc->sc_curbuf->b_error = EIO;
915 1.1 ragge biodone(rfc_sc->sc_curbuf);
916 1.1 ragge rfc_sc->sc_curbuf = NULL;
917 1.1 ragge RFS_SETCMD(rf_sc->sc_state, RFS_NOTINIT);
918 1.1 ragge }
919 1.1 ragge return;
920 1.1 ragge }
921 1.1 ragge
922 1.1 ragge
923 1.1 ragge
924 1.1 ragge int
925 1.1 ragge rfdump(dev_t dev, daddr_t blkno, caddr_t va, size_t size)
926 1.1 ragge {
927 1.1 ragge
928 1.1 ragge /* A 0.5MB floppy is much to small to take a system dump... */
929 1.1 ragge return(ENXIO);
930 1.1 ragge }
931 1.1 ragge
932 1.1 ragge
933 1.1 ragge
934 1.1 ragge int
935 1.1 ragge rfsize(dev_t dev)
936 1.1 ragge {
937 1.1 ragge
938 1.1 ragge return(-1);
939 1.1 ragge }
940 1.1 ragge
941 1.1 ragge
942 1.1 ragge
943 1.1 ragge int
944 1.1 ragge rfopen(dev_t dev, int oflags, int devtype, struct proc *p)
945 1.1 ragge {
946 1.1 ragge struct rf_softc *rf_sc;
947 1.1 ragge struct rfc_softc *rfc_sc;
948 1.1 ragge struct disklabel *dl;
949 1.1 ragge int unit;
950 1.1 ragge
951 1.1 ragge unit = DISKUNIT(dev);
952 1.1 ragge if (unit >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[unit]) == NULL) {
953 1.1 ragge return(ENXIO);
954 1.1 ragge }
955 1.1 ragge rfc_sc = (struct rfc_softc *)rf_sc->sc_dev.dv_parent;
956 1.1 ragge dl = rf_sc->sc_disk.dk_label;
957 1.1 ragge switch (DISKPART(dev)) {
958 1.1 ragge case 0: /* Part. a is single density. */
959 1.1 ragge rf_sc->sc_state &= ~RFS_DENS;
960 1.1 ragge rf_sc->sc_state &= ~RFS_AD;
961 1.1 ragge break;
962 1.1 ragge case 1: /* Part. b is double density. */
963 1.1 ragge /*
964 1.1 ragge * Opening a singe density only drive
965 1.1 ragge * in double density is sensless.
966 1.1 ragge */
967 1.1 ragge if (rfc_sc->type == 1) {
968 1.1 ragge return(ENXIO);
969 1.1 ragge }
970 1.1 ragge rf_sc->sc_state |= RFS_DENS;
971 1.1 ragge rf_sc->sc_state &= ~RFS_AD;
972 1.1 ragge break;
973 1.1 ragge case 2: /* Part. c is auto density. */
974 1.1 ragge rf_sc->sc_state |= RFS_AD;
975 1.1 ragge break;
976 1.1 ragge default:
977 1.1 ragge return(ENXIO);
978 1.1 ragge break;
979 1.1 ragge }
980 1.1 ragge if ((rf_sc->sc_state & RFS_CMDS) == RFS_NOTINIT) {
981 1.1 ragge rfc_sc->sc_curchild = rf_sc->sc_dnum;
982 1.1 ragge /*
983 1.1 ragge * Controller is idle and density is not detected.
984 1.1 ragge * Start a density probe by issuing a read sector command
985 1.1 ragge * and sleep until the density probe finished.
986 1.1 ragge * Due to this it is imposible to open unformated media.
987 1.1 ragge * As the RX02/02 is not able to format its own media,
988 1.1 ragge * media must be purchased preformated. fsck DEC makreting!
989 1.1 ragge */
990 1.1 ragge RFS_SETCMD(rf_sc->sc_state, RFS_PROBING);
991 1.1 ragge disk_busy(&rf_sc->sc_disk);
992 1.1 ragge if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE
993 1.1 ragge | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
994 1.1 ragge | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD),
995 1.1 ragge 1, 1) < 0) {
996 1.1 ragge rf_sc->sc_state = 0;
997 1.1 ragge return(ENXIO);
998 1.1 ragge }
999 1.1 ragge /* wait max. 2 sec for density probe to finish */
1000 1.1 ragge if (tsleep(rf_sc, PRIBIO | PCATCH, "density probe", 2 * hz)
1001 1.1 ragge != 0 || (rf_sc->sc_state & RFS_CMDS) == RFS_NOTINIT) {
1002 1.1 ragge /* timeout elapsed and / or somthing went wrong */
1003 1.1 ragge rf_sc->sc_state = 0;
1004 1.1 ragge return(ENXIO);
1005 1.1 ragge }
1006 1.1 ragge }
1007 1.1 ragge /* disklabel. We use different fake geometries for SD and DD. */
1008 1.1 ragge if ((rf_sc->sc_state & RFS_DENS) == 0) {
1009 1.1 ragge dl->d_nsectors = 10; /* sectors per track */
1010 1.1 ragge dl->d_secpercyl = 10; /* sectors per cylinder */
1011 1.1 ragge dl->d_ncylinders = 50; /* cylinders per unit */
1012 1.1 ragge dl->d_secperunit = 501; /* sectors per unit */
1013 1.1 ragge /* number of sectors in partition */
1014 1.1 ragge dl->d_partitions[2].p_size = 500;
1015 1.1 ragge } else {
1016 1.1 ragge dl->d_nsectors = RX2_SECTORS / 2; /* sectors per track */
1017 1.1 ragge dl->d_secpercyl = RX2_SECTORS / 2; /* sectors per cylinder */
1018 1.1 ragge dl->d_ncylinders = RX2_TRACKS; /* cylinders per unit */
1019 1.1 ragge /* sectors per unit */
1020 1.1 ragge dl->d_secperunit = RX2_SECTORS * RX2_TRACKS / 2;
1021 1.1 ragge /* number of sectors in partition */
1022 1.1 ragge dl->d_partitions[2].p_size = RX2_SECTORS * RX2_TRACKS / 2;
1023 1.1 ragge }
1024 1.1 ragge rf_sc->sc_open++;
1025 1.1 ragge return(0);
1026 1.1 ragge }
1027 1.1 ragge
1028 1.1 ragge
1029 1.1 ragge
1030 1.1 ragge int
1031 1.1 ragge rfclose(dev_t dev, int fflag, int devtype, struct proc *p)
1032 1.1 ragge {
1033 1.1 ragge struct rf_softc *rf_sc;
1034 1.1 ragge int unit;
1035 1.1 ragge
1036 1.1 ragge unit = DISKUNIT(dev);
1037 1.1 ragge if (unit >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[unit]) == NULL) {
1038 1.1 ragge return(ENXIO);
1039 1.1 ragge }
1040 1.1 ragge if (rf_sc->sc_open == 0) {
1041 1.1 ragge panic("rfclose: can not close non-open drive %s",
1042 1.1 ragge rf_sc->sc_dev.dv_xname);
1043 1.1 ragge } else {
1044 1.1 ragge if (--rf_sc->sc_open == 0) {
1045 1.1 ragge rf_sc->sc_state = 0;
1046 1.1 ragge }
1047 1.1 ragge }
1048 1.1 ragge return(0);
1049 1.1 ragge }
1050 1.1 ragge
1051 1.1 ragge
1052 1.1 ragge
1053 1.1 ragge int
1054 1.1 ragge rfread(dev_t dev, struct uio *uio, int ioflag)
1055 1.1 ragge {
1056 1.1 ragge
1057 1.1 ragge return(physio(rfstrategy, NULL, dev, B_READ, minphys, uio));
1058 1.1 ragge }
1059 1.1 ragge
1060 1.1 ragge
1061 1.1 ragge
1062 1.1 ragge int
1063 1.1 ragge rfwrite(dev_t dev, struct uio *uio, int ioflag)
1064 1.1 ragge {
1065 1.1 ragge
1066 1.1 ragge return(physio(rfstrategy, NULL, dev, B_WRITE, minphys, uio));
1067 1.1 ragge }
1068 1.1 ragge
1069 1.1 ragge
1070 1.1 ragge
1071 1.1 ragge int
1072 1.1 ragge rfioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
1073 1.1 ragge {
1074 1.1 ragge struct rf_softc *rf_sc;
1075 1.1 ragge int unit;
1076 1.1 ragge
1077 1.1 ragge unit = DISKUNIT(dev);
1078 1.1 ragge if (unit >= rf_cd.cd_ndevs || (rf_sc = rf_cd.cd_devs[unit]) == NULL) {
1079 1.1 ragge return(ENXIO);
1080 1.1 ragge }
1081 1.1 ragge /* We are going to operate on a non open dev? PANIC! */
1082 1.1 ragge if (rf_sc->sc_open == 0) {
1083 1.1 ragge panic("rfstrategy: can not operate on non-open drive %s (2)",
1084 1.1 ragge rf_sc->sc_dev.dv_xname);
1085 1.1 ragge }
1086 1.1 ragge switch (cmd) {
1087 1.1 ragge /* get and set disklabel; DIOCGPART used internally */
1088 1.1 ragge case DIOCGDINFO: /* get */
1089 1.1 ragge memcpy(data, rf_sc->sc_disk.dk_label,
1090 1.1 ragge sizeof(struct disklabel));
1091 1.1 ragge return(0);
1092 1.1 ragge case DIOCSDINFO: /* set */
1093 1.1 ragge return(0);
1094 1.1 ragge case DIOCWDINFO: /* set, update disk */
1095 1.1 ragge return(0);
1096 1.1 ragge case DIOCGPART: /* get partition */
1097 1.1 ragge ((struct partinfo *)data)->disklab = rf_sc->sc_disk.dk_label;
1098 1.1 ragge ((struct partinfo *)data)->part =
1099 1.1 ragge &rf_sc->sc_disk.dk_label->d_partitions[DISKPART(dev)];
1100 1.1 ragge return(0);
1101 1.1 ragge
1102 1.1 ragge /* do format operation, read or write */
1103 1.1 ragge case DIOCRFORMAT:
1104 1.1 ragge break;
1105 1.1 ragge case DIOCWFORMAT:
1106 1.1 ragge break;
1107 1.1 ragge
1108 1.1 ragge case DIOCSSTEP: /* set step rate */
1109 1.1 ragge break;
1110 1.1 ragge case DIOCSRETRIES: /* set # of retries */
1111 1.1 ragge break;
1112 1.1 ragge case DIOCKLABEL: /* keep/drop label on close? */
1113 1.1 ragge break;
1114 1.1 ragge case DIOCWLABEL: /* write en/disable label */
1115 1.1 ragge break;
1116 1.1 ragge
1117 1.1 ragge /* case DIOCSBAD: / * set kernel dkbad */
1118 1.1 ragge break; /* */
1119 1.1 ragge case DIOCEJECT: /* eject removable disk */
1120 1.1 ragge break;
1121 1.1 ragge case ODIOCEJECT: /* eject removable disk */
1122 1.1 ragge break;
1123 1.1 ragge case DIOCLOCK: /* lock/unlock pack */
1124 1.1 ragge break;
1125 1.1 ragge
1126 1.1 ragge /* get default label, clear label */
1127 1.1 ragge case DIOCGDEFLABEL:
1128 1.1 ragge break;
1129 1.1 ragge case DIOCCLRLABEL:
1130 1.1 ragge break;
1131 1.1 ragge default:
1132 1.1 ragge return(ENOTTY);
1133 1.1 ragge }
1134 1.1 ragge
1135 1.1 ragge return(ENOTTY);
1136 1.1 ragge }
1137 1.1 ragge
1138 1.1 ragge
1139