wdc.c revision 1.152 1 1.152 wiz /* $NetBSD: wdc.c,v 1.152 2003/11/02 11:07:46 wiz Exp $ */
2 1.31 bouyer
3 1.31 bouyer /*
4 1.137 bouyer * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. All rights reserved.
5 1.31 bouyer *
6 1.31 bouyer * Redistribution and use in source and binary forms, with or without
7 1.31 bouyer * modification, are permitted provided that the following conditions
8 1.31 bouyer * are met:
9 1.31 bouyer * 1. Redistributions of source code must retain the above copyright
10 1.31 bouyer * notice, this list of conditions and the following disclaimer.
11 1.31 bouyer * 2. Redistributions in binary form must reproduce the above copyright
12 1.31 bouyer * notice, this list of conditions and the following disclaimer in the
13 1.31 bouyer * documentation and/or other materials provided with the distribution.
14 1.31 bouyer * 3. All advertising materials mentioning features or use of this software
15 1.31 bouyer * must display the following acknowledgement:
16 1.31 bouyer * This product includes software developed by Manuel Bouyer.
17 1.31 bouyer * 4. The name of the author may not be used to endorse or promote products
18 1.31 bouyer * derived from this software without specific prior written permission.
19 1.31 bouyer *
20 1.31 bouyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 1.31 bouyer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 1.31 bouyer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 1.31 bouyer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 1.31 bouyer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 1.31 bouyer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 1.31 bouyer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 1.31 bouyer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 1.31 bouyer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 1.31 bouyer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 1.31 bouyer */
31 1.2 bouyer
32 1.27 mycroft /*-
33 1.125 mycroft * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
34 1.27 mycroft * All rights reserved.
35 1.2 bouyer *
36 1.27 mycroft * This code is derived from software contributed to The NetBSD Foundation
37 1.27 mycroft * by Charles M. Hannum, by Onno van der Linden and by Manuel Bouyer.
38 1.12 cgd *
39 1.2 bouyer * Redistribution and use in source and binary forms, with or without
40 1.2 bouyer * modification, are permitted provided that the following conditions
41 1.2 bouyer * are met:
42 1.2 bouyer * 1. Redistributions of source code must retain the above copyright
43 1.2 bouyer * notice, this list of conditions and the following disclaimer.
44 1.2 bouyer * 2. Redistributions in binary form must reproduce the above copyright
45 1.2 bouyer * notice, this list of conditions and the following disclaimer in the
46 1.2 bouyer * documentation and/or other materials provided with the distribution.
47 1.2 bouyer * 3. All advertising materials mentioning features or use of this software
48 1.2 bouyer * must display the following acknowledgement:
49 1.27 mycroft * This product includes software developed by the NetBSD
50 1.27 mycroft * Foundation, Inc. and its contributors.
51 1.27 mycroft * 4. Neither the name of The NetBSD Foundation nor the names of its
52 1.27 mycroft * contributors may be used to endorse or promote products derived
53 1.27 mycroft * from this software without specific prior written permission.
54 1.2 bouyer *
55 1.27 mycroft * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
56 1.27 mycroft * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
57 1.27 mycroft * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
58 1.27 mycroft * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
59 1.27 mycroft * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
60 1.27 mycroft * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
61 1.27 mycroft * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
62 1.27 mycroft * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
63 1.27 mycroft * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
64 1.27 mycroft * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
65 1.27 mycroft * POSSIBILITY OF SUCH DAMAGE.
66 1.2 bouyer */
67 1.2 bouyer
68 1.12 cgd /*
69 1.12 cgd * CODE UNTESTED IN THE CURRENT REVISION:
70 1.12 cgd */
71 1.100 lukem
72 1.100 lukem #include <sys/cdefs.h>
73 1.152 wiz __KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.152 2003/11/02 11:07:46 wiz Exp $");
74 1.12 cgd
75 1.59 hubertf #ifndef WDCDEBUG
76 1.31 bouyer #define WDCDEBUG
77 1.59 hubertf #endif /* WDCDEBUG */
78 1.31 bouyer
79 1.2 bouyer #include <sys/param.h>
80 1.2 bouyer #include <sys/systm.h>
81 1.2 bouyer #include <sys/kernel.h>
82 1.137 bouyer #include <sys/kthread.h>
83 1.2 bouyer #include <sys/conf.h>
84 1.2 bouyer #include <sys/buf.h>
85 1.31 bouyer #include <sys/device.h>
86 1.2 bouyer #include <sys/malloc.h>
87 1.71 bouyer #include <sys/pool.h>
88 1.2 bouyer #include <sys/syslog.h>
89 1.2 bouyer #include <sys/proc.h>
90 1.2 bouyer
91 1.2 bouyer #include <machine/intr.h>
92 1.2 bouyer #include <machine/bus.h>
93 1.2 bouyer
94 1.17 sakamoto #ifndef __BUS_SPACE_HAS_STREAM_METHODS
95 1.31 bouyer #define bus_space_write_multi_stream_2 bus_space_write_multi_2
96 1.31 bouyer #define bus_space_write_multi_stream_4 bus_space_write_multi_4
97 1.31 bouyer #define bus_space_read_multi_stream_2 bus_space_read_multi_2
98 1.31 bouyer #define bus_space_read_multi_stream_4 bus_space_read_multi_4
99 1.17 sakamoto #endif /* __BUS_SPACE_HAS_STREAM_METHODS */
100 1.16 sakamoto
101 1.103 bouyer #include <dev/ata/atavar.h>
102 1.102 bouyer #include <dev/ata/wdvar.h>
103 1.31 bouyer #include <dev/ata/atareg.h>
104 1.12 cgd #include <dev/ic/wdcreg.h>
105 1.12 cgd #include <dev/ic/wdcvar.h>
106 1.31 bouyer
107 1.137 bouyer #include "locators.h"
108 1.137 bouyer
109 1.122 thorpej #include "ataraid.h"
110 1.2 bouyer #include "atapibus.h"
111 1.106 bouyer #include "wd.h"
112 1.2 bouyer
113 1.122 thorpej #if NATARAID > 0
114 1.122 thorpej #include <dev/ata/ata_raidvar.h>
115 1.122 thorpej #endif
116 1.122 thorpej
117 1.31 bouyer #define WDCDELAY 100 /* 100 microseconds */
118 1.31 bouyer #define WDCNDELAY_RST (WDC_RESET_WAIT * 1000 / WDCDELAY)
119 1.2 bouyer #if 0
120 1.31 bouyer /* If you enable this, it will report any delays more than WDCDELAY * N long. */
121 1.2 bouyer #define WDCNDELAY_DEBUG 50
122 1.2 bouyer #endif
123 1.2 bouyer
124 1.137 bouyer /* When polling wait that much and then tsleep for 1/hz seconds */
125 1.137 bouyer #define WDCDELAY_POLL 1 /* ms */
126 1.137 bouyer
127 1.137 bouyer /* timeout for the control commands */
128 1.137 bouyer #define WDC_CTRL_DELAY 10000 /* 10s, for the recall command */
129 1.137 bouyer
130 1.71 bouyer struct pool wdc_xfer_pool;
131 1.2 bouyer
132 1.106 bouyer #if NWD > 0
133 1.103 bouyer extern const struct ata_bustype wdc_ata_bustype; /* in ata_wdc.c */
134 1.106 bouyer #else
135 1.106 bouyer /* A fake one, the autoconfig will print "wd at foo ... not configured */
136 1.106 bouyer const struct ata_bustype wdc_ata_bustype = {
137 1.106 bouyer SCSIPI_BUSTYPE_ATA,
138 1.106 bouyer NULL,
139 1.106 bouyer NULL,
140 1.106 bouyer NULL,
141 1.106 bouyer NULL,
142 1.106 bouyer NULL,
143 1.106 bouyer NULL,
144 1.106 bouyer NULL
145 1.106 bouyer };
146 1.106 bouyer #endif
147 1.102 bouyer
148 1.137 bouyer int atabusmatch __P((struct device *, struct cfdata *, void *));
149 1.137 bouyer void atabusattach __P((struct device *, struct device *, void *));
150 1.137 bouyer void atabus_create_thread __P((void *));
151 1.137 bouyer void atabus_thread __P((void *));
152 1.137 bouyer void atabusconfig __P((struct atabus_softc *));
153 1.137 bouyer int atabusactivate __P((struct device *, enum devact));
154 1.137 bouyer int atabusdetach __P((struct device *, int flags));
155 1.137 bouyer int atabusprint __P((void *, const char *));
156 1.137 bouyer
157 1.137 bouyer CFATTACH_DECL(atabus, sizeof(struct atabus_softc),
158 1.137 bouyer atabusmatch, atabusattach, atabusdetach, atabusactivate);
159 1.137 bouyer
160 1.137 bouyer struct atabus_initq {
161 1.137 bouyer struct atabus_softc *atabus_sc;
162 1.137 bouyer TAILQ_ENTRY(atabus_initq) atabus_initq;
163 1.137 bouyer };
164 1.137 bouyer static TAILQ_HEAD(, atabus_initq) atabus_initq_head =
165 1.137 bouyer TAILQ_HEAD_INITIALIZER(atabus_initq_head);
166 1.137 bouyer static struct simplelock atabus_interlock = SIMPLELOCK_INITIALIZER;
167 1.137 bouyer
168 1.137 bouyer int __wdcprobe __P((struct channel_softc*, int));
169 1.31 bouyer static void __wdcerror __P((struct channel_softc*, char *));
170 1.137 bouyer static int __wdcwait_reset __P((struct channel_softc *, int, int));
171 1.31 bouyer void __wdccommand_done __P((struct channel_softc *, struct wdc_xfer *));
172 1.31 bouyer void __wdccommand_start __P((struct channel_softc *, struct wdc_xfer *));
173 1.66 bouyer int __wdccommand_intr __P((struct channel_softc *, struct wdc_xfer *, int));
174 1.137 bouyer int __wdcwait __P((struct channel_softc *, int, int, int));
175 1.31 bouyer int wdprint __P((void *, const char *));
176 1.134 mycroft void wdc_finish_attach __P((struct device *));
177 1.125 mycroft void wdc_channel_attach __P((struct channel_softc *));
178 1.31 bouyer
179 1.31 bouyer #define DEBUG_INTR 0x01
180 1.31 bouyer #define DEBUG_XFERS 0x02
181 1.31 bouyer #define DEBUG_STATUS 0x04
182 1.31 bouyer #define DEBUG_FUNCS 0x08
183 1.31 bouyer #define DEBUG_PROBE 0x10
184 1.74 enami #define DEBUG_DETACH 0x20
185 1.87 bouyer #define DEBUG_DELAY 0x40
186 1.31 bouyer #ifdef WDCDEBUG
187 1.32 bouyer int wdcdebug_mask = 0;
188 1.31 bouyer int wdc_nxfer = 0;
189 1.31 bouyer #define WDCDEBUG_PRINT(args, level) if (wdcdebug_mask & (level)) printf args
190 1.2 bouyer #else
191 1.31 bouyer #define WDCDEBUG_PRINT(args, level)
192 1.2 bouyer #endif
193 1.2 bouyer
194 1.31 bouyer int
195 1.137 bouyer atabusprint(aux, pnp)
196 1.137 bouyer void *aux;
197 1.137 bouyer const char *pnp;
198 1.137 bouyer {
199 1.137 bouyer struct channel_softc *chan = aux;
200 1.137 bouyer if (pnp)
201 1.137 bouyer aprint_normal("atabus at %s", pnp);
202 1.137 bouyer aprint_normal(" channel %d", chan->channel);
203 1.137 bouyer return (UNCONF);
204 1.137 bouyer }
205 1.137 bouyer
206 1.137 bouyer int
207 1.137 bouyer atabusmatch(parent, cf, aux)
208 1.137 bouyer struct device *parent;
209 1.137 bouyer struct cfdata *cf;
210 1.137 bouyer void *aux;
211 1.137 bouyer {
212 1.137 bouyer struct channel_softc *chp = aux;
213 1.137 bouyer
214 1.137 bouyer if (chp == NULL)
215 1.137 bouyer return (0);
216 1.137 bouyer
217 1.138 bouyer if (cf->cf_loc[ATACF_CHANNEL] != chp->channel &&
218 1.138 bouyer cf->cf_loc[ATACF_CHANNEL] != ATACF_CHANNEL_DEFAULT)
219 1.137 bouyer return (0);
220 1.137 bouyer
221 1.137 bouyer return (1);
222 1.137 bouyer }
223 1.137 bouyer
224 1.137 bouyer void
225 1.137 bouyer atabusattach(parent, self, aux)
226 1.137 bouyer struct device *parent, *self;
227 1.137 bouyer void *aux;
228 1.137 bouyer {
229 1.137 bouyer struct atabus_softc *atabus_sc = (struct atabus_softc *)self;
230 1.137 bouyer struct channel_softc *chp = aux;
231 1.137 bouyer struct atabus_initq *atabus_initq;
232 1.137 bouyer
233 1.137 bouyer atabus_sc->sc_chan = chp;
234 1.137 bouyer
235 1.151 briggs aprint_normal("\n");
236 1.151 briggs aprint_naive("\n");
237 1.137 bouyer atabus_initq = malloc(sizeof(struct atabus_initq), M_DEVBUF, M_NOWAIT);
238 1.137 bouyer atabus_initq->atabus_sc = atabus_sc;
239 1.137 bouyer TAILQ_INSERT_TAIL(&atabus_initq_head, atabus_initq, atabus_initq);
240 1.137 bouyer config_pending_incr();
241 1.137 bouyer kthread_create(atabus_create_thread, atabus_sc);
242 1.137 bouyer
243 1.137 bouyer }
244 1.137 bouyer
245 1.137 bouyer void
246 1.137 bouyer atabus_create_thread(arg)
247 1.137 bouyer void *arg;
248 1.137 bouyer {
249 1.137 bouyer struct atabus_softc *atabus_sc = arg;
250 1.137 bouyer struct channel_softc *chp = atabus_sc->sc_chan;
251 1.137 bouyer int error;
252 1.137 bouyer
253 1.137 bouyer if ((error = kthread_create1(atabus_thread, atabus_sc, &chp->thread,
254 1.137 bouyer "%s", atabus_sc->sc_dev.dv_xname)) != 0)
255 1.137 bouyer printf("unable to create kernel thread for %s: error %d\n",
256 1.137 bouyer atabus_sc->sc_dev.dv_xname, error);
257 1.137 bouyer }
258 1.137 bouyer
259 1.137 bouyer void
260 1.137 bouyer atabus_thread(arg)
261 1.137 bouyer void *arg;
262 1.137 bouyer {
263 1.137 bouyer struct atabus_softc *atabus_sc = arg;
264 1.137 bouyer struct channel_softc *chp = atabus_sc->sc_chan;
265 1.137 bouyer struct wdc_xfer *xfer;
266 1.137 bouyer int s;
267 1.137 bouyer
268 1.137 bouyer s = splbio();
269 1.137 bouyer chp->ch_flags |= WDCF_TH_RUN;
270 1.137 bouyer splx(s);
271 1.137 bouyer atabusconfig(atabus_sc);
272 1.147 bouyer for(;;) {
273 1.137 bouyer s = splbio();
274 1.147 bouyer if ((chp->ch_flags & (WDCF_TH_RESET | WDCF_SHUTDOWN)) == 0 &&
275 1.147 bouyer ((chp->ch_flags & WDCF_ACTIVE) == 0 ||
276 1.148 bouyer chp->ch_queue->queue_freeze == 0)) {
277 1.147 bouyer chp->ch_flags &= ~WDCF_TH_RUN;
278 1.147 bouyer tsleep(&chp->thread, PRIBIO, "atath", 0);
279 1.147 bouyer chp->ch_flags |= WDCF_TH_RUN;
280 1.147 bouyer }
281 1.137 bouyer splx(s);
282 1.137 bouyer if (chp->ch_flags & WDCF_SHUTDOWN)
283 1.137 bouyer break;
284 1.137 bouyer s = splbio();
285 1.137 bouyer if (chp->ch_flags & WDCF_TH_RESET) {
286 1.137 bouyer int drive;
287 1.137 bouyer (void) wdcreset(chp, RESET_SLEEP);
288 1.137 bouyer for (drive = 0; drive < 2; drive++) {
289 1.137 bouyer chp->ch_drive[drive].state = 0;
290 1.137 bouyer }
291 1.137 bouyer chp->ch_flags &= ~WDCF_TH_RESET;
292 1.148 bouyer chp->ch_queue->queue_freeze--;
293 1.137 bouyer wdcstart(chp);
294 1.137 bouyer } else if ((chp->ch_flags & WDCF_ACTIVE) != 0 &&
295 1.148 bouyer chp->ch_queue->queue_freeze == 1) {
296 1.137 bouyer /*
297 1.148 bouyer * caller has bumped queue_freeze, decrease it
298 1.137 bouyer */
299 1.148 bouyer chp->ch_queue->queue_freeze--;
300 1.137 bouyer xfer = chp->ch_queue->sc_xfer.tqh_first;
301 1.137 bouyer #ifdef DIAGNOSTIC
302 1.137 bouyer if (xfer == NULL)
303 1.137 bouyer panic("channel active with no xfer ?");
304 1.137 bouyer #endif
305 1.137 bouyer xfer->c_start(chp, xfer);
306 1.148 bouyer } else if (chp->ch_queue->queue_freeze > 1) {
307 1.148 bouyer panic("queue_freeze");
308 1.137 bouyer }
309 1.137 bouyer splx(s);
310 1.137 bouyer }
311 1.137 bouyer chp->thread = NULL;
312 1.137 bouyer wakeup(&chp->ch_flags);
313 1.137 bouyer kthread_exit(0);
314 1.137 bouyer }
315 1.137 bouyer
316 1.137 bouyer void
317 1.137 bouyer atabusconfig(atabus_sc)
318 1.137 bouyer struct atabus_softc *atabus_sc;
319 1.137 bouyer {
320 1.137 bouyer struct channel_softc *chp = atabus_sc->sc_chan;
321 1.150 simonb int i, error, need_delref = 0;
322 1.137 bouyer struct ataparams params;
323 1.137 bouyer struct atabus_initq *atabus_initq = NULL;
324 1.145 christos u_int8_t st0 = 0, st1 = 0;
325 1.137 bouyer
326 1.137 bouyer if ((error = wdc_addref(chp)) != 0) {
327 1.137 bouyer aprint_error("%s: unable to enable controller\n",
328 1.137 bouyer chp->wdc->sc_dev.dv_xname);
329 1.144 briggs goto out;
330 1.137 bouyer }
331 1.144 briggs need_delref = 1;
332 1.137 bouyer
333 1.137 bouyer if (__wdcprobe(chp, 0) == 0)
334 1.137 bouyer /* If no drives, abort attach here. */
335 1.137 bouyer goto out;
336 1.137 bouyer
337 1.137 bouyer /* for ATA/OLD drives, wait for DRDY, 3s timeout */
338 1.137 bouyer for (i = 0; i < mstohz(3000); i++) {
339 1.137 bouyer if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
340 1.137 bouyer chp->wdc->select(chp,0);
341 1.137 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
342 1.137 bouyer WDSD_IBM);
343 1.137 bouyer delay(10); /* 400ns delay */
344 1.137 bouyer st0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
345 1.137 bouyer
346 1.137 bouyer if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
347 1.137 bouyer chp->wdc->select(chp,1);
348 1.137 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
349 1.137 bouyer WDSD_IBM | 0x10);
350 1.137 bouyer delay(10); /* 400ns delay */
351 1.137 bouyer st1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
352 1.137 bouyer
353 1.137 bouyer if (((chp->ch_drive[0].drive_flags & (DRIVE_ATA|DRIVE_OLD))
354 1.137 bouyer == 0 ||
355 1.137 bouyer (st0 & WDCS_DRDY)) &&
356 1.137 bouyer ((chp->ch_drive[1].drive_flags & (DRIVE_ATA|DRIVE_OLD))
357 1.137 bouyer == 0 ||
358 1.137 bouyer (st1 & WDCS_DRDY)))
359 1.137 bouyer break;
360 1.137 bouyer tsleep(&atabus_sc, PRIBIO, "atadrdy", 1);
361 1.137 bouyer }
362 1.137 bouyer if ((st0 & WDCS_DRDY) == 0)
363 1.137 bouyer chp->ch_drive[0].drive_flags &= ~(DRIVE_ATA|DRIVE_OLD);
364 1.137 bouyer if ((st1 & WDCS_DRDY) == 0)
365 1.137 bouyer chp->ch_drive[1].drive_flags &= ~(DRIVE_ATA|DRIVE_OLD);
366 1.137 bouyer
367 1.137 bouyer WDCDEBUG_PRINT(("%s:%d: wait DRDY st0 0x%x st1 0x%x\n",
368 1.137 bouyer chp->wdc->sc_dev.dv_xname,
369 1.137 bouyer chp->channel, st0, st1), DEBUG_PROBE);
370 1.137 bouyer
371 1.137 bouyer /* Wait a bit, some devices are weird just after a reset. */
372 1.137 bouyer delay(5000);
373 1.137 bouyer
374 1.137 bouyer for (i = 0; i < 2; i++) {
375 1.137 bouyer chp->ch_drive[i].chnl_softc = chp;
376 1.137 bouyer chp->ch_drive[i].drive = i;
377 1.137 bouyer /*
378 1.137 bouyer * Init error counter so that an error withing the first xfers
379 1.137 bouyer * will trigger a downgrade
380 1.137 bouyer */
381 1.137 bouyer chp->ch_drive[i].n_dmaerrs = NERRS_MAX-1;
382 1.137 bouyer
383 1.137 bouyer /* If controller can't do 16bit flag the drives as 32bit */
384 1.137 bouyer if ((chp->wdc->cap &
385 1.137 bouyer (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
386 1.137 bouyer WDC_CAPABILITY_DATA32)
387 1.137 bouyer chp->ch_drive[i].drive_flags |= DRIVE_CAP32;
388 1.137 bouyer if ((chp->ch_drive[i].drive_flags & DRIVE) == 0)
389 1.137 bouyer continue;
390 1.137 bouyer
391 1.144 briggs /* Shortcut in case we've been shutdown */
392 1.144 briggs if (chp->ch_flags & WDCF_SHUTDOWN)
393 1.144 briggs goto out;
394 1.144 briggs
395 1.137 bouyer /* issue an identify, to try to detect ghosts */
396 1.137 bouyer error = ata_get_params(&chp->ch_drive[i],
397 1.137 bouyer AT_WAIT | AT_POLL, ¶ms);
398 1.137 bouyer if (error != CMD_OK) {
399 1.137 bouyer tsleep(&atabus_sc, PRIBIO, "atacnf", mstohz(1000));
400 1.144 briggs
401 1.144 briggs /* Shortcut in case we've been shutdown */
402 1.144 briggs if (chp->ch_flags & WDCF_SHUTDOWN)
403 1.144 briggs goto out;
404 1.144 briggs
405 1.137 bouyer error = ata_get_params(&chp->ch_drive[i],
406 1.137 bouyer AT_WAIT | AT_POLL, ¶ms);
407 1.137 bouyer }
408 1.137 bouyer if (error == CMD_OK) {
409 1.152 wiz /* If IDENTIFY succeeded, this is not an OLD ctrl */
410 1.137 bouyer chp->ch_drive[0].drive_flags &= ~DRIVE_OLD;
411 1.137 bouyer chp->ch_drive[1].drive_flags &= ~DRIVE_OLD;
412 1.137 bouyer } else {
413 1.137 bouyer chp->ch_drive[i].drive_flags &=
414 1.137 bouyer ~(DRIVE_ATA | DRIVE_ATAPI);
415 1.137 bouyer WDCDEBUG_PRINT(("%s:%d:%d: IDENTIFY failed (%d)\n",
416 1.137 bouyer chp->wdc->sc_dev.dv_xname,
417 1.137 bouyer chp->channel, i, error), DEBUG_PROBE);
418 1.137 bouyer if ((chp->ch_drive[i].drive_flags & DRIVE_OLD) == 0)
419 1.137 bouyer continue;
420 1.137 bouyer /*
421 1.137 bouyer * Pre-ATA drive ?
422 1.137 bouyer * Test registers writability (Error register not
423 1.137 bouyer * writable, but cyllo is), then try an ATA command.
424 1.137 bouyer */
425 1.137 bouyer if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
426 1.137 bouyer chp->wdc->select(chp,i);
427 1.137 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
428 1.137 bouyer WDSD_IBM | (i << 4));
429 1.137 bouyer delay(10); /* 400ns delay */
430 1.137 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
431 1.137 bouyer wd_error, 0x58);
432 1.137 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
433 1.137 bouyer wd_cyl_lo, 0xa5);
434 1.137 bouyer if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
435 1.137 bouyer wd_error) == 0x58 ||
436 1.137 bouyer bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
437 1.137 bouyer wd_cyl_lo) != 0xa5) {
438 1.137 bouyer WDCDEBUG_PRINT(("%s:%d:%d: register "
439 1.137 bouyer "writability failed\n",
440 1.137 bouyer chp->wdc->sc_dev.dv_xname,
441 1.137 bouyer chp->channel, i), DEBUG_PROBE);
442 1.137 bouyer chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
443 1.137 bouyer }
444 1.137 bouyer if (wait_for_ready(chp, 10000, 0) == WDCWAIT_TOUT) {
445 1.137 bouyer WDCDEBUG_PRINT(("%s:%d:%d: not ready\n",
446 1.137 bouyer chp->wdc->sc_dev.dv_xname,
447 1.137 bouyer chp->channel, i), DEBUG_PROBE);
448 1.137 bouyer chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
449 1.137 bouyer continue;
450 1.137 bouyer }
451 1.137 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
452 1.137 bouyer wd_command, WDCC_RECAL);
453 1.137 bouyer delay(10); /* 400ns delay */
454 1.137 bouyer if (wait_for_ready(chp, 10000, 0) == WDCWAIT_TOUT) {
455 1.137 bouyer WDCDEBUG_PRINT(("%s:%d:%d: WDCC_RECAL failed\n",
456 1.137 bouyer chp->wdc->sc_dev.dv_xname,
457 1.137 bouyer chp->channel, i), DEBUG_PROBE);
458 1.137 bouyer chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
459 1.137 bouyer }
460 1.137 bouyer }
461 1.137 bouyer }
462 1.137 bouyer
463 1.137 bouyer WDCDEBUG_PRINT(("atabusattach: ch_drive_flags 0x%x 0x%x\n",
464 1.137 bouyer chp->ch_drive[0].drive_flags, chp->ch_drive[1].drive_flags),
465 1.137 bouyer DEBUG_PROBE);
466 1.137 bouyer
467 1.137 bouyer /* If no drives, abort here */
468 1.137 bouyer if ((chp->ch_drive[0].drive_flags & DRIVE) == 0 &&
469 1.137 bouyer (chp->ch_drive[1].drive_flags & DRIVE) == 0)
470 1.137 bouyer goto out;
471 1.137 bouyer
472 1.137 bouyer /* Make sure the devices probe in atabus order to avoid jitter. */
473 1.137 bouyer simple_lock(&atabus_interlock);
474 1.137 bouyer while(1) {
475 1.137 bouyer atabus_initq = TAILQ_FIRST(&atabus_initq_head);
476 1.137 bouyer if (atabus_initq->atabus_sc == atabus_sc)
477 1.137 bouyer break;
478 1.137 bouyer ltsleep(&atabus_initq_head, PRIBIO, "ata_initq", 0,
479 1.137 bouyer &atabus_interlock);
480 1.137 bouyer }
481 1.137 bouyer simple_unlock(&atabus_interlock);
482 1.137 bouyer
483 1.137 bouyer /*
484 1.137 bouyer * Attach an ATAPI bus, if needed.
485 1.137 bouyer */
486 1.137 bouyer if ((chp->ch_drive[0].drive_flags & DRIVE_ATAPI) ||
487 1.137 bouyer (chp->ch_drive[1].drive_flags & DRIVE_ATAPI)) {
488 1.137 bouyer #if NATAPIBUS > 0
489 1.137 bouyer wdc_atapibus_attach(atabus_sc);
490 1.137 bouyer #else
491 1.137 bouyer /*
492 1.137 bouyer * Fake the autoconfig "not configured" message
493 1.137 bouyer */
494 1.137 bouyer aprint_normal("atapibus at %s not configured\n",
495 1.137 bouyer chp->wdc->sc_dev.dv_xname);
496 1.137 bouyer chp->atapibus = NULL;
497 1.141 bouyer chp->ch_drive[0].drive_flags &= ~DRIVE_ATAPI;
498 1.141 bouyer chp->ch_drive[1].drive_flags &= ~DRIVE_ATAPI;
499 1.137 bouyer #endif
500 1.137 bouyer }
501 1.137 bouyer
502 1.137 bouyer for (i = 0; i < 2; i++) {
503 1.137 bouyer struct ata_device adev;
504 1.137 bouyer if ((chp->ch_drive[i].drive_flags &
505 1.137 bouyer (DRIVE_ATA | DRIVE_OLD)) == 0) {
506 1.137 bouyer continue;
507 1.137 bouyer }
508 1.137 bouyer memset(&adev, 0, sizeof(struct ata_device));
509 1.137 bouyer adev.adev_bustype = &wdc_ata_bustype;
510 1.137 bouyer adev.adev_channel = chp->channel;
511 1.137 bouyer adev.adev_openings = 1;
512 1.137 bouyer adev.adev_drv_data = &chp->ch_drive[i];
513 1.137 bouyer chp->ata_drives[i] = config_found(&atabus_sc->sc_dev,
514 1.137 bouyer &adev, wdprint);
515 1.141 bouyer if (chp->ata_drives[i] != NULL)
516 1.137 bouyer wdc_probe_caps(&chp->ch_drive[i]);
517 1.141 bouyer else
518 1.141 bouyer chp->ch_drive[i].drive_flags &=
519 1.141 bouyer ~(DRIVE_ATA | DRIVE_OLD);
520 1.137 bouyer }
521 1.137 bouyer
522 1.137 bouyer /* now that we know the drives, the controller can set its modes */
523 1.137 bouyer if (chp->wdc->cap & WDC_CAPABILITY_MODE) {
524 1.137 bouyer chp->wdc->set_modes(chp);
525 1.137 bouyer wdc_print_modes(chp);
526 1.137 bouyer }
527 1.137 bouyer #if NATARAID > 0
528 1.137 bouyer if (chp->wdc->cap & WDC_CAPABILITY_RAID)
529 1.137 bouyer for (i = 0; i < 2; i++)
530 1.137 bouyer if (chp->ata_drives[i] != NULL)
531 1.137 bouyer ata_raid_check_component(chp->ata_drives[i]);
532 1.137 bouyer #endif /* NATARAID > 0 */
533 1.137 bouyer
534 1.137 bouyer /*
535 1.152 wiz * reset drive_flags for unattached devices, reset state for attached
536 1.137 bouyer * ones
537 1.137 bouyer */
538 1.137 bouyer for (i = 0; i < 2; i++) {
539 1.137 bouyer if (chp->ch_drive[i].drv_softc == NULL)
540 1.137 bouyer chp->ch_drive[i].drive_flags = 0;
541 1.137 bouyer else
542 1.137 bouyer chp->ch_drive[i].state = 0;
543 1.137 bouyer }
544 1.137 bouyer
545 1.137 bouyer out:
546 1.137 bouyer if (atabus_initq == NULL) {
547 1.137 bouyer simple_lock(&atabus_interlock);
548 1.137 bouyer while(1) {
549 1.137 bouyer atabus_initq = TAILQ_FIRST(&atabus_initq_head);
550 1.137 bouyer if (atabus_initq->atabus_sc == atabus_sc)
551 1.137 bouyer break;
552 1.137 bouyer ltsleep(&atabus_initq_head, PRIBIO, "ata_initq", 0,
553 1.137 bouyer &atabus_interlock);
554 1.137 bouyer }
555 1.137 bouyer simple_unlock(&atabus_interlock);
556 1.137 bouyer }
557 1.137 bouyer simple_lock(&atabus_interlock);
558 1.137 bouyer TAILQ_REMOVE(&atabus_initq_head, atabus_initq, atabus_initq);
559 1.137 bouyer simple_unlock(&atabus_interlock);
560 1.137 bouyer
561 1.137 bouyer free(atabus_initq, M_DEVBUF);
562 1.137 bouyer wakeup(&atabus_initq_head);
563 1.137 bouyer
564 1.137 bouyer config_pending_decr();
565 1.144 briggs if (need_delref)
566 1.144 briggs wdc_delref(chp);
567 1.137 bouyer }
568 1.137 bouyer
569 1.137 bouyer
570 1.137 bouyer int
571 1.31 bouyer wdprint(aux, pnp)
572 1.31 bouyer void *aux;
573 1.31 bouyer const char *pnp;
574 1.31 bouyer {
575 1.102 bouyer struct ata_device *adev = aux;
576 1.31 bouyer if (pnp)
577 1.120 thorpej aprint_normal("wd at %s", pnp);
578 1.137 bouyer aprint_normal(" drive %d", adev->adev_drv_data->drive);
579 1.31 bouyer return (UNCONF);
580 1.31 bouyer }
581 1.31 bouyer
582 1.31 bouyer /* Test to see controller with at last one attached drive is there.
583 1.31 bouyer * Returns a bit for each possible drive found (0x01 for drive 0,
584 1.31 bouyer * 0x02 for drive 1).
585 1.31 bouyer * Logic:
586 1.31 bouyer * - If a status register is at 0xff, assume there is no drive here
587 1.97 bjh21 * (ISA has pull-up resistors). Similarly if the status register has
588 1.97 bjh21 * the value we last wrote to the bus (for IDE interfaces without pullups).
589 1.97 bjh21 * If no drive at all -> return.
590 1.31 bouyer * - reset the controller, wait for it to complete (may take up to 31s !).
591 1.31 bouyer * If timeout -> return.
592 1.31 bouyer * - test ATA/ATAPI signatures. If at last one drive found -> return.
593 1.31 bouyer * - try an ATA command on the master.
594 1.12 cgd */
595 1.31 bouyer
596 1.2 bouyer int
597 1.31 bouyer wdcprobe(chp)
598 1.31 bouyer struct channel_softc *chp;
599 1.12 cgd {
600 1.137 bouyer return __wdcprobe(chp, 1);
601 1.137 bouyer }
602 1.137 bouyer
603 1.137 bouyer int
604 1.137 bouyer __wdcprobe(chp, poll)
605 1.137 bouyer struct channel_softc *chp;
606 1.137 bouyer int poll;
607 1.137 bouyer {
608 1.31 bouyer u_int8_t st0, st1, sc, sn, cl, ch;
609 1.31 bouyer u_int8_t ret_value = 0x03;
610 1.31 bouyer u_int8_t drive;
611 1.31 bouyer
612 1.31 bouyer /*
613 1.31 bouyer * Sanity check to see if the wdc channel responds at all.
614 1.31 bouyer */
615 1.31 bouyer
616 1.43 kenh if (chp->wdc == NULL ||
617 1.43 kenh (chp->wdc->cap & WDC_CAPABILITY_NO_EXTRA_RESETS) == 0) {
618 1.107 dbj
619 1.107 dbj if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
620 1.107 dbj chp->wdc->select(chp,0);
621 1.137 bouyer
622 1.43 kenh bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
623 1.43 kenh WDSD_IBM);
624 1.131 mycroft delay(10); /* 400ns delay */
625 1.43 kenh st0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
626 1.107 dbj
627 1.107 dbj if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
628 1.107 dbj chp->wdc->select(chp,1);
629 1.137 bouyer
630 1.43 kenh bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
631 1.43 kenh WDSD_IBM | 0x10);
632 1.131 mycroft delay(10); /* 400ns delay */
633 1.43 kenh st1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
634 1.43 kenh
635 1.43 kenh WDCDEBUG_PRINT(("%s:%d: before reset, st0=0x%x, st1=0x%x\n",
636 1.43 kenh chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
637 1.43 kenh chp->channel, st0, st1), DEBUG_PROBE);
638 1.43 kenh
639 1.142 bouyer if (st0 == 0xff || st0 == WDSD_IBM)
640 1.43 kenh ret_value &= ~0x01;
641 1.142 bouyer if (st1 == 0xff || st1 == (WDSD_IBM | 0x10))
642 1.43 kenh ret_value &= ~0x02;
643 1.125 mycroft /* Register writability test, drive 0. */
644 1.125 mycroft if (ret_value & 0x01) {
645 1.125 mycroft if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
646 1.125 mycroft chp->wdc->select(chp,0);
647 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
648 1.125 mycroft WDSD_IBM);
649 1.137 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo, 0x02);
650 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
651 1.131 mycroft wd_cyl_lo) != 0x02)
652 1.125 mycroft ret_value &= ~0x01;
653 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo,
654 1.131 mycroft 0x01);
655 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
656 1.131 mycroft wd_cyl_lo) != 0x01)
657 1.125 mycroft ret_value &= ~0x01;
658 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sector,
659 1.125 mycroft 0x01);
660 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
661 1.125 mycroft wd_sector) != 0x01)
662 1.125 mycroft ret_value &= ~0x01;
663 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sector,
664 1.125 mycroft 0x02);
665 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
666 1.125 mycroft wd_sector) != 0x02)
667 1.125 mycroft ret_value &= ~0x01;
668 1.131 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
669 1.131 mycroft wd_cyl_lo) != 0x01)
670 1.131 mycroft ret_value &= ~0x01;
671 1.125 mycroft }
672 1.125 mycroft /* Register writability test, drive 1. */
673 1.125 mycroft if (ret_value & 0x02) {
674 1.125 mycroft if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
675 1.137 bouyer chp->wdc->select(chp,1);
676 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
677 1.137 bouyer WDSD_IBM | 0x10);
678 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo,
679 1.131 mycroft 0x02);
680 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
681 1.137 bouyer wd_cyl_lo) != 0x02)
682 1.125 mycroft ret_value &= ~0x02;
683 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo,
684 1.131 mycroft 0x01);
685 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
686 1.137 bouyer wd_cyl_lo) != 0x01)
687 1.125 mycroft ret_value &= ~0x02;
688 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sector,
689 1.125 mycroft 0x01);
690 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
691 1.125 mycroft wd_sector) != 0x01)
692 1.125 mycroft ret_value &= ~0x02;
693 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sector,
694 1.125 mycroft 0x02);
695 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
696 1.125 mycroft wd_sector) != 0x02)
697 1.125 mycroft ret_value &= ~0x02;
698 1.131 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
699 1.131 mycroft wd_cyl_lo) != 0x01)
700 1.131 mycroft ret_value &= ~0x02;
701 1.125 mycroft }
702 1.137 bouyer
703 1.137 bouyer if (ret_value == 0)
704 1.137 bouyer return 0;
705 1.62 bouyer }
706 1.31 bouyer
707 1.137 bouyer if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
708 1.137 bouyer chp->wdc->select(chp,0);
709 1.137 bouyer /* assert SRST, wait for reset to complete */
710 1.137 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
711 1.137 bouyer WDSD_IBM);
712 1.137 bouyer delay(10); /* 400ns delay */
713 1.137 bouyer bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
714 1.137 bouyer WDCTL_RST | WDCTL_IDS | WDCTL_4BIT);
715 1.137 bouyer DELAY(2000);
716 1.137 bouyer (void) bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_error);
717 1.137 bouyer bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
718 1.137 bouyer delay(10); /* 400ns delay */
719 1.137 bouyer
720 1.137 bouyer ret_value = __wdcwait_reset(chp, ret_value, poll);
721 1.137 bouyer WDCDEBUG_PRINT(("%s:%d: after reset, ret_value=0x%d\n",
722 1.137 bouyer chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", chp->channel,
723 1.137 bouyer ret_value), DEBUG_PROBE);
724 1.12 cgd
725 1.137 bouyer /* if reset failed, there's nothing here */
726 1.137 bouyer if (ret_value == 0)
727 1.137 bouyer return 0;
728 1.67 bouyer
729 1.12 cgd /*
730 1.137 bouyer * Test presence of drives. First test register signatures looking for
731 1.137 bouyer * ATAPI devices. If it's not an ATAPI and reset said there may be
732 1.137 bouyer * something here assume it's ATA or OLD. Ghost will be killed later in
733 1.137 bouyer * attach routine.
734 1.12 cgd */
735 1.137 bouyer for (drive = 0; drive < 2; drive++) {
736 1.137 bouyer if ((ret_value & (0x01 << drive)) == 0)
737 1.137 bouyer continue;
738 1.137 bouyer if (chp->wdc && chp->wdc->cap & WDC_CAPABILITY_SELECT)
739 1.137 bouyer chp->wdc->select(chp,drive);
740 1.137 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
741 1.137 bouyer WDSD_IBM | (drive << 4));
742 1.137 bouyer delay(10); /* 400ns delay */
743 1.137 bouyer /* Save registers contents */
744 1.137 bouyer sc = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt);
745 1.137 bouyer sn = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_sector);
746 1.137 bouyer cl = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo);
747 1.137 bouyer ch = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_hi);
748 1.137 bouyer
749 1.137 bouyer WDCDEBUG_PRINT(("%s:%d:%d: after reset, sc=0x%x sn=0x%x "
750 1.137 bouyer "cl=0x%x ch=0x%x\n",
751 1.137 bouyer chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
752 1.137 bouyer chp->channel, drive, sc, sn, cl, ch), DEBUG_PROBE);
753 1.31 bouyer /*
754 1.137 bouyer * sc & sn are supposted to be 0x1 for ATAPI but in some cases
755 1.137 bouyer * we get wrong values here, so ignore it.
756 1.31 bouyer */
757 1.137 bouyer if (cl == 0x14 && ch == 0xeb) {
758 1.137 bouyer chp->ch_drive[drive].drive_flags |= DRIVE_ATAPI;
759 1.137 bouyer } else {
760 1.137 bouyer chp->ch_drive[drive].drive_flags |= DRIVE_ATA;
761 1.137 bouyer if (chp->wdc == NULL ||
762 1.137 bouyer (chp->wdc->cap & WDC_CAPABILITY_PREATA) != 0)
763 1.137 bouyer chp->ch_drive[drive].drive_flags |= DRIVE_OLD;
764 1.137 bouyer }
765 1.31 bouyer }
766 1.137 bouyer return (ret_value);
767 1.137 bouyer }
768 1.31 bouyer
769 1.137 bouyer void
770 1.137 bouyer wdcattach(chp)
771 1.137 bouyer struct channel_softc *chp;
772 1.137 bouyer {
773 1.137 bouyer static int inited = 0;
774 1.32 bouyer
775 1.137 bouyer if (chp->ch_flags & WDCF_DISABLED)
776 1.137 bouyer return;
777 1.74 enami
778 1.137 bouyer /* initialise global data */
779 1.137 bouyer callout_init(&chp->ch_callout);
780 1.137 bouyer if (inited == 0) {
781 1.137 bouyer /* Initialize the wdc_xfer pool. */
782 1.137 bouyer pool_init(&wdc_xfer_pool, sizeof(struct wdc_xfer), 0,
783 1.137 bouyer 0, 0, "wdcspl", NULL);
784 1.137 bouyer inited++;
785 1.133 bouyer }
786 1.137 bouyer TAILQ_INIT(&chp->ch_queue->sc_xfer);
787 1.148 bouyer chp->ch_queue->queue_freeze = 0;
788 1.126 enami
789 1.143 bouyer chp->atabus = config_found(&chp->wdc->sc_dev, chp, atabusprint);
790 1.74 enami }
791 1.74 enami
792 1.74 enami /*
793 1.74 enami * Call activate routine of underlying devices.
794 1.74 enami */
795 1.74 enami int
796 1.137 bouyer atabusactivate(self, act)
797 1.74 enami struct device *self;
798 1.74 enami enum devact act;
799 1.74 enami {
800 1.137 bouyer struct atabus_softc *atabus_sc = (struct atabus_softc *)self;
801 1.137 bouyer struct channel_softc *chp = atabus_sc->sc_chan;
802 1.88 mrg struct device *sc = 0;
803 1.137 bouyer int s, i, error = 0;
804 1.74 enami
805 1.74 enami s = splbio();
806 1.74 enami switch (act) {
807 1.74 enami case DVACT_ACTIVATE:
808 1.74 enami error = EOPNOTSUPP;
809 1.74 enami break;
810 1.74 enami
811 1.74 enami case DVACT_DEACTIVATE:
812 1.137 bouyer /*
813 1.137 bouyer * We might call deactivate routine for
814 1.137 bouyer * the children of atapibus twice (once via
815 1.137 bouyer * atapibus, once directly), but since
816 1.137 bouyer * config_deactivate maintains DVF_ACTIVE flag,
817 1.137 bouyer * it's safe.
818 1.137 bouyer */
819 1.137 bouyer sc = chp->atapibus;
820 1.137 bouyer if (sc != NULL) {
821 1.137 bouyer error = config_deactivate(sc);
822 1.137 bouyer if (error != 0)
823 1.137 bouyer goto out;
824 1.137 bouyer }
825 1.74 enami
826 1.137 bouyer for (i = 0; i < 2; i++) {
827 1.137 bouyer sc = chp->ch_drive[i].drv_softc;
828 1.137 bouyer WDCDEBUG_PRINT(("atabusactivate: %s:"
829 1.137 bouyer " deactivating %s\n", atabus_sc->sc_dev.dv_xname,
830 1.137 bouyer sc == NULL ? "nodrv" : sc->dv_xname),
831 1.137 bouyer DEBUG_DETACH);
832 1.74 enami if (sc != NULL) {
833 1.74 enami error = config_deactivate(sc);
834 1.74 enami if (error != 0)
835 1.74 enami goto out;
836 1.74 enami }
837 1.74 enami }
838 1.74 enami break;
839 1.74 enami }
840 1.74 enami
841 1.74 enami out:
842 1.74 enami splx(s);
843 1.74 enami
844 1.74 enami #ifdef WDCDEBUG
845 1.88 mrg if (sc && error != 0)
846 1.137 bouyer WDCDEBUG_PRINT(("atabusactivate: %s: "
847 1.137 bouyer "error %d deactivating %s\n", atabus_sc->sc_dev.dv_xname,
848 1.137 bouyer error, sc->dv_xname), DEBUG_DETACH);
849 1.74 enami #endif
850 1.74 enami return (error);
851 1.74 enami }
852 1.74 enami
853 1.137 bouyer int wdcactivate(self, act)
854 1.137 bouyer struct device *self;
855 1.137 bouyer enum devact act;
856 1.137 bouyer {
857 1.137 bouyer struct wdc_softc *wdc = (struct wdc_softc *)self;
858 1.137 bouyer int s, i, error = 0;
859 1.137 bouyer
860 1.137 bouyer s = splbio();
861 1.137 bouyer switch (act) {
862 1.137 bouyer case DVACT_ACTIVATE:
863 1.137 bouyer error = EOPNOTSUPP;
864 1.137 bouyer break;
865 1.137 bouyer
866 1.137 bouyer case DVACT_DEACTIVATE:
867 1.137 bouyer for (i = 0; i < wdc->nchannels; i++) {
868 1.137 bouyer error = config_deactivate(wdc->channels[i]->atabus);
869 1.137 bouyer if (error)
870 1.137 bouyer break;
871 1.137 bouyer }
872 1.137 bouyer break;
873 1.137 bouyer }
874 1.137 bouyer splx(s);
875 1.137 bouyer return (error);
876 1.137 bouyer }
877 1.137 bouyer
878 1.137 bouyer
879 1.74 enami int
880 1.137 bouyer atabusdetach(self, flags)
881 1.74 enami struct device *self;
882 1.74 enami int flags;
883 1.74 enami {
884 1.137 bouyer struct atabus_softc *atabus_sc = (struct atabus_softc *)self;
885 1.137 bouyer struct channel_softc *chp = atabus_sc->sc_chan;
886 1.88 mrg struct device *sc = 0;
887 1.137 bouyer int i, error = 0;
888 1.137 bouyer
889 1.137 bouyer /* shutdown channel */
890 1.137 bouyer chp->ch_flags |= WDCF_SHUTDOWN;
891 1.143 bouyer wakeup(&chp->thread);
892 1.137 bouyer while (chp->thread != NULL)
893 1.137 bouyer tsleep(&chp->ch_flags, PRIBIO, "atadown", 0);
894 1.74 enami
895 1.137 bouyer /*
896 1.137 bouyer * Detach atapibus and its children.
897 1.137 bouyer */
898 1.137 bouyer sc = chp->atapibus;
899 1.137 bouyer if (sc != NULL) {
900 1.137 bouyer WDCDEBUG_PRINT(("atabusdetach: %s: detaching %s\n",
901 1.137 bouyer atabus_sc->sc_dev.dv_xname, sc->dv_xname), DEBUG_DETACH);
902 1.137 bouyer error = config_detach(sc, flags);
903 1.137 bouyer if (error != 0)
904 1.137 bouyer goto out;
905 1.137 bouyer }
906 1.74 enami
907 1.137 bouyer /*
908 1.137 bouyer * Detach our other children.
909 1.137 bouyer */
910 1.137 bouyer for (i = 0; i < 2; i++) {
911 1.137 bouyer if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI)
912 1.137 bouyer continue;
913 1.137 bouyer sc = chp->ch_drive[i].drv_softc;
914 1.137 bouyer WDCDEBUG_PRINT(("atabusdetach: %s: detaching %s\n",
915 1.137 bouyer atabus_sc->sc_dev.dv_xname,
916 1.137 bouyer sc == NULL ? "nodrv" : sc->dv_xname),
917 1.137 bouyer DEBUG_DETACH);
918 1.74 enami if (sc != NULL) {
919 1.74 enami error = config_detach(sc, flags);
920 1.74 enami if (error != 0)
921 1.74 enami goto out;
922 1.74 enami }
923 1.137 bouyer }
924 1.74 enami
925 1.137 bouyer wdc_kill_pending(chp);
926 1.74 enami
927 1.74 enami out:
928 1.74 enami #ifdef WDCDEBUG
929 1.88 mrg if (sc && error != 0)
930 1.137 bouyer WDCDEBUG_PRINT(("atabusdetach: %s: error %d detaching %s\n",
931 1.137 bouyer atabus_sc->sc_dev.dv_xname, error, sc->dv_xname),
932 1.137 bouyer DEBUG_DETACH);
933 1.74 enami #endif
934 1.74 enami return (error);
935 1.31 bouyer }
936 1.31 bouyer
937 1.137 bouyer int
938 1.137 bouyer wdcdetach(self, flags)
939 1.137 bouyer struct device *self;
940 1.137 bouyer int flags;
941 1.137 bouyer {
942 1.137 bouyer struct wdc_softc *wdc = (struct wdc_softc *)self;
943 1.137 bouyer struct channel_softc *chp;
944 1.137 bouyer int i, error = 0;
945 1.137 bouyer
946 1.137 bouyer for (i = 0; i < wdc->nchannels; i++) {
947 1.137 bouyer chp = wdc->channels[i];
948 1.137 bouyer WDCDEBUG_PRINT(("wdcdetach: %s: detaching %s\n",
949 1.137 bouyer wdc->sc_dev.dv_xname, chp->atabus->dv_xname), DEBUG_DETACH);
950 1.137 bouyer error = config_detach(chp->atabus, flags);
951 1.137 bouyer if (error)
952 1.137 bouyer break;
953 1.137 bouyer }
954 1.137 bouyer return (error);
955 1.137 bouyer }
956 1.137 bouyer
957 1.31 bouyer /*
958 1.31 bouyer * Start I/O on a controller, for the given channel.
959 1.31 bouyer * The first xfer may be not for our channel if the channel queues
960 1.31 bouyer * are shared.
961 1.31 bouyer */
962 1.31 bouyer void
963 1.45 drochner wdcstart(chp)
964 1.45 drochner struct channel_softc *chp;
965 1.31 bouyer {
966 1.31 bouyer struct wdc_xfer *xfer;
967 1.38 bouyer
968 1.38 bouyer #ifdef WDC_DIAGNOSTIC
969 1.38 bouyer int spl1, spl2;
970 1.38 bouyer
971 1.38 bouyer spl1 = splbio();
972 1.38 bouyer spl2 = splbio();
973 1.38 bouyer if (spl2 != spl1) {
974 1.38 bouyer printf("wdcstart: not at splbio()\n");
975 1.38 bouyer panic("wdcstart");
976 1.38 bouyer }
977 1.38 bouyer splx(spl2);
978 1.38 bouyer splx(spl1);
979 1.38 bouyer #endif /* WDC_DIAGNOSTIC */
980 1.12 cgd
981 1.31 bouyer /* is there a xfer ? */
982 1.45 drochner if ((xfer = chp->ch_queue->sc_xfer.tqh_first) == NULL)
983 1.31 bouyer return;
984 1.47 bouyer
985 1.47 bouyer /* adjust chp, in case we have a shared queue */
986 1.49 bouyer chp = xfer->chp;
987 1.47 bouyer
988 1.31 bouyer if ((chp->ch_flags & WDCF_ACTIVE) != 0 ) {
989 1.31 bouyer return; /* channel aleady active */
990 1.31 bouyer }
991 1.148 bouyer if (__predict_false(chp->ch_queue->queue_freeze > 0)) {
992 1.147 bouyer return; /* queue froozen */
993 1.137 bouyer }
994 1.31 bouyer #ifdef DIAGNOSTIC
995 1.31 bouyer if ((chp->ch_flags & WDCF_IRQ_WAIT) != 0)
996 1.118 provos panic("wdcstart: channel waiting for irq");
997 1.31 bouyer #endif
998 1.45 drochner if (chp->wdc->cap & WDC_CAPABILITY_HWLOCK)
999 1.45 drochner if (!(*chp->wdc->claim_hw)(chp, 0))
1000 1.31 bouyer return;
1001 1.12 cgd
1002 1.31 bouyer WDCDEBUG_PRINT(("wdcstart: xfer %p channel %d drive %d\n", xfer,
1003 1.49 bouyer chp->channel, xfer->drive), DEBUG_XFERS);
1004 1.31 bouyer chp->ch_flags |= WDCF_ACTIVE;
1005 1.37 bouyer if (chp->ch_drive[xfer->drive].drive_flags & DRIVE_RESET) {
1006 1.37 bouyer chp->ch_drive[xfer->drive].drive_flags &= ~DRIVE_RESET;
1007 1.37 bouyer chp->ch_drive[xfer->drive].state = 0;
1008 1.37 bouyer }
1009 1.98 bjh21 if (chp->wdc->cap & WDC_CAPABILITY_NOIRQ)
1010 1.98 bjh21 KASSERT(xfer->c_flags & C_POLL);
1011 1.31 bouyer xfer->c_start(chp, xfer);
1012 1.31 bouyer }
1013 1.2 bouyer
1014 1.31 bouyer /* restart an interrupted I/O */
1015 1.31 bouyer void
1016 1.31 bouyer wdcrestart(v)
1017 1.31 bouyer void *v;
1018 1.31 bouyer {
1019 1.31 bouyer struct channel_softc *chp = v;
1020 1.31 bouyer int s;
1021 1.2 bouyer
1022 1.31 bouyer s = splbio();
1023 1.45 drochner wdcstart(chp);
1024 1.31 bouyer splx(s);
1025 1.2 bouyer }
1026 1.31 bouyer
1027 1.2 bouyer
1028 1.31 bouyer /*
1029 1.31 bouyer * Interrupt routine for the controller. Acknowledge the interrupt, check for
1030 1.31 bouyer * errors on the current operation, mark it done if necessary, and start the
1031 1.31 bouyer * next request. Also check for a partially done transfer, and continue with
1032 1.31 bouyer * the next chunk if so.
1033 1.31 bouyer */
1034 1.12 cgd int
1035 1.31 bouyer wdcintr(arg)
1036 1.31 bouyer void *arg;
1037 1.12 cgd {
1038 1.31 bouyer struct channel_softc *chp = arg;
1039 1.31 bouyer struct wdc_xfer *xfer;
1040 1.76 bouyer int ret;
1041 1.12 cgd
1042 1.80 enami if ((chp->wdc->sc_dev.dv_flags & DVF_ACTIVE) == 0) {
1043 1.80 enami WDCDEBUG_PRINT(("wdcintr: deactivated controller\n"),
1044 1.80 enami DEBUG_INTR);
1045 1.80 enami return (0);
1046 1.80 enami }
1047 1.31 bouyer if ((chp->ch_flags & WDCF_IRQ_WAIT) == 0) {
1048 1.31 bouyer WDCDEBUG_PRINT(("wdcintr: inactive controller\n"), DEBUG_INTR);
1049 1.113 bouyer /* try to clear the pending interrupt anyway */
1050 1.113 bouyer (void)bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
1051 1.80 enami return (0);
1052 1.31 bouyer }
1053 1.12 cgd
1054 1.31 bouyer WDCDEBUG_PRINT(("wdcintr\n"), DEBUG_INTR);
1055 1.84 bouyer xfer = chp->ch_queue->sc_xfer.tqh_first;
1056 1.84 bouyer if (chp->ch_flags & WDCF_DMA_WAIT) {
1057 1.84 bouyer chp->wdc->dma_status =
1058 1.84 bouyer (*chp->wdc->dma_finish)(chp->wdc->dma_arg, chp->channel,
1059 1.84 bouyer xfer->drive, 0);
1060 1.84 bouyer if (chp->wdc->dma_status & WDC_DMAST_NOIRQ) {
1061 1.84 bouyer /* IRQ not for us, not detected by DMA engine */
1062 1.84 bouyer return 0;
1063 1.84 bouyer }
1064 1.84 bouyer chp->ch_flags &= ~WDCF_DMA_WAIT;
1065 1.84 bouyer }
1066 1.31 bouyer chp->ch_flags &= ~WDCF_IRQ_WAIT;
1067 1.76 bouyer ret = xfer->c_intr(chp, xfer, 1);
1068 1.76 bouyer if (ret == 0) /* irq was not for us, still waiting for irq */
1069 1.76 bouyer chp->ch_flags |= WDCF_IRQ_WAIT;
1070 1.76 bouyer return (ret);
1071 1.12 cgd }
1072 1.12 cgd
1073 1.31 bouyer /* Put all disk in RESET state */
1074 1.125 mycroft void
1075 1.137 bouyer wdc_reset_channel(drvp, flags)
1076 1.31 bouyer struct ata_drive_datas *drvp;
1077 1.137 bouyer int flags;
1078 1.2 bouyer {
1079 1.31 bouyer struct channel_softc *chp = drvp->chnl_softc;
1080 1.2 bouyer int drive;
1081 1.34 bouyer WDCDEBUG_PRINT(("ata_reset_channel %s:%d for drive %d\n",
1082 1.34 bouyer chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive),
1083 1.34 bouyer DEBUG_FUNCS);
1084 1.147 bouyer if ((flags & AT_POLL) == 0) {
1085 1.137 bouyer chp->ch_flags |= WDCF_TH_RESET;
1086 1.148 bouyer chp->ch_queue->queue_freeze++;
1087 1.137 bouyer wakeup(&chp->thread);
1088 1.137 bouyer return;
1089 1.137 bouyer }
1090 1.147 bouyer (void) wdcreset(chp, RESET_POLL);
1091 1.31 bouyer for (drive = 0; drive < 2; drive++) {
1092 1.31 bouyer chp->ch_drive[drive].state = 0;
1093 1.12 cgd }
1094 1.31 bouyer }
1095 1.12 cgd
1096 1.31 bouyer int
1097 1.137 bouyer wdcreset(chp, poll)
1098 1.31 bouyer struct channel_softc *chp;
1099 1.137 bouyer int poll;
1100 1.31 bouyer {
1101 1.31 bouyer int drv_mask1, drv_mask2;
1102 1.2 bouyer
1103 1.107 dbj if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
1104 1.107 dbj chp->wdc->select(chp,0);
1105 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
1106 1.31 bouyer WDSD_IBM); /* master */
1107 1.131 mycroft delay(10); /* 400ns delay */
1108 1.31 bouyer bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
1109 1.131 mycroft WDCTL_RST | WDCTL_IDS | WDCTL_4BIT);
1110 1.131 mycroft delay(2000);
1111 1.31 bouyer (void) bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_error);
1112 1.137 bouyer bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
1113 1.137 bouyer WDCTL_4BIT | WDCTL_IDS);
1114 1.131 mycroft delay(10); /* 400ns delay */
1115 1.2 bouyer
1116 1.31 bouyer drv_mask1 = (chp->ch_drive[0].drive_flags & DRIVE) ? 0x01:0x00;
1117 1.31 bouyer drv_mask1 |= (chp->ch_drive[1].drive_flags & DRIVE) ? 0x02:0x00;
1118 1.137 bouyer drv_mask2 = __wdcwait_reset(chp, drv_mask1,
1119 1.137 bouyer (poll == RESET_SLEEP) ? 0 : 1);
1120 1.137 bouyer if (drv_mask2 != drv_mask1) {
1121 1.31 bouyer printf("%s channel %d: reset failed for",
1122 1.31 bouyer chp->wdc->sc_dev.dv_xname, chp->channel);
1123 1.31 bouyer if ((drv_mask1 & 0x01) != 0 && (drv_mask2 & 0x01) == 0)
1124 1.31 bouyer printf(" drive 0");
1125 1.31 bouyer if ((drv_mask1 & 0x02) != 0 && (drv_mask2 & 0x02) == 0)
1126 1.31 bouyer printf(" drive 1");
1127 1.31 bouyer printf("\n");
1128 1.31 bouyer }
1129 1.137 bouyer bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
1130 1.31 bouyer return (drv_mask1 != drv_mask2) ? 1 : 0;
1131 1.31 bouyer }
1132 1.31 bouyer
1133 1.31 bouyer static int
1134 1.137 bouyer __wdcwait_reset(chp, drv_mask, poll)
1135 1.31 bouyer struct channel_softc *chp;
1136 1.31 bouyer int drv_mask;
1137 1.31 bouyer {
1138 1.137 bouyer int timeout, nloop;
1139 1.149 bouyer u_int8_t st0 = 0, st1 = 0;
1140 1.70 bouyer #ifdef WDCDEBUG
1141 1.146 christos u_int8_t sc0 = 0, sn0 = 0, cl0 = 0, ch0 = 0;
1142 1.146 christos u_int8_t sc1 = 0, sn1 = 0, cl1 = 0, ch1 = 0;
1143 1.70 bouyer #endif
1144 1.137 bouyer
1145 1.137 bouyer if (poll)
1146 1.137 bouyer nloop = WDCNDELAY_RST;
1147 1.137 bouyer else
1148 1.137 bouyer nloop = WDC_RESET_WAIT * hz / 1000;
1149 1.31 bouyer /* wait for BSY to deassert */
1150 1.137 bouyer for (timeout = 0; timeout < nloop; timeout++) {
1151 1.109 bouyer if (chp->wdc && chp->wdc->cap & WDC_CAPABILITY_SELECT)
1152 1.107 dbj chp->wdc->select(chp,0);
1153 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
1154 1.31 bouyer WDSD_IBM); /* master */
1155 1.65 bouyer delay(10);
1156 1.31 bouyer st0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
1157 1.70 bouyer #ifdef WDCDEBUG
1158 1.70 bouyer sc0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt);
1159 1.70 bouyer sn0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_sector);
1160 1.70 bouyer cl0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo);
1161 1.70 bouyer ch0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_hi);
1162 1.70 bouyer #endif
1163 1.109 bouyer if (chp->wdc && chp->wdc->cap & WDC_CAPABILITY_SELECT)
1164 1.107 dbj chp->wdc->select(chp,1);
1165 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
1166 1.31 bouyer WDSD_IBM | 0x10); /* slave */
1167 1.65 bouyer delay(10);
1168 1.31 bouyer st1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
1169 1.70 bouyer #ifdef WDCDEBUG
1170 1.70 bouyer sc1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt);
1171 1.70 bouyer sn1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_sector);
1172 1.70 bouyer cl1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo);
1173 1.70 bouyer ch1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_hi);
1174 1.70 bouyer #endif
1175 1.31 bouyer
1176 1.31 bouyer if ((drv_mask & 0x01) == 0) {
1177 1.31 bouyer /* no master */
1178 1.31 bouyer if ((drv_mask & 0x02) != 0 && (st1 & WDCS_BSY) == 0) {
1179 1.31 bouyer /* No master, slave is ready, it's done */
1180 1.65 bouyer goto end;
1181 1.31 bouyer }
1182 1.31 bouyer } else if ((drv_mask & 0x02) == 0) {
1183 1.31 bouyer /* no slave */
1184 1.31 bouyer if ((drv_mask & 0x01) != 0 && (st0 & WDCS_BSY) == 0) {
1185 1.31 bouyer /* No slave, master is ready, it's done */
1186 1.65 bouyer goto end;
1187 1.31 bouyer }
1188 1.2 bouyer } else {
1189 1.31 bouyer /* Wait for both master and slave to be ready */
1190 1.31 bouyer if ((st0 & WDCS_BSY) == 0 && (st1 & WDCS_BSY) == 0) {
1191 1.65 bouyer goto end;
1192 1.2 bouyer }
1193 1.2 bouyer }
1194 1.137 bouyer if (poll)
1195 1.137 bouyer delay(WDCDELAY);
1196 1.137 bouyer else
1197 1.137 bouyer tsleep(&nloop, PRIBIO, "atarst", 1);
1198 1.2 bouyer }
1199 1.116 wiz /* Reset timed out. Maybe it's because drv_mask was not right */
1200 1.31 bouyer if (st0 & WDCS_BSY)
1201 1.31 bouyer drv_mask &= ~0x01;
1202 1.31 bouyer if (st1 & WDCS_BSY)
1203 1.31 bouyer drv_mask &= ~0x02;
1204 1.65 bouyer end:
1205 1.70 bouyer WDCDEBUG_PRINT(("%s:%d:0: after reset, sc=0x%x sn=0x%x "
1206 1.70 bouyer "cl=0x%x ch=0x%x\n",
1207 1.70 bouyer chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
1208 1.70 bouyer chp->channel, sc0, sn0, cl0, ch0), DEBUG_PROBE);
1209 1.70 bouyer WDCDEBUG_PRINT(("%s:%d:1: after reset, sc=0x%x sn=0x%x "
1210 1.70 bouyer "cl=0x%x ch=0x%x\n",
1211 1.70 bouyer chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
1212 1.70 bouyer chp->channel, sc1, sn1, cl1, ch1), DEBUG_PROBE);
1213 1.70 bouyer
1214 1.149 bouyer WDCDEBUG_PRINT(("%s:%d: wdcwait_reset() end, st0=0x%x st1=0x%x\n",
1215 1.65 bouyer chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", chp->channel,
1216 1.149 bouyer st0, st1), DEBUG_PROBE);
1217 1.65 bouyer
1218 1.31 bouyer return drv_mask;
1219 1.2 bouyer }
1220 1.2 bouyer
1221 1.2 bouyer /*
1222 1.31 bouyer * Wait for a drive to be !BSY, and have mask in its status register.
1223 1.31 bouyer * return -1 for a timeout after "timeout" ms.
1224 1.2 bouyer */
1225 1.31 bouyer int
1226 1.137 bouyer __wdcwait(chp, mask, bits, timeout)
1227 1.31 bouyer struct channel_softc *chp;
1228 1.31 bouyer int mask, bits, timeout;
1229 1.2 bouyer {
1230 1.31 bouyer u_char status;
1231 1.31 bouyer int time = 0;
1232 1.60 abs
1233 1.137 bouyer WDCDEBUG_PRINT(("__wdcwait %s:%d\n", chp->wdc ?chp->wdc->sc_dev.dv_xname
1234 1.60 abs :"none", chp->channel), DEBUG_STATUS);
1235 1.31 bouyer chp->ch_error = 0;
1236 1.31 bouyer
1237 1.31 bouyer timeout = timeout * 1000 / WDCDELAY; /* delay uses microseconds */
1238 1.2 bouyer
1239 1.31 bouyer for (;;) {
1240 1.31 bouyer chp->ch_status = status =
1241 1.31 bouyer bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
1242 1.131 mycroft if ((status & (WDCS_BSY | mask)) == bits)
1243 1.31 bouyer break;
1244 1.31 bouyer if (++time > timeout) {
1245 1.137 bouyer WDCDEBUG_PRINT(("__wdcwait: timeout (time=%d), "
1246 1.87 bouyer "status %x error %x (mask 0x%x bits 0x%x)\n",
1247 1.87 bouyer time, status,
1248 1.31 bouyer bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1249 1.77 bouyer wd_error), mask, bits),
1250 1.87 bouyer DEBUG_STATUS | DEBUG_PROBE | DEBUG_DELAY);
1251 1.137 bouyer return(WDCWAIT_TOUT);
1252 1.31 bouyer }
1253 1.31 bouyer delay(WDCDELAY);
1254 1.2 bouyer }
1255 1.87 bouyer #ifdef WDCDEBUG
1256 1.87 bouyer if (time > 0 && (wdcdebug_mask & DEBUG_DELAY))
1257 1.137 bouyer printf("__wdcwait: did busy-wait, time=%d\n", time);
1258 1.87 bouyer #endif
1259 1.31 bouyer if (status & WDCS_ERR)
1260 1.31 bouyer chp->ch_error = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1261 1.31 bouyer wd_error);
1262 1.31 bouyer #ifdef WDCNDELAY_DEBUG
1263 1.31 bouyer /* After autoconfig, there should be no long delays. */
1264 1.31 bouyer if (!cold && time > WDCNDELAY_DEBUG) {
1265 1.31 bouyer struct wdc_xfer *xfer = chp->ch_queue->sc_xfer.tqh_first;
1266 1.31 bouyer if (xfer == NULL)
1267 1.31 bouyer printf("%s channel %d: warning: busy-wait took %dus\n",
1268 1.31 bouyer chp->wdc->sc_dev.dv_xname, chp->channel,
1269 1.31 bouyer WDCDELAY * time);
1270 1.31 bouyer else
1271 1.31 bouyer printf("%s:%d:%d: warning: busy-wait took %dus\n",
1272 1.49 bouyer chp->wdc->sc_dev.dv_xname, chp->channel,
1273 1.31 bouyer xfer->drive,
1274 1.31 bouyer WDCDELAY * time);
1275 1.2 bouyer }
1276 1.2 bouyer #endif
1277 1.137 bouyer return(WDCWAIT_OK);
1278 1.137 bouyer }
1279 1.137 bouyer
1280 1.137 bouyer /*
1281 1.137 bouyer * Call __wdcwait(), polling using tsleep() or waking up the kernel
1282 1.137 bouyer * thread if possible
1283 1.137 bouyer */
1284 1.137 bouyer int
1285 1.137 bouyer wdcwait(chp, mask, bits, timeout, flags)
1286 1.137 bouyer struct channel_softc *chp;
1287 1.137 bouyer int mask, bits, timeout, flags;
1288 1.137 bouyer {
1289 1.137 bouyer int error, i, timeout_hz = mstohz(timeout);
1290 1.137 bouyer
1291 1.137 bouyer if (timeout_hz == 0 ||
1292 1.137 bouyer (flags & (AT_WAIT | AT_POLL)) == AT_POLL)
1293 1.137 bouyer error = __wdcwait(chp, mask, bits, timeout);
1294 1.137 bouyer else {
1295 1.137 bouyer error = __wdcwait(chp, mask, bits, WDCDELAY_POLL);
1296 1.137 bouyer if (error != 0) {
1297 1.147 bouyer if ((chp->ch_flags & WDCF_TH_RUN) ||
1298 1.147 bouyer (flags & AT_WAIT)) {
1299 1.137 bouyer /*
1300 1.147 bouyer * we're running in the channel thread
1301 1.147 bouyer * or some userland thread context
1302 1.137 bouyer */
1303 1.137 bouyer for (i = 0; i < timeout_hz; i++) {
1304 1.137 bouyer if (__wdcwait(chp, mask, bits,
1305 1.137 bouyer WDCDELAY_POLL) == 0) {
1306 1.137 bouyer error = 0;
1307 1.137 bouyer break;
1308 1.137 bouyer }
1309 1.137 bouyer tsleep(&chp, PRIBIO, "atapoll", 1);
1310 1.137 bouyer }
1311 1.137 bouyer } else {
1312 1.137 bouyer /*
1313 1.137 bouyer * we're probably in interrupt context,
1314 1.137 bouyer * ask the thread to come back here
1315 1.137 bouyer */
1316 1.147 bouyer #ifdef DIAGNOSTIC
1317 1.148 bouyer if (chp->ch_queue->queue_freeze > 0)
1318 1.148 bouyer panic("wdcwait: queue_freeze");
1319 1.147 bouyer #endif
1320 1.148 bouyer chp->ch_queue->queue_freeze++;
1321 1.137 bouyer wakeup(&chp->thread);
1322 1.137 bouyer return(WDCWAIT_THR);
1323 1.137 bouyer }
1324 1.137 bouyer }
1325 1.137 bouyer }
1326 1.137 bouyer return(error);
1327 1.2 bouyer }
1328 1.2 bouyer
1329 1.137 bouyer
1330 1.84 bouyer /*
1331 1.84 bouyer * Busy-wait for DMA to complete
1332 1.84 bouyer */
1333 1.84 bouyer int
1334 1.84 bouyer wdc_dmawait(chp, xfer, timeout)
1335 1.84 bouyer struct channel_softc *chp;
1336 1.84 bouyer struct wdc_xfer *xfer;
1337 1.84 bouyer int timeout;
1338 1.84 bouyer {
1339 1.84 bouyer int time;
1340 1.84 bouyer for (time = 0; time < timeout * 1000 / WDCDELAY; time++) {
1341 1.84 bouyer chp->wdc->dma_status =
1342 1.84 bouyer (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
1343 1.84 bouyer chp->channel, xfer->drive, 0);
1344 1.84 bouyer if ((chp->wdc->dma_status & WDC_DMAST_NOIRQ) == 0)
1345 1.84 bouyer return 0;
1346 1.84 bouyer delay(WDCDELAY);
1347 1.84 bouyer }
1348 1.84 bouyer /* timeout, force a DMA halt */
1349 1.84 bouyer chp->wdc->dma_status = (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
1350 1.84 bouyer chp->channel, xfer->drive, 1);
1351 1.84 bouyer return 1;
1352 1.84 bouyer }
1353 1.84 bouyer
1354 1.31 bouyer void
1355 1.31 bouyer wdctimeout(arg)
1356 1.31 bouyer void *arg;
1357 1.2 bouyer {
1358 1.31 bouyer struct channel_softc *chp = (struct channel_softc *)arg;
1359 1.31 bouyer struct wdc_xfer *xfer = chp->ch_queue->sc_xfer.tqh_first;
1360 1.31 bouyer int s;
1361 1.2 bouyer
1362 1.31 bouyer WDCDEBUG_PRINT(("wdctimeout\n"), DEBUG_FUNCS);
1363 1.31 bouyer
1364 1.31 bouyer s = splbio();
1365 1.31 bouyer if ((chp->ch_flags & WDCF_IRQ_WAIT) != 0) {
1366 1.31 bouyer __wdcerror(chp, "lost interrupt");
1367 1.88 mrg printf("\ttype: %s tc_bcount: %d tc_skip: %d\n",
1368 1.88 mrg (xfer->c_flags & C_ATAPI) ? "atapi" : "ata",
1369 1.88 mrg xfer->c_bcount,
1370 1.88 mrg xfer->c_skip);
1371 1.84 bouyer if (chp->ch_flags & WDCF_DMA_WAIT) {
1372 1.84 bouyer chp->wdc->dma_status =
1373 1.84 bouyer (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
1374 1.84 bouyer chp->channel, xfer->drive, 1);
1375 1.84 bouyer chp->ch_flags &= ~WDCF_DMA_WAIT;
1376 1.84 bouyer }
1377 1.31 bouyer /*
1378 1.119 drochner * Call the interrupt routine. If we just missed an interrupt,
1379 1.31 bouyer * it will do what's needed. Else, it will take the needed
1380 1.31 bouyer * action (reset the device).
1381 1.70 bouyer * Before that we need to reinstall the timeout callback,
1382 1.70 bouyer * in case it will miss another irq while in this transfer
1383 1.70 bouyer * We arbitray chose it to be 1s
1384 1.31 bouyer */
1385 1.81 thorpej callout_reset(&chp->ch_callout, hz, wdctimeout, chp);
1386 1.31 bouyer xfer->c_flags |= C_TIMEOU;
1387 1.31 bouyer chp->ch_flags &= ~WDCF_IRQ_WAIT;
1388 1.66 bouyer xfer->c_intr(chp, xfer, 1);
1389 1.31 bouyer } else
1390 1.31 bouyer __wdcerror(chp, "missing untimeout");
1391 1.31 bouyer splx(s);
1392 1.2 bouyer }
1393 1.2 bouyer
1394 1.31 bouyer /*
1395 1.152 wiz * Probe drive's capabilities, for use by the controller later
1396 1.31 bouyer * Assumes drvp points to an existing drive.
1397 1.31 bouyer * XXX this should be a controller-indep function
1398 1.31 bouyer */
1399 1.2 bouyer void
1400 1.31 bouyer wdc_probe_caps(drvp)
1401 1.31 bouyer struct ata_drive_datas *drvp;
1402 1.2 bouyer {
1403 1.31 bouyer struct ataparams params, params2;
1404 1.31 bouyer struct channel_softc *chp = drvp->chnl_softc;
1405 1.31 bouyer struct device *drv_dev = drvp->drv_softc;
1406 1.31 bouyer struct wdc_softc *wdc = chp->wdc;
1407 1.31 bouyer int i, printed;
1408 1.31 bouyer char *sep = "";
1409 1.48 bouyer int cf_flags;
1410 1.31 bouyer
1411 1.125 mycroft if (ata_get_params(drvp, AT_WAIT, ¶ms) != CMD_OK) {
1412 1.31 bouyer /* IDENTIFY failed. Can't tell more about the device */
1413 1.2 bouyer return;
1414 1.2 bouyer }
1415 1.31 bouyer if ((wdc->cap & (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
1416 1.31 bouyer (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) {
1417 1.2 bouyer /*
1418 1.39 bouyer * Controller claims 16 and 32 bit transfers.
1419 1.39 bouyer * Re-do an IDENTIFY with 32-bit transfers,
1420 1.31 bouyer * and compare results.
1421 1.2 bouyer */
1422 1.31 bouyer drvp->drive_flags |= DRIVE_CAP32;
1423 1.125 mycroft ata_get_params(drvp, AT_WAIT, ¶ms2);
1424 1.31 bouyer if (memcmp(¶ms, ¶ms2, sizeof(struct ataparams)) != 0) {
1425 1.31 bouyer /* Not good. fall back to 16bits */
1426 1.31 bouyer drvp->drive_flags &= ~DRIVE_CAP32;
1427 1.31 bouyer } else {
1428 1.125 mycroft aprint_normal("%s: 32-bit data port\n",
1429 1.123 thorpej drv_dev->dv_xname);
1430 1.2 bouyer }
1431 1.2 bouyer }
1432 1.55 bouyer #if 0 /* Some ultra-DMA drives claims to only support ATA-3. sigh */
1433 1.55 bouyer if (params.atap_ata_major > 0x01 &&
1434 1.55 bouyer params.atap_ata_major != 0xffff) {
1435 1.55 bouyer for (i = 14; i > 0; i--) {
1436 1.55 bouyer if (params.atap_ata_major & (1 << i)) {
1437 1.125 mycroft aprint_normal("%s: ATA version %d\n",
1438 1.125 mycroft drv_dev->dv_xname, i);
1439 1.55 bouyer drvp->ata_vers = i;
1440 1.55 bouyer break;
1441 1.55 bouyer }
1442 1.55 bouyer }
1443 1.125 mycroft }
1444 1.55 bouyer #endif
1445 1.2 bouyer
1446 1.31 bouyer /* An ATAPI device is at last PIO mode 3 */
1447 1.31 bouyer if (drvp->drive_flags & DRIVE_ATAPI)
1448 1.31 bouyer drvp->PIO_mode = 3;
1449 1.2 bouyer
1450 1.2 bouyer /*
1451 1.31 bouyer * It's not in the specs, but it seems that some drive
1452 1.31 bouyer * returns 0xffff in atap_extensions when this field is invalid
1453 1.2 bouyer */
1454 1.31 bouyer if (params.atap_extensions != 0xffff &&
1455 1.31 bouyer (params.atap_extensions & WDC_EXT_MODES)) {
1456 1.31 bouyer printed = 0;
1457 1.31 bouyer /*
1458 1.31 bouyer * XXX some drives report something wrong here (they claim to
1459 1.31 bouyer * support PIO mode 8 !). As mode is coded on 3 bits in
1460 1.31 bouyer * SET FEATURE, limit it to 7 (so limit i to 4).
1461 1.116 wiz * If higher mode than 7 is found, abort.
1462 1.31 bouyer */
1463 1.39 bouyer for (i = 7; i >= 0; i--) {
1464 1.31 bouyer if ((params.atap_piomode_supp & (1 << i)) == 0)
1465 1.31 bouyer continue;
1466 1.39 bouyer if (i > 4)
1467 1.39 bouyer return;
1468 1.31 bouyer /*
1469 1.31 bouyer * See if mode is accepted.
1470 1.31 bouyer * If the controller can't set its PIO mode,
1471 1.31 bouyer * assume the defaults are good, so don't try
1472 1.31 bouyer * to set it
1473 1.31 bouyer */
1474 1.31 bouyer if ((wdc->cap & WDC_CAPABILITY_MODE) != 0)
1475 1.137 bouyer /*
1476 1.137 bouyer * It's OK to pool here, it's fast enouth
1477 1.137 bouyer * to not bother waiting for interrupt
1478 1.137 bouyer */
1479 1.31 bouyer if (ata_set_mode(drvp, 0x08 | (i + 3),
1480 1.125 mycroft AT_WAIT) != CMD_OK)
1481 1.2 bouyer continue;
1482 1.31 bouyer if (!printed) {
1483 1.123 thorpej aprint_normal("%s: drive supports PIO mode %d",
1484 1.39 bouyer drv_dev->dv_xname, i + 3);
1485 1.31 bouyer sep = ",";
1486 1.31 bouyer printed = 1;
1487 1.31 bouyer }
1488 1.31 bouyer /*
1489 1.31 bouyer * If controller's driver can't set its PIO mode,
1490 1.31 bouyer * get the highter one for the drive.
1491 1.31 bouyer */
1492 1.31 bouyer if ((wdc->cap & WDC_CAPABILITY_MODE) == 0 ||
1493 1.52 bouyer wdc->PIO_cap >= i + 3) {
1494 1.31 bouyer drvp->PIO_mode = i + 3;
1495 1.48 bouyer drvp->PIO_cap = i + 3;
1496 1.2 bouyer break;
1497 1.2 bouyer }
1498 1.2 bouyer }
1499 1.31 bouyer if (!printed) {
1500 1.31 bouyer /*
1501 1.31 bouyer * We didn't find a valid PIO mode.
1502 1.31 bouyer * Assume the values returned for DMA are buggy too
1503 1.31 bouyer */
1504 1.31 bouyer return;
1505 1.2 bouyer }
1506 1.35 bouyer drvp->drive_flags |= DRIVE_MODE;
1507 1.31 bouyer printed = 0;
1508 1.31 bouyer for (i = 7; i >= 0; i--) {
1509 1.31 bouyer if ((params.atap_dmamode_supp & (1 << i)) == 0)
1510 1.31 bouyer continue;
1511 1.31 bouyer if ((wdc->cap & WDC_CAPABILITY_DMA) &&
1512 1.31 bouyer (wdc->cap & WDC_CAPABILITY_MODE))
1513 1.125 mycroft if (ata_set_mode(drvp, 0x20 | i, AT_WAIT)
1514 1.31 bouyer != CMD_OK)
1515 1.31 bouyer continue;
1516 1.31 bouyer if (!printed) {
1517 1.123 thorpej aprint_normal("%s DMA mode %d", sep, i);
1518 1.31 bouyer sep = ",";
1519 1.31 bouyer printed = 1;
1520 1.31 bouyer }
1521 1.31 bouyer if (wdc->cap & WDC_CAPABILITY_DMA) {
1522 1.31 bouyer if ((wdc->cap & WDC_CAPABILITY_MODE) &&
1523 1.52 bouyer wdc->DMA_cap < i)
1524 1.31 bouyer continue;
1525 1.31 bouyer drvp->DMA_mode = i;
1526 1.48 bouyer drvp->DMA_cap = i;
1527 1.31 bouyer drvp->drive_flags |= DRIVE_DMA;
1528 1.31 bouyer }
1529 1.2 bouyer break;
1530 1.2 bouyer }
1531 1.31 bouyer if (params.atap_extensions & WDC_EXT_UDMA_MODES) {
1532 1.71 bouyer printed = 0;
1533 1.31 bouyer for (i = 7; i >= 0; i--) {
1534 1.31 bouyer if ((params.atap_udmamode_supp & (1 << i))
1535 1.31 bouyer == 0)
1536 1.31 bouyer continue;
1537 1.31 bouyer if ((wdc->cap & WDC_CAPABILITY_MODE) &&
1538 1.31 bouyer (wdc->cap & WDC_CAPABILITY_UDMA))
1539 1.31 bouyer if (ata_set_mode(drvp, 0x40 | i,
1540 1.125 mycroft AT_WAIT) != CMD_OK)
1541 1.31 bouyer continue;
1542 1.71 bouyer if (!printed) {
1543 1.123 thorpej aprint_normal("%s Ultra-DMA mode %d",
1544 1.123 thorpej sep, i);
1545 1.93 wrstuden if (i == 2)
1546 1.123 thorpej aprint_normal(" (Ultra/33)");
1547 1.93 wrstuden else if (i == 4)
1548 1.123 thorpej aprint_normal(" (Ultra/66)");
1549 1.93 wrstuden else if (i == 5)
1550 1.123 thorpej aprint_normal(" (Ultra/100)");
1551 1.117 bouyer else if (i == 6)
1552 1.123 thorpej aprint_normal(" (Ultra/133)");
1553 1.71 bouyer sep = ",";
1554 1.71 bouyer printed = 1;
1555 1.71 bouyer }
1556 1.31 bouyer if (wdc->cap & WDC_CAPABILITY_UDMA) {
1557 1.50 bouyer if ((wdc->cap & WDC_CAPABILITY_MODE) &&
1558 1.52 bouyer wdc->UDMA_cap < i)
1559 1.50 bouyer continue;
1560 1.31 bouyer drvp->UDMA_mode = i;
1561 1.48 bouyer drvp->UDMA_cap = i;
1562 1.31 bouyer drvp->drive_flags |= DRIVE_UDMA;
1563 1.31 bouyer }
1564 1.31 bouyer break;
1565 1.31 bouyer }
1566 1.31 bouyer }
1567 1.123 thorpej aprint_normal("\n");
1568 1.55 bouyer }
1569 1.55 bouyer
1570 1.55 bouyer /* Try to guess ATA version here, if it didn't get reported */
1571 1.55 bouyer if (drvp->ata_vers == 0) {
1572 1.55 bouyer if (drvp->drive_flags & DRIVE_UDMA)
1573 1.55 bouyer drvp->ata_vers = 4; /* should be at last ATA-4 */
1574 1.55 bouyer else if (drvp->PIO_cap > 2)
1575 1.55 bouyer drvp->ata_vers = 2; /* should be at last ATA-2 */
1576 1.48 bouyer }
1577 1.48 bouyer cf_flags = drv_dev->dv_cfdata->cf_flags;
1578 1.48 bouyer if (cf_flags & ATA_CONFIG_PIO_SET) {
1579 1.48 bouyer drvp->PIO_mode =
1580 1.48 bouyer (cf_flags & ATA_CONFIG_PIO_MODES) >> ATA_CONFIG_PIO_OFF;
1581 1.48 bouyer drvp->drive_flags |= DRIVE_MODE;
1582 1.48 bouyer }
1583 1.48 bouyer if ((wdc->cap & WDC_CAPABILITY_DMA) == 0) {
1584 1.48 bouyer /* don't care about DMA modes */
1585 1.48 bouyer return;
1586 1.48 bouyer }
1587 1.48 bouyer if (cf_flags & ATA_CONFIG_DMA_SET) {
1588 1.48 bouyer if ((cf_flags & ATA_CONFIG_DMA_MODES) ==
1589 1.48 bouyer ATA_CONFIG_DMA_DISABLE) {
1590 1.48 bouyer drvp->drive_flags &= ~DRIVE_DMA;
1591 1.48 bouyer } else {
1592 1.48 bouyer drvp->DMA_mode = (cf_flags & ATA_CONFIG_DMA_MODES) >>
1593 1.48 bouyer ATA_CONFIG_DMA_OFF;
1594 1.48 bouyer drvp->drive_flags |= DRIVE_DMA | DRIVE_MODE;
1595 1.48 bouyer }
1596 1.101 bouyer }
1597 1.101 bouyer if ((wdc->cap & WDC_CAPABILITY_UDMA) == 0) {
1598 1.101 bouyer /* don't care about UDMA modes */
1599 1.101 bouyer return;
1600 1.48 bouyer }
1601 1.48 bouyer if (cf_flags & ATA_CONFIG_UDMA_SET) {
1602 1.48 bouyer if ((cf_flags & ATA_CONFIG_UDMA_MODES) ==
1603 1.48 bouyer ATA_CONFIG_UDMA_DISABLE) {
1604 1.48 bouyer drvp->drive_flags &= ~DRIVE_UDMA;
1605 1.48 bouyer } else {
1606 1.48 bouyer drvp->UDMA_mode = (cf_flags & ATA_CONFIG_UDMA_MODES) >>
1607 1.48 bouyer ATA_CONFIG_UDMA_OFF;
1608 1.48 bouyer drvp->drive_flags |= DRIVE_UDMA | DRIVE_MODE;
1609 1.48 bouyer }
1610 1.2 bouyer }
1611 1.54 bouyer }
1612 1.54 bouyer
1613 1.54 bouyer /*
1614 1.56 bouyer * downgrade the transfer mode of a drive after an error. return 1 if
1615 1.54 bouyer * downgrade was possible, 0 otherwise.
1616 1.54 bouyer */
1617 1.54 bouyer int
1618 1.137 bouyer wdc_downgrade_mode(drvp, flags)
1619 1.54 bouyer struct ata_drive_datas *drvp;
1620 1.54 bouyer {
1621 1.54 bouyer struct channel_softc *chp = drvp->chnl_softc;
1622 1.54 bouyer struct device *drv_dev = drvp->drv_softc;
1623 1.54 bouyer struct wdc_softc *wdc = chp->wdc;
1624 1.54 bouyer int cf_flags = drv_dev->dv_cfdata->cf_flags;
1625 1.54 bouyer
1626 1.54 bouyer /* if drive or controller don't know its mode, we can't do much */
1627 1.54 bouyer if ((drvp->drive_flags & DRIVE_MODE) == 0 ||
1628 1.54 bouyer (wdc->cap & WDC_CAPABILITY_MODE) == 0)
1629 1.54 bouyer return 0;
1630 1.54 bouyer /* current drive mode was set by a config flag, let it this way */
1631 1.54 bouyer if ((cf_flags & ATA_CONFIG_PIO_SET) ||
1632 1.54 bouyer (cf_flags & ATA_CONFIG_DMA_SET) ||
1633 1.54 bouyer (cf_flags & ATA_CONFIG_UDMA_SET))
1634 1.54 bouyer return 0;
1635 1.54 bouyer
1636 1.61 bouyer /*
1637 1.73 bouyer * If we were using Ultra-DMA mode > 2, downgrade to mode 2 first.
1638 1.73 bouyer * Maybe we didn't properly notice the cable type
1639 1.78 bouyer * If we were using Ultra-DMA mode 2, downgrade to mode 1 first.
1640 1.78 bouyer * It helps in some cases.
1641 1.73 bouyer */
1642 1.78 bouyer if ((drvp->drive_flags & DRIVE_UDMA) && drvp->UDMA_mode >= 2) {
1643 1.78 bouyer drvp->UDMA_mode = (drvp->UDMA_mode == 2) ? 1 : 2;
1644 1.78 bouyer printf("%s: transfer error, downgrading to Ultra-DMA mode %d\n",
1645 1.73 bouyer drv_dev->dv_xname, drvp->UDMA_mode);
1646 1.73 bouyer }
1647 1.73 bouyer
1648 1.73 bouyer /*
1649 1.61 bouyer * If we were using ultra-DMA, don't downgrade to multiword DMA
1650 1.61 bouyer * if we noticed a CRC error. It has been noticed that CRC errors
1651 1.61 bouyer * in ultra-DMA lead to silent data corruption in multiword DMA.
1652 1.61 bouyer * Data corruption is less likely to occur in PIO mode.
1653 1.61 bouyer */
1654 1.73 bouyer else if ((drvp->drive_flags & DRIVE_UDMA) &&
1655 1.61 bouyer (drvp->drive_flags & DRIVE_DMAERR) == 0) {
1656 1.54 bouyer drvp->drive_flags &= ~DRIVE_UDMA;
1657 1.54 bouyer drvp->drive_flags |= DRIVE_DMA;
1658 1.54 bouyer drvp->DMA_mode = drvp->DMA_cap;
1659 1.56 bouyer printf("%s: transfer error, downgrading to DMA mode %d\n",
1660 1.54 bouyer drv_dev->dv_xname, drvp->DMA_mode);
1661 1.61 bouyer } else if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) {
1662 1.61 bouyer drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
1663 1.54 bouyer drvp->PIO_mode = drvp->PIO_cap;
1664 1.56 bouyer printf("%s: transfer error, downgrading to PIO mode %d\n",
1665 1.54 bouyer drv_dev->dv_xname, drvp->PIO_mode);
1666 1.54 bouyer } else /* already using PIO, can't downgrade */
1667 1.54 bouyer return 0;
1668 1.54 bouyer
1669 1.54 bouyer wdc->set_modes(chp);
1670 1.137 bouyer wdc_print_modes(chp);
1671 1.137 bouyer /* reset the channel, which will shedule all drives for setup */
1672 1.137 bouyer wdc_reset_channel(drvp, flags);
1673 1.54 bouyer return 1;
1674 1.2 bouyer }
1675 1.2 bouyer
1676 1.2 bouyer int
1677 1.31 bouyer wdc_exec_command(drvp, wdc_c)
1678 1.31 bouyer struct ata_drive_datas *drvp;
1679 1.31 bouyer struct wdc_command *wdc_c;
1680 1.31 bouyer {
1681 1.31 bouyer struct channel_softc *chp = drvp->chnl_softc;
1682 1.2 bouyer struct wdc_xfer *xfer;
1683 1.31 bouyer int s, ret;
1684 1.2 bouyer
1685 1.34 bouyer WDCDEBUG_PRINT(("wdc_exec_command %s:%d:%d\n",
1686 1.34 bouyer chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive),
1687 1.34 bouyer DEBUG_FUNCS);
1688 1.2 bouyer
1689 1.31 bouyer /* set up an xfer and queue. Wait for completion */
1690 1.31 bouyer xfer = wdc_get_xfer(wdc_c->flags & AT_WAIT ? WDC_CANSLEEP :
1691 1.31 bouyer WDC_NOSLEEP);
1692 1.31 bouyer if (xfer == NULL) {
1693 1.31 bouyer return WDC_TRY_AGAIN;
1694 1.31 bouyer }
1695 1.2 bouyer
1696 1.98 bjh21 if (chp->wdc->cap & WDC_CAPABILITY_NOIRQ)
1697 1.98 bjh21 wdc_c->flags |= AT_POLL;
1698 1.31 bouyer if (wdc_c->flags & AT_POLL)
1699 1.31 bouyer xfer->c_flags |= C_POLL;
1700 1.31 bouyer xfer->drive = drvp->drive;
1701 1.31 bouyer xfer->databuf = wdc_c->data;
1702 1.31 bouyer xfer->c_bcount = wdc_c->bcount;
1703 1.31 bouyer xfer->cmd = wdc_c;
1704 1.31 bouyer xfer->c_start = __wdccommand_start;
1705 1.31 bouyer xfer->c_intr = __wdccommand_intr;
1706 1.75 enami xfer->c_kill_xfer = __wdccommand_done;
1707 1.2 bouyer
1708 1.31 bouyer s = splbio();
1709 1.31 bouyer wdc_exec_xfer(chp, xfer);
1710 1.31 bouyer #ifdef DIAGNOSTIC
1711 1.31 bouyer if ((wdc_c->flags & AT_POLL) != 0 &&
1712 1.31 bouyer (wdc_c->flags & AT_DONE) == 0)
1713 1.118 provos panic("wdc_exec_command: polled command not done");
1714 1.2 bouyer #endif
1715 1.31 bouyer if (wdc_c->flags & AT_DONE) {
1716 1.31 bouyer ret = WDC_COMPLETE;
1717 1.31 bouyer } else {
1718 1.31 bouyer if (wdc_c->flags & AT_WAIT) {
1719 1.69 bouyer while ((wdc_c->flags & AT_DONE) == 0) {
1720 1.69 bouyer tsleep(wdc_c, PRIBIO, "wdccmd", 0);
1721 1.69 bouyer }
1722 1.31 bouyer ret = WDC_COMPLETE;
1723 1.31 bouyer } else {
1724 1.31 bouyer ret = WDC_QUEUED;
1725 1.2 bouyer }
1726 1.2 bouyer }
1727 1.31 bouyer splx(s);
1728 1.31 bouyer return ret;
1729 1.2 bouyer }
1730 1.2 bouyer
1731 1.2 bouyer void
1732 1.31 bouyer __wdccommand_start(chp, xfer)
1733 1.31 bouyer struct channel_softc *chp;
1734 1.2 bouyer struct wdc_xfer *xfer;
1735 1.31 bouyer {
1736 1.31 bouyer int drive = xfer->drive;
1737 1.31 bouyer struct wdc_command *wdc_c = xfer->cmd;
1738 1.31 bouyer
1739 1.34 bouyer WDCDEBUG_PRINT(("__wdccommand_start %s:%d:%d\n",
1740 1.34 bouyer chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
1741 1.34 bouyer DEBUG_FUNCS);
1742 1.31 bouyer
1743 1.107 dbj if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
1744 1.107 dbj chp->wdc->select(chp,drive);
1745 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
1746 1.31 bouyer WDSD_IBM | (drive << 4));
1747 1.137 bouyer switch(wdcwait(chp, wdc_c->r_st_bmask | WDCS_DRQ,
1748 1.137 bouyer wdc_c->r_st_bmask, wdc_c->timeout, wdc_c->flags)) {
1749 1.137 bouyer case WDCWAIT_OK:
1750 1.137 bouyer break;
1751 1.137 bouyer case WDCWAIT_TOUT:
1752 1.31 bouyer wdc_c->flags |= AT_TIMEOU;
1753 1.31 bouyer __wdccommand_done(chp, xfer);
1754 1.53 bouyer return;
1755 1.137 bouyer case WDCWAIT_THR:
1756 1.137 bouyer return;
1757 1.31 bouyer }
1758 1.135 bouyer if (wdc_c->flags & AT_POLL) {
1759 1.135 bouyer /* polled command, disable interrupts */
1760 1.135 bouyer bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
1761 1.135 bouyer WDCTL_4BIT | WDCTL_IDS);
1762 1.135 bouyer }
1763 1.31 bouyer wdccommand(chp, drive, wdc_c->r_command, wdc_c->r_cyl, wdc_c->r_head,
1764 1.31 bouyer wdc_c->r_sector, wdc_c->r_count, wdc_c->r_precomp);
1765 1.139 bouyer
1766 1.31 bouyer if ((wdc_c->flags & AT_POLL) == 0) {
1767 1.31 bouyer chp->ch_flags |= WDCF_IRQ_WAIT; /* wait for interrupt */
1768 1.81 thorpej callout_reset(&chp->ch_callout, wdc_c->timeout / 1000 * hz,
1769 1.81 thorpej wdctimeout, chp);
1770 1.31 bouyer return;
1771 1.2 bouyer }
1772 1.2 bouyer /*
1773 1.31 bouyer * Polled command. Wait for drive ready or drq. Done in intr().
1774 1.31 bouyer * Wait for at last 400ns for status bit to be valid.
1775 1.2 bouyer */
1776 1.134 mycroft delay(10); /* 400ns delay */
1777 1.66 bouyer __wdccommand_intr(chp, xfer, 0);
1778 1.2 bouyer }
1779 1.2 bouyer
1780 1.2 bouyer int
1781 1.66 bouyer __wdccommand_intr(chp, xfer, irq)
1782 1.31 bouyer struct channel_softc *chp;
1783 1.31 bouyer struct wdc_xfer *xfer;
1784 1.66 bouyer int irq;
1785 1.2 bouyer {
1786 1.31 bouyer struct wdc_command *wdc_c = xfer->cmd;
1787 1.31 bouyer int bcount = wdc_c->bcount;
1788 1.31 bouyer char *data = wdc_c->data;
1789 1.137 bouyer int wflags;
1790 1.137 bouyer
1791 1.137 bouyer if ((wdc_c->flags & (AT_WAIT | AT_POLL)) == (AT_WAIT | AT_POLL)) {
1792 1.137 bouyer /* both wait and poll, we can tsleep here */
1793 1.147 bouyer wflags = AT_WAIT | AT_POLL;
1794 1.137 bouyer } else {
1795 1.137 bouyer wflags = AT_POLL;
1796 1.137 bouyer }
1797 1.31 bouyer
1798 1.114 bouyer again:
1799 1.34 bouyer WDCDEBUG_PRINT(("__wdccommand_intr %s:%d:%d\n",
1800 1.34 bouyer chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), DEBUG_INTR);
1801 1.137 bouyer /*
1802 1.137 bouyer * after a ATAPI_SOFT_RESET, the device will have released the bus.
1803 1.137 bouyer * Reselect again, it doesn't hurt for others commands, and the time
1804 1.137 bouyer * penalty for the extra regiter write is acceptable,
1805 1.137 bouyer * wdc_exec_command() isn't called often (mosly for autoconfig)
1806 1.137 bouyer */
1807 1.137 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
1808 1.137 bouyer WDSD_IBM | (xfer->drive << 4));
1809 1.114 bouyer if ((wdc_c->flags & AT_XFDONE) != 0) {
1810 1.114 bouyer /*
1811 1.114 bouyer * We have completed a data xfer. The drive should now be
1812 1.114 bouyer * in its initial state
1813 1.114 bouyer */
1814 1.114 bouyer if (wdcwait(chp, wdc_c->r_st_bmask | WDCS_DRQ,
1815 1.137 bouyer wdc_c->r_st_bmask, (irq == 0) ? wdc_c->timeout : 0,
1816 1.137 bouyer wflags) == WDCWAIT_TOUT) {
1817 1.114 bouyer if (irq && (xfer->c_flags & C_TIMEOU) == 0)
1818 1.114 bouyer return 0; /* IRQ was not for us */
1819 1.114 bouyer wdc_c->flags |= AT_TIMEOU;
1820 1.114 bouyer }
1821 1.131 mycroft goto out;
1822 1.114 bouyer }
1823 1.31 bouyer if (wdcwait(chp, wdc_c->r_st_pmask, wdc_c->r_st_pmask,
1824 1.137 bouyer (irq == 0) ? wdc_c->timeout : 0, wflags) == WDCWAIT_TOUT) {
1825 1.66 bouyer if (irq && (xfer->c_flags & C_TIMEOU) == 0)
1826 1.63 bouyer return 0; /* IRQ was not for us */
1827 1.63 bouyer wdc_c->flags |= AT_TIMEOU;
1828 1.131 mycroft goto out;
1829 1.2 bouyer }
1830 1.91 bouyer if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
1831 1.91 bouyer chp->wdc->irqack(chp);
1832 1.31 bouyer if (wdc_c->flags & AT_READ) {
1833 1.131 mycroft if ((chp->ch_status & WDCS_DRQ) == 0) {
1834 1.131 mycroft wdc_c->flags |= AT_TIMEOU;
1835 1.131 mycroft goto out;
1836 1.131 mycroft }
1837 1.31 bouyer if (chp->ch_drive[xfer->drive].drive_flags & DRIVE_CAP32) {
1838 1.31 bouyer bus_space_read_multi_4(chp->data32iot, chp->data32ioh,
1839 1.31 bouyer 0, (u_int32_t*)data, bcount >> 2);
1840 1.31 bouyer data += bcount & 0xfffffffc;
1841 1.31 bouyer bcount = bcount & 0x03;
1842 1.31 bouyer }
1843 1.31 bouyer if (bcount > 0)
1844 1.31 bouyer bus_space_read_multi_2(chp->cmd_iot, chp->cmd_ioh,
1845 1.31 bouyer wd_data, (u_int16_t *)data, bcount >> 1);
1846 1.114 bouyer /* at this point the drive should be in its initial state */
1847 1.114 bouyer wdc_c->flags |= AT_XFDONE;
1848 1.137 bouyer /* XXX should read status register here ? */
1849 1.131 mycroft } else if (wdc_c->flags & AT_WRITE) {
1850 1.131 mycroft if ((chp->ch_status & WDCS_DRQ) == 0) {
1851 1.114 bouyer wdc_c->flags |= AT_TIMEOU;
1852 1.131 mycroft goto out;
1853 1.131 mycroft }
1854 1.31 bouyer if (chp->ch_drive[xfer->drive].drive_flags & DRIVE_CAP32) {
1855 1.31 bouyer bus_space_write_multi_4(chp->data32iot, chp->data32ioh,
1856 1.31 bouyer 0, (u_int32_t*)data, bcount >> 2);
1857 1.31 bouyer data += bcount & 0xfffffffc;
1858 1.31 bouyer bcount = bcount & 0x03;
1859 1.31 bouyer }
1860 1.31 bouyer if (bcount > 0)
1861 1.31 bouyer bus_space_write_multi_2(chp->cmd_iot, chp->cmd_ioh,
1862 1.31 bouyer wd_data, (u_int16_t *)data, bcount >> 1);
1863 1.114 bouyer wdc_c->flags |= AT_XFDONE;
1864 1.114 bouyer if ((wdc_c->flags & AT_POLL) == 0) {
1865 1.114 bouyer chp->ch_flags |= WDCF_IRQ_WAIT; /* wait for interrupt */
1866 1.114 bouyer callout_reset(&chp->ch_callout,
1867 1.114 bouyer wdc_c->timeout / 1000 * hz, wdctimeout, chp);
1868 1.114 bouyer return 1;
1869 1.114 bouyer } else {
1870 1.114 bouyer goto again;
1871 1.114 bouyer }
1872 1.2 bouyer }
1873 1.131 mycroft out:
1874 1.31 bouyer __wdccommand_done(chp, xfer);
1875 1.31 bouyer return 1;
1876 1.2 bouyer }
1877 1.2 bouyer
1878 1.2 bouyer void
1879 1.31 bouyer __wdccommand_done(chp, xfer)
1880 1.31 bouyer struct channel_softc *chp;
1881 1.31 bouyer struct wdc_xfer *xfer;
1882 1.2 bouyer {
1883 1.31 bouyer struct wdc_command *wdc_c = xfer->cmd;
1884 1.2 bouyer
1885 1.34 bouyer WDCDEBUG_PRINT(("__wdccommand_done %s:%d:%d\n",
1886 1.34 bouyer chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), DEBUG_FUNCS);
1887 1.70 bouyer
1888 1.81 thorpej callout_stop(&chp->ch_callout);
1889 1.70 bouyer
1890 1.31 bouyer if (chp->ch_status & WDCS_DWF)
1891 1.31 bouyer wdc_c->flags |= AT_DF;
1892 1.31 bouyer if (chp->ch_status & WDCS_ERR) {
1893 1.31 bouyer wdc_c->flags |= AT_ERROR;
1894 1.31 bouyer wdc_c->r_error = chp->ch_error;
1895 1.31 bouyer }
1896 1.31 bouyer wdc_c->flags |= AT_DONE;
1897 1.80 enami if ((wdc_c->flags & AT_READREG) != 0 &&
1898 1.80 enami (chp->wdc->sc_dev.dv_flags & DVF_ACTIVE) != 0 &&
1899 1.75 enami (wdc_c->flags & (AT_ERROR | AT_DF)) == 0) {
1900 1.46 kenh wdc_c->r_head = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1901 1.46 kenh wd_sdh);
1902 1.46 kenh wdc_c->r_cyl = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1903 1.46 kenh wd_cyl_hi) << 8;
1904 1.46 kenh wdc_c->r_cyl |= bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1905 1.46 kenh wd_cyl_lo);
1906 1.46 kenh wdc_c->r_sector = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1907 1.46 kenh wd_sector);
1908 1.46 kenh wdc_c->r_count = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1909 1.46 kenh wd_seccnt);
1910 1.46 kenh wdc_c->r_error = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1911 1.46 kenh wd_error);
1912 1.46 kenh wdc_c->r_precomp = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1913 1.46 kenh wd_precomp);
1914 1.135 bouyer }
1915 1.137 bouyer
1916 1.135 bouyer if (wdc_c->flags & AT_POLL) {
1917 1.135 bouyer /* enable interrupts */
1918 1.135 bouyer bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
1919 1.135 bouyer WDCTL_4BIT);
1920 1.46 kenh }
1921 1.31 bouyer wdc_free_xfer(chp, xfer);
1922 1.71 bouyer if (wdc_c->flags & AT_WAIT)
1923 1.71 bouyer wakeup(wdc_c);
1924 1.71 bouyer else if (wdc_c->callback)
1925 1.71 bouyer wdc_c->callback(wdc_c->callback_arg);
1926 1.45 drochner wdcstart(chp);
1927 1.31 bouyer return;
1928 1.2 bouyer }
1929 1.2 bouyer
1930 1.2 bouyer /*
1931 1.31 bouyer * Send a command. The drive should be ready.
1932 1.2 bouyer * Assumes interrupts are blocked.
1933 1.2 bouyer */
1934 1.31 bouyer void
1935 1.31 bouyer wdccommand(chp, drive, command, cylin, head, sector, count, precomp)
1936 1.31 bouyer struct channel_softc *chp;
1937 1.31 bouyer u_int8_t drive;
1938 1.31 bouyer u_int8_t command;
1939 1.31 bouyer u_int16_t cylin;
1940 1.31 bouyer u_int8_t head, sector, count, precomp;
1941 1.31 bouyer {
1942 1.31 bouyer WDCDEBUG_PRINT(("wdccommand %s:%d:%d: command=0x%x cylin=%d head=%d "
1943 1.31 bouyer "sector=%d count=%d precomp=%d\n", chp->wdc->sc_dev.dv_xname,
1944 1.31 bouyer chp->channel, drive, command, cylin, head, sector, count, precomp),
1945 1.31 bouyer DEBUG_FUNCS);
1946 1.31 bouyer
1947 1.107 dbj if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
1948 1.107 dbj chp->wdc->select(chp,drive);
1949 1.107 dbj
1950 1.31 bouyer /* Select drive, head, and addressing mode. */
1951 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
1952 1.31 bouyer WDSD_IBM | (drive << 4) | head);
1953 1.31 bouyer /* Load parameters. wd_features(ATA/ATAPI) = wd_precomp(ST506) */
1954 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_precomp,
1955 1.31 bouyer precomp);
1956 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo, cylin);
1957 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_hi, cylin >> 8);
1958 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sector, sector);
1959 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt, count);
1960 1.108 christos
1961 1.108 christos /* Send command. */
1962 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_command, command);
1963 1.108 christos return;
1964 1.108 christos }
1965 1.108 christos
1966 1.108 christos /*
1967 1.108 christos * Send a 48-bit addressing command. The drive should be ready.
1968 1.108 christos * Assumes interrupts are blocked.
1969 1.108 christos */
1970 1.108 christos void
1971 1.108 christos wdccommandext(chp, drive, command, blkno, count)
1972 1.108 christos struct channel_softc *chp;
1973 1.108 christos u_int8_t drive;
1974 1.108 christos u_int8_t command;
1975 1.108 christos u_int64_t blkno;
1976 1.108 christos u_int16_t count;
1977 1.108 christos {
1978 1.108 christos WDCDEBUG_PRINT(("wdccommandext %s:%d:%d: command=0x%x blkno=%d "
1979 1.108 christos "count=%d\n", chp->wdc->sc_dev.dv_xname,
1980 1.108 christos chp->channel, drive, command, (u_int32_t) blkno, count),
1981 1.108 christos DEBUG_FUNCS);
1982 1.108 christos
1983 1.108 christos if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
1984 1.108 christos chp->wdc->select(chp,drive);
1985 1.108 christos
1986 1.108 christos /* Select drive, head, and addressing mode. */
1987 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
1988 1.108 christos (drive << 4) | WDSD_LBA);
1989 1.108 christos
1990 1.108 christos /* previous */
1991 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_features, 0);
1992 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt, count >> 8);
1993 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_lba_hi, blkno >> 40);
1994 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_lba_mi, blkno >> 32);
1995 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_lba_lo, blkno >> 24);
1996 1.108 christos
1997 1.108 christos /* current */
1998 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_features, 0);
1999 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt, count);
2000 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_lba_hi, blkno >> 16);
2001 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_lba_mi, blkno >> 8);
2002 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_lba_lo, blkno);
2003 1.2 bouyer
2004 1.31 bouyer /* Send command. */
2005 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_command, command);
2006 1.31 bouyer return;
2007 1.2 bouyer }
2008 1.2 bouyer
2009 1.2 bouyer /*
2010 1.31 bouyer * Simplified version of wdccommand(). Unbusy/ready/drq must be
2011 1.31 bouyer * tested by the caller.
2012 1.2 bouyer */
2013 1.31 bouyer void
2014 1.31 bouyer wdccommandshort(chp, drive, command)
2015 1.31 bouyer struct channel_softc *chp;
2016 1.31 bouyer int drive;
2017 1.31 bouyer int command;
2018 1.2 bouyer {
2019 1.2 bouyer
2020 1.31 bouyer WDCDEBUG_PRINT(("wdccommandshort %s:%d:%d command 0x%x\n",
2021 1.31 bouyer chp->wdc->sc_dev.dv_xname, chp->channel, drive, command),
2022 1.31 bouyer DEBUG_FUNCS);
2023 1.107 dbj
2024 1.107 dbj if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
2025 1.107 dbj chp->wdc->select(chp,drive);
2026 1.2 bouyer
2027 1.31 bouyer /* Select drive. */
2028 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
2029 1.31 bouyer WDSD_IBM | (drive << 4));
2030 1.2 bouyer
2031 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_command, command);
2032 1.31 bouyer }
2033 1.2 bouyer
2034 1.31 bouyer /* Add a command to the queue and start controller. Must be called at splbio */
2035 1.2 bouyer
2036 1.2 bouyer void
2037 1.31 bouyer wdc_exec_xfer(chp, xfer)
2038 1.31 bouyer struct channel_softc *chp;
2039 1.2 bouyer struct wdc_xfer *xfer;
2040 1.2 bouyer {
2041 1.33 bouyer WDCDEBUG_PRINT(("wdc_exec_xfer %p channel %d drive %d\n", xfer,
2042 1.33 bouyer chp->channel, xfer->drive), DEBUG_XFERS);
2043 1.2 bouyer
2044 1.31 bouyer /* complete xfer setup */
2045 1.49 bouyer xfer->chp = chp;
2046 1.2 bouyer
2047 1.31 bouyer /*
2048 1.31 bouyer * If we are a polled command, and the list is not empty,
2049 1.31 bouyer * we are doing a dump. Drop the list to allow the polled command
2050 1.31 bouyer * to complete, we're going to reboot soon anyway.
2051 1.31 bouyer */
2052 1.31 bouyer if ((xfer->c_flags & C_POLL) != 0 &&
2053 1.31 bouyer chp->ch_queue->sc_xfer.tqh_first != NULL) {
2054 1.31 bouyer TAILQ_INIT(&chp->ch_queue->sc_xfer);
2055 1.31 bouyer }
2056 1.2 bouyer /* insert at the end of command list */
2057 1.31 bouyer TAILQ_INSERT_TAIL(&chp->ch_queue->sc_xfer,xfer , c_xferchain);
2058 1.31 bouyer WDCDEBUG_PRINT(("wdcstart from wdc_exec_xfer, flags 0x%x\n",
2059 1.33 bouyer chp->ch_flags), DEBUG_XFERS);
2060 1.45 drochner wdcstart(chp);
2061 1.31 bouyer }
2062 1.2 bouyer
2063 1.2 bouyer struct wdc_xfer *
2064 1.2 bouyer wdc_get_xfer(flags)
2065 1.2 bouyer int flags;
2066 1.2 bouyer {
2067 1.2 bouyer struct wdc_xfer *xfer;
2068 1.72 bouyer int s;
2069 1.2 bouyer
2070 1.72 bouyer s = splbio();
2071 1.71 bouyer xfer = pool_get(&wdc_xfer_pool,
2072 1.71 bouyer ((flags & WDC_NOSLEEP) != 0 ? PR_NOWAIT : PR_WAITOK));
2073 1.72 bouyer splx(s);
2074 1.99 chs if (xfer != NULL) {
2075 1.99 chs memset(xfer, 0, sizeof(struct wdc_xfer));
2076 1.99 chs }
2077 1.2 bouyer return xfer;
2078 1.2 bouyer }
2079 1.2 bouyer
2080 1.2 bouyer void
2081 1.31 bouyer wdc_free_xfer(chp, xfer)
2082 1.31 bouyer struct channel_softc *chp;
2083 1.2 bouyer struct wdc_xfer *xfer;
2084 1.2 bouyer {
2085 1.31 bouyer struct wdc_softc *wdc = chp->wdc;
2086 1.2 bouyer int s;
2087 1.2 bouyer
2088 1.31 bouyer if (wdc->cap & WDC_CAPABILITY_HWLOCK)
2089 1.31 bouyer (*wdc->free_hw)(chp);
2090 1.2 bouyer s = splbio();
2091 1.31 bouyer chp->ch_flags &= ~WDCF_ACTIVE;
2092 1.31 bouyer TAILQ_REMOVE(&chp->ch_queue->sc_xfer, xfer, c_xferchain);
2093 1.72 bouyer pool_put(&wdc_xfer_pool, xfer);
2094 1.2 bouyer splx(s);
2095 1.75 enami }
2096 1.75 enami
2097 1.75 enami /*
2098 1.75 enami * Kill off all pending xfers for a channel_softc.
2099 1.75 enami *
2100 1.75 enami * Must be called at splbio().
2101 1.75 enami */
2102 1.75 enami void
2103 1.75 enami wdc_kill_pending(chp)
2104 1.75 enami struct channel_softc *chp;
2105 1.75 enami {
2106 1.75 enami struct wdc_xfer *xfer;
2107 1.75 enami
2108 1.75 enami while ((xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer)) != NULL) {
2109 1.75 enami chp = xfer->chp;
2110 1.75 enami (*xfer->c_kill_xfer)(chp, xfer);
2111 1.75 enami }
2112 1.2 bouyer }
2113 1.2 bouyer
2114 1.31 bouyer static void
2115 1.31 bouyer __wdcerror(chp, msg)
2116 1.31 bouyer struct channel_softc *chp;
2117 1.2 bouyer char *msg;
2118 1.2 bouyer {
2119 1.31 bouyer struct wdc_xfer *xfer = chp->ch_queue->sc_xfer.tqh_first;
2120 1.88 mrg
2121 1.2 bouyer if (xfer == NULL)
2122 1.31 bouyer printf("%s:%d: %s\n", chp->wdc->sc_dev.dv_xname, chp->channel,
2123 1.31 bouyer msg);
2124 1.2 bouyer else
2125 1.31 bouyer printf("%s:%d:%d: %s\n", chp->wdc->sc_dev.dv_xname,
2126 1.49 bouyer chp->channel, xfer->drive, msg);
2127 1.2 bouyer }
2128 1.2 bouyer
2129 1.2 bouyer /*
2130 1.2 bouyer * the bit bucket
2131 1.2 bouyer */
2132 1.2 bouyer void
2133 1.31 bouyer wdcbit_bucket(chp, size)
2134 1.31 bouyer struct channel_softc *chp;
2135 1.2 bouyer int size;
2136 1.2 bouyer {
2137 1.2 bouyer
2138 1.12 cgd for (; size >= 2; size -= 2)
2139 1.31 bouyer (void)bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, wd_data);
2140 1.12 cgd if (size)
2141 1.31 bouyer (void)bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_data);
2142 1.44 thorpej }
2143 1.44 thorpej
2144 1.44 thorpej int
2145 1.44 thorpej wdc_addref(chp)
2146 1.44 thorpej struct channel_softc *chp;
2147 1.44 thorpej {
2148 1.44 thorpej struct wdc_softc *wdc = chp->wdc;
2149 1.96 bouyer struct scsipi_adapter *adapt = &wdc->sc_atapi_adapter._generic;
2150 1.44 thorpej int s, error = 0;
2151 1.44 thorpej
2152 1.44 thorpej s = splbio();
2153 1.96 bouyer if (adapt->adapt_refcnt++ == 0 &&
2154 1.96 bouyer adapt->adapt_enable != NULL) {
2155 1.96 bouyer error = (*adapt->adapt_enable)(&wdc->sc_dev, 1);
2156 1.44 thorpej if (error)
2157 1.96 bouyer adapt->adapt_refcnt--;
2158 1.44 thorpej }
2159 1.44 thorpej splx(s);
2160 1.44 thorpej return (error);
2161 1.44 thorpej }
2162 1.44 thorpej
2163 1.44 thorpej void
2164 1.44 thorpej wdc_delref(chp)
2165 1.44 thorpej struct channel_softc *chp;
2166 1.44 thorpej {
2167 1.44 thorpej struct wdc_softc *wdc = chp->wdc;
2168 1.96 bouyer struct scsipi_adapter *adapt = &wdc->sc_atapi_adapter._generic;
2169 1.44 thorpej int s;
2170 1.44 thorpej
2171 1.44 thorpej s = splbio();
2172 1.96 bouyer if (adapt->adapt_refcnt-- == 1 &&
2173 1.96 bouyer adapt->adapt_enable != NULL)
2174 1.96 bouyer (void) (*adapt->adapt_enable)(&wdc->sc_dev, 0);
2175 1.44 thorpej splx(s);
2176 1.93 wrstuden }
2177 1.93 wrstuden
2178 1.93 wrstuden void
2179 1.93 wrstuden wdc_print_modes(struct channel_softc *chp)
2180 1.93 wrstuden {
2181 1.93 wrstuden int drive;
2182 1.93 wrstuden struct ata_drive_datas *drvp;
2183 1.93 wrstuden
2184 1.93 wrstuden for (drive = 0; drive < 2; drive++) {
2185 1.93 wrstuden drvp = &chp->ch_drive[drive];
2186 1.93 wrstuden if ((drvp->drive_flags & DRIVE) == 0)
2187 1.93 wrstuden continue;
2188 1.123 thorpej aprint_normal("%s(%s:%d:%d): using PIO mode %d",
2189 1.93 wrstuden drvp->drv_softc->dv_xname,
2190 1.93 wrstuden chp->wdc->sc_dev.dv_xname,
2191 1.93 wrstuden chp->channel, drive, drvp->PIO_mode);
2192 1.93 wrstuden if (drvp->drive_flags & DRIVE_DMA)
2193 1.123 thorpej aprint_normal(", DMA mode %d", drvp->DMA_mode);
2194 1.93 wrstuden if (drvp->drive_flags & DRIVE_UDMA) {
2195 1.123 thorpej aprint_normal(", Ultra-DMA mode %d", drvp->UDMA_mode);
2196 1.93 wrstuden if (drvp->UDMA_mode == 2)
2197 1.123 thorpej aprint_normal(" (Ultra/33)");
2198 1.93 wrstuden else if (drvp->UDMA_mode == 4)
2199 1.123 thorpej aprint_normal(" (Ultra/66)");
2200 1.93 wrstuden else if (drvp->UDMA_mode == 5)
2201 1.123 thorpej aprint_normal(" (Ultra/100)");
2202 1.123 thorpej else if (drvp->UDMA_mode == 6)
2203 1.123 thorpej aprint_normal(" (Ultra/133)");
2204 1.93 wrstuden }
2205 1.93 wrstuden if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA))
2206 1.123 thorpej aprint_normal(" (using DMA data transfers)");
2207 1.123 thorpej aprint_normal("\n");
2208 1.93 wrstuden }
2209 1.2 bouyer }
2210