wdc.c revision 1.126 1 1.126 enami /* $NetBSD: wdc.c,v 1.126 2003/09/20 02:19:36 enami Exp $ */
2 1.31 bouyer
3 1.31 bouyer /*
4 1.104 bouyer * Copyright (c) 1998, 2001 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.126 enami __KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.126 2003/09/20 02:19:36 enami 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.2 bouyer #include <sys/conf.h>
83 1.2 bouyer #include <sys/buf.h>
84 1.31 bouyer #include <sys/device.h>
85 1.2 bouyer #include <sys/malloc.h>
86 1.71 bouyer #include <sys/pool.h>
87 1.2 bouyer #include <sys/syslog.h>
88 1.2 bouyer #include <sys/proc.h>
89 1.2 bouyer
90 1.2 bouyer #include <machine/intr.h>
91 1.2 bouyer #include <machine/bus.h>
92 1.2 bouyer
93 1.17 sakamoto #ifndef __BUS_SPACE_HAS_STREAM_METHODS
94 1.31 bouyer #define bus_space_write_multi_stream_2 bus_space_write_multi_2
95 1.31 bouyer #define bus_space_write_multi_stream_4 bus_space_write_multi_4
96 1.31 bouyer #define bus_space_read_multi_stream_2 bus_space_read_multi_2
97 1.31 bouyer #define bus_space_read_multi_stream_4 bus_space_read_multi_4
98 1.17 sakamoto #endif /* __BUS_SPACE_HAS_STREAM_METHODS */
99 1.16 sakamoto
100 1.103 bouyer #include <dev/ata/atavar.h>
101 1.102 bouyer #include <dev/ata/wdvar.h>
102 1.31 bouyer #include <dev/ata/atareg.h>
103 1.12 cgd #include <dev/ic/wdcreg.h>
104 1.12 cgd #include <dev/ic/wdcvar.h>
105 1.31 bouyer
106 1.122 thorpej #include "ataraid.h"
107 1.2 bouyer #include "atapibus.h"
108 1.106 bouyer #include "wd.h"
109 1.2 bouyer
110 1.122 thorpej #if NATARAID > 0
111 1.122 thorpej #include <dev/ata/ata_raidvar.h>
112 1.122 thorpej #endif
113 1.122 thorpej
114 1.31 bouyer #define WDCDELAY 100 /* 100 microseconds */
115 1.31 bouyer #define WDCNDELAY_RST (WDC_RESET_WAIT * 1000 / WDCDELAY)
116 1.2 bouyer #if 0
117 1.31 bouyer /* If you enable this, it will report any delays more than WDCDELAY * N long. */
118 1.2 bouyer #define WDCNDELAY_DEBUG 50
119 1.2 bouyer #endif
120 1.2 bouyer
121 1.71 bouyer struct pool wdc_xfer_pool;
122 1.2 bouyer
123 1.106 bouyer #if NWD > 0
124 1.103 bouyer extern const struct ata_bustype wdc_ata_bustype; /* in ata_wdc.c */
125 1.106 bouyer #else
126 1.106 bouyer /* A fake one, the autoconfig will print "wd at foo ... not configured */
127 1.106 bouyer const struct ata_bustype wdc_ata_bustype = {
128 1.106 bouyer SCSIPI_BUSTYPE_ATA,
129 1.106 bouyer NULL,
130 1.106 bouyer NULL,
131 1.106 bouyer NULL,
132 1.106 bouyer NULL,
133 1.106 bouyer NULL,
134 1.106 bouyer NULL,
135 1.106 bouyer NULL
136 1.106 bouyer };
137 1.106 bouyer #endif
138 1.102 bouyer
139 1.31 bouyer static void __wdcerror __P((struct channel_softc*, char *));
140 1.31 bouyer static int __wdcwait_reset __P((struct channel_softc *, int));
141 1.31 bouyer void __wdccommand_done __P((struct channel_softc *, struct wdc_xfer *));
142 1.31 bouyer void __wdccommand_start __P((struct channel_softc *, struct wdc_xfer *));
143 1.66 bouyer int __wdccommand_intr __P((struct channel_softc *, struct wdc_xfer *, int));
144 1.31 bouyer int wdprint __P((void *, const char *));
145 1.125 mycroft void wdc_channel_attach __P((struct channel_softc *));
146 1.31 bouyer
147 1.31 bouyer #define DEBUG_INTR 0x01
148 1.31 bouyer #define DEBUG_XFERS 0x02
149 1.31 bouyer #define DEBUG_STATUS 0x04
150 1.31 bouyer #define DEBUG_FUNCS 0x08
151 1.31 bouyer #define DEBUG_PROBE 0x10
152 1.74 enami #define DEBUG_DETACH 0x20
153 1.87 bouyer #define DEBUG_DELAY 0x40
154 1.31 bouyer #ifdef WDCDEBUG
155 1.32 bouyer int wdcdebug_mask = 0;
156 1.31 bouyer int wdc_nxfer = 0;
157 1.31 bouyer #define WDCDEBUG_PRINT(args, level) if (wdcdebug_mask & (level)) printf args
158 1.2 bouyer #else
159 1.31 bouyer #define WDCDEBUG_PRINT(args, level)
160 1.2 bouyer #endif
161 1.2 bouyer
162 1.31 bouyer int
163 1.31 bouyer wdprint(aux, pnp)
164 1.31 bouyer void *aux;
165 1.31 bouyer const char *pnp;
166 1.31 bouyer {
167 1.102 bouyer struct ata_device *adev = aux;
168 1.31 bouyer if (pnp)
169 1.120 thorpej aprint_normal("wd at %s", pnp);
170 1.120 thorpej aprint_normal(" channel %d drive %d", adev->adev_channel,
171 1.102 bouyer adev->adev_drv_data->drive);
172 1.31 bouyer return (UNCONF);
173 1.31 bouyer }
174 1.31 bouyer
175 1.31 bouyer /* Test to see controller with at last one attached drive is there.
176 1.31 bouyer * Returns a bit for each possible drive found (0x01 for drive 0,
177 1.31 bouyer * 0x02 for drive 1).
178 1.31 bouyer * Logic:
179 1.31 bouyer * - If a status register is at 0xff, assume there is no drive here
180 1.97 bjh21 * (ISA has pull-up resistors). Similarly if the status register has
181 1.97 bjh21 * the value we last wrote to the bus (for IDE interfaces without pullups).
182 1.97 bjh21 * If no drive at all -> return.
183 1.31 bouyer * - reset the controller, wait for it to complete (may take up to 31s !).
184 1.31 bouyer * If timeout -> return.
185 1.31 bouyer * - test ATA/ATAPI signatures. If at last one drive found -> return.
186 1.31 bouyer * - try an ATA command on the master.
187 1.12 cgd */
188 1.31 bouyer
189 1.2 bouyer int
190 1.31 bouyer wdcprobe(chp)
191 1.31 bouyer struct channel_softc *chp;
192 1.12 cgd {
193 1.31 bouyer u_int8_t st0, st1, sc, sn, cl, ch;
194 1.31 bouyer u_int8_t ret_value = 0x03;
195 1.31 bouyer u_int8_t drive;
196 1.31 bouyer
197 1.31 bouyer /*
198 1.31 bouyer * Sanity check to see if the wdc channel responds at all.
199 1.31 bouyer */
200 1.31 bouyer
201 1.43 kenh if (chp->wdc == NULL ||
202 1.43 kenh (chp->wdc->cap & WDC_CAPABILITY_NO_EXTRA_RESETS) == 0) {
203 1.107 dbj
204 1.107 dbj if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
205 1.107 dbj chp->wdc->select(chp,0);
206 1.43 kenh bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
207 1.43 kenh WDSD_IBM);
208 1.65 bouyer delay(10);
209 1.43 kenh st0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
210 1.107 dbj
211 1.107 dbj if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
212 1.107 dbj chp->wdc->select(chp,1);
213 1.43 kenh bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
214 1.43 kenh WDSD_IBM | 0x10);
215 1.65 bouyer delay(10);
216 1.43 kenh st1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
217 1.43 kenh
218 1.43 kenh WDCDEBUG_PRINT(("%s:%d: before reset, st0=0x%x, st1=0x%x\n",
219 1.43 kenh chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
220 1.43 kenh chp->channel, st0, st1), DEBUG_PROBE);
221 1.43 kenh
222 1.125 mycroft if ((st0 & 0x7f) == 0x7f || st0 == WDSD_IBM)
223 1.43 kenh ret_value &= ~0x01;
224 1.125 mycroft if ((st1 & 0x7f) == 0x7f || st1 == (WDSD_IBM | 0x10))
225 1.43 kenh ret_value &= ~0x02;
226 1.125 mycroft
227 1.125 mycroft /* Register writability test, drive 0. */
228 1.125 mycroft if (ret_value & 0x01) {
229 1.125 mycroft if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
230 1.125 mycroft chp->wdc->select(chp,0);
231 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
232 1.125 mycroft WDSD_IBM);
233 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo,
234 1.125 mycroft 0x01);
235 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
236 1.125 mycroft wd_cyl_lo) != 0x01)
237 1.125 mycroft ret_value &= ~0x01;
238 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo,
239 1.125 mycroft 0x02);
240 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
241 1.125 mycroft wd_cyl_lo) != 0x02)
242 1.125 mycroft ret_value &= ~0x01;
243 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sector,
244 1.125 mycroft 0x01);
245 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
246 1.125 mycroft wd_sector) != 0x01)
247 1.125 mycroft ret_value &= ~0x01;
248 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sector,
249 1.125 mycroft 0x02);
250 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
251 1.125 mycroft wd_sector) != 0x02)
252 1.125 mycroft ret_value &= ~0x01;
253 1.125 mycroft }
254 1.125 mycroft
255 1.125 mycroft /* Register writability test, drive 1. */
256 1.125 mycroft if (ret_value & 0x02) {
257 1.125 mycroft if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
258 1.125 mycroft chp->wdc->select(chp,1);
259 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
260 1.125 mycroft WDSD_IBM | 0x10);
261 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo,
262 1.125 mycroft 0x01);
263 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
264 1.125 mycroft wd_cyl_lo) != 0x01)
265 1.125 mycroft ret_value &= ~0x02;
266 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo,
267 1.125 mycroft 0x02);
268 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
269 1.125 mycroft wd_cyl_lo) != 0x02)
270 1.125 mycroft ret_value &= ~0x02;
271 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sector,
272 1.125 mycroft 0x01);
273 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
274 1.125 mycroft wd_sector) != 0x01)
275 1.125 mycroft ret_value &= ~0x02;
276 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sector,
277 1.125 mycroft 0x02);
278 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
279 1.125 mycroft wd_sector) != 0x02)
280 1.125 mycroft ret_value &= ~0x02;
281 1.125 mycroft }
282 1.125 mycroft
283 1.125 mycroft /* Register ghost test. */
284 1.125 mycroft if (ret_value == 0x03) {
285 1.125 mycroft if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
286 1.125 mycroft chp->wdc->select(chp,1);
287 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
288 1.125 mycroft WDSD_IBM | 0x10);
289 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sector, 0x01);
290 1.125 mycroft if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
291 1.125 mycroft chp->wdc->select(chp,0);
292 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
293 1.125 mycroft WDSD_IBM);
294 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sector, 0x02);
295 1.125 mycroft if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
296 1.125 mycroft chp->wdc->select(chp,1);
297 1.125 mycroft bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
298 1.125 mycroft WDSD_IBM | 0x10);
299 1.125 mycroft if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_sector) == 0x02) {
300 1.125 mycroft printf("ghost detected\n");
301 1.125 mycroft ret_value = 0x01;
302 1.125 mycroft }
303 1.125 mycroft }
304 1.125 mycroft
305 1.43 kenh if (ret_value == 0)
306 1.43 kenh return 0;
307 1.125 mycroft
308 1.43 kenh }
309 1.42 thorpej
310 1.107 dbj if (chp->wdc && (chp->wdc->cap & WDC_CAPABILITY_SELECT))
311 1.107 dbj chp->wdc->select(chp,0);
312 1.31 bouyer /* assert SRST, wait for reset to complete */
313 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
314 1.31 bouyer WDSD_IBM);
315 1.65 bouyer delay(10);
316 1.31 bouyer bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
317 1.31 bouyer WDCTL_RST | WDCTL_IDS);
318 1.31 bouyer DELAY(1000);
319 1.31 bouyer bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
320 1.31 bouyer WDCTL_IDS);
321 1.31 bouyer delay(1000);
322 1.31 bouyer (void) bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_error);
323 1.31 bouyer bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
324 1.65 bouyer delay(10);
325 1.31 bouyer
326 1.31 bouyer ret_value = __wdcwait_reset(chp, ret_value);
327 1.31 bouyer WDCDEBUG_PRINT(("%s:%d: after reset, ret_value=0x%d\n",
328 1.31 bouyer chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", chp->channel,
329 1.31 bouyer ret_value), DEBUG_PROBE);
330 1.26 drochner
331 1.31 bouyer /* if reset failed, there's nothing here */
332 1.31 bouyer if (ret_value == 0)
333 1.31 bouyer return 0;
334 1.2 bouyer
335 1.31 bouyer /*
336 1.31 bouyer * Test presence of drives. First test register signatures looking for
337 1.67 bouyer * ATAPI devices. If it's not an ATAPI and reset said there may be
338 1.67 bouyer * something here assume it's ATA or OLD. Ghost will be killed later in
339 1.67 bouyer * attach routine.
340 1.31 bouyer */
341 1.31 bouyer for (drive = 0; drive < 2; drive++) {
342 1.31 bouyer if ((ret_value & (0x01 << drive)) == 0)
343 1.31 bouyer continue;
344 1.109 bouyer if (chp->wdc && chp->wdc->cap & WDC_CAPABILITY_SELECT)
345 1.107 dbj chp->wdc->select(chp,drive);
346 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
347 1.31 bouyer WDSD_IBM | (drive << 4));
348 1.65 bouyer delay(10);
349 1.31 bouyer /* Save registers contents */
350 1.31 bouyer sc = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt);
351 1.31 bouyer sn = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_sector);
352 1.31 bouyer cl = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo);
353 1.31 bouyer ch = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_hi);
354 1.31 bouyer
355 1.31 bouyer WDCDEBUG_PRINT(("%s:%d:%d: after reset, sc=0x%x sn=0x%x "
356 1.31 bouyer "cl=0x%x ch=0x%x\n",
357 1.31 bouyer chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
358 1.31 bouyer chp->channel, drive, sc, sn, cl, ch), DEBUG_PROBE);
359 1.57 bouyer /*
360 1.90 bouyer * sc & sn are supposted to be 0x1 for ATAPI but in some cases
361 1.90 bouyer * we get wrong values here, so ignore it.
362 1.57 bouyer */
363 1.90 bouyer if (cl == 0x14 && ch == 0xeb) {
364 1.31 bouyer chp->ch_drive[drive].drive_flags |= DRIVE_ATAPI;
365 1.67 bouyer } else {
366 1.62 bouyer chp->ch_drive[drive].drive_flags |= DRIVE_ATA;
367 1.67 bouyer if (chp->wdc == NULL ||
368 1.67 bouyer (chp->wdc->cap & WDC_CAPABILITY_PREATA) != 0)
369 1.67 bouyer chp->ch_drive[drive].drive_flags |= DRIVE_OLD;
370 1.2 bouyer }
371 1.7 bouyer }
372 1.31 bouyer return (ret_value);
373 1.31 bouyer }
374 1.31 bouyer
375 1.31 bouyer void
376 1.125 mycroft wdcattach(self)
377 1.125 mycroft struct device *self;
378 1.125 mycroft {
379 1.125 mycroft struct wdc_softc *wdc = (void *)self;
380 1.125 mycroft int i;
381 1.125 mycroft
382 1.125 mycroft for (i = 0; i < wdc->nchannels; i++)
383 1.125 mycroft wdc_channel_attach(wdc->channels[i]);
384 1.125 mycroft }
385 1.125 mycroft
386 1.125 mycroft void
387 1.125 mycroft wdc_channel_attach(chp)
388 1.31 bouyer struct channel_softc *chp;
389 1.31 bouyer {
390 1.121 simonb int ctrl_flags, i, error;
391 1.62 bouyer struct ataparams params;
392 1.62 bouyer static int inited = 0;
393 1.31 bouyer
394 1.125 mycroft if (chp->ch_flags & WDCF_DISABLED)
395 1.125 mycroft return;
396 1.125 mycroft
397 1.81 thorpej callout_init(&chp->ch_callout);
398 1.81 thorpej
399 1.44 thorpej if ((error = wdc_addref(chp)) != 0) {
400 1.123 thorpej aprint_error("%s: unable to enable controller\n",
401 1.44 thorpej chp->wdc->sc_dev.dv_xname);
402 1.44 thorpej return;
403 1.44 thorpej }
404 1.44 thorpej
405 1.74 enami if (wdcprobe(chp) == 0)
406 1.44 thorpej /* If no drives, abort attach here. */
407 1.74 enami goto out;
408 1.31 bouyer
409 1.71 bouyer /* initialise global data */
410 1.62 bouyer if (inited == 0) {
411 1.71 bouyer /* Initialize the wdc_xfer pool. */
412 1.71 bouyer pool_init(&wdc_xfer_pool, sizeof(struct wdc_xfer), 0,
413 1.112 thorpej 0, 0, "wdcspl", NULL);
414 1.62 bouyer inited++;
415 1.62 bouyer }
416 1.31 bouyer TAILQ_INIT(&chp->ch_queue->sc_xfer);
417 1.62 bouyer
418 1.62 bouyer for (i = 0; i < 2; i++) {
419 1.62 bouyer chp->ch_drive[i].chnl_softc = chp;
420 1.62 bouyer chp->ch_drive[i].drive = i;
421 1.78 bouyer /*
422 1.78 bouyer * Init error counter so that an error withing the first xfers
423 1.78 bouyer * will trigger a downgrade
424 1.78 bouyer */
425 1.78 bouyer chp->ch_drive[i].n_dmaerrs = NERRS_MAX-1;
426 1.78 bouyer
427 1.62 bouyer /* If controller can't do 16bit flag the drives as 32bit */
428 1.62 bouyer if ((chp->wdc->cap &
429 1.62 bouyer (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
430 1.62 bouyer WDC_CAPABILITY_DATA32)
431 1.62 bouyer chp->ch_drive[i].drive_flags |= DRIVE_CAP32;
432 1.67 bouyer if ((chp->ch_drive[i].drive_flags & DRIVE) == 0)
433 1.67 bouyer continue;
434 1.62 bouyer
435 1.79 bouyer /*
436 1.79 bouyer * Wait a bit, some devices are weird just after a reset.
437 1.79 bouyer * Then issue a IDENTIFY command, to try to detect slave ghost
438 1.79 bouyer */
439 1.115 bouyer delay(5000);
440 1.125 mycroft error = ata_get_params(&chp->ch_drive[i], AT_WAIT, ¶ms);
441 1.86 bouyer if (error != CMD_OK) {
442 1.86 bouyer delay(1000000);
443 1.125 mycroft error = ata_get_params(&chp->ch_drive[i], AT_WAIT,
444 1.86 bouyer ¶ms);
445 1.86 bouyer }
446 1.77 bouyer if (error == CMD_OK) {
447 1.67 bouyer /* If IDENTIFY succeded, this is not an OLD ctrl */
448 1.67 bouyer chp->ch_drive[0].drive_flags &= ~DRIVE_OLD;
449 1.67 bouyer chp->ch_drive[1].drive_flags &= ~DRIVE_OLD;
450 1.67 bouyer } else {
451 1.62 bouyer chp->ch_drive[i].drive_flags &=
452 1.62 bouyer ~(DRIVE_ATA | DRIVE_ATAPI);
453 1.77 bouyer WDCDEBUG_PRINT(("%s:%d:%d: IDENTIFY failed (%d)\n",
454 1.67 bouyer chp->wdc->sc_dev.dv_xname,
455 1.77 bouyer chp->channel, i, error), DEBUG_PROBE);
456 1.67 bouyer if ((chp->ch_drive[i].drive_flags & DRIVE_OLD) == 0)
457 1.67 bouyer continue;
458 1.68 bouyer /*
459 1.68 bouyer * Pre-ATA drive ?
460 1.68 bouyer * Test registers writability (Error register not
461 1.68 bouyer * writable, but cyllo is), then try an ATA command.
462 1.68 bouyer */
463 1.107 dbj if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
464 1.107 dbj chp->wdc->select(chp,i);
465 1.68 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
466 1.68 bouyer WDSD_IBM | (i << 4));
467 1.68 bouyer delay(10);
468 1.68 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
469 1.68 bouyer wd_error, 0x58);
470 1.68 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
471 1.68 bouyer wd_cyl_lo, 0xa5);
472 1.68 bouyer if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
473 1.68 bouyer wd_error == 0x58) ||
474 1.68 bouyer bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
475 1.68 bouyer wd_cyl_lo) != 0xa5) {
476 1.68 bouyer WDCDEBUG_PRINT(("%s:%d:%d: register "
477 1.68 bouyer "writability failed\n",
478 1.68 bouyer chp->wdc->sc_dev.dv_xname,
479 1.68 bouyer chp->channel, i), DEBUG_PROBE);
480 1.68 bouyer chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
481 1.68 bouyer }
482 1.107 dbj if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
483 1.107 dbj chp->wdc->select(chp,i);
484 1.67 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
485 1.67 bouyer WDSD_IBM | (i << 4));
486 1.67 bouyer delay(100);
487 1.67 bouyer if (wait_for_ready(chp, 10000) != 0) {
488 1.67 bouyer WDCDEBUG_PRINT(("%s:%d:%d: not ready\n",
489 1.67 bouyer chp->wdc->sc_dev.dv_xname,
490 1.67 bouyer chp->channel, i), DEBUG_PROBE);
491 1.67 bouyer chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
492 1.67 bouyer continue;
493 1.67 bouyer }
494 1.67 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
495 1.67 bouyer wd_command, WDCC_RECAL);
496 1.67 bouyer if (wait_for_ready(chp, 10000) != 0) {
497 1.67 bouyer WDCDEBUG_PRINT(("%s:%d:%d: WDCC_RECAL failed\n",
498 1.67 bouyer chp->wdc->sc_dev.dv_xname,
499 1.67 bouyer chp->channel, i), DEBUG_PROBE);
500 1.67 bouyer chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
501 1.67 bouyer }
502 1.62 bouyer }
503 1.62 bouyer }
504 1.31 bouyer ctrl_flags = chp->wdc->sc_dev.dv_cfdata->cf_flags;
505 1.31 bouyer
506 1.31 bouyer WDCDEBUG_PRINT(("wdcattach: ch_drive_flags 0x%x 0x%x\n",
507 1.31 bouyer chp->ch_drive[0].drive_flags, chp->ch_drive[1].drive_flags),
508 1.31 bouyer DEBUG_PROBE);
509 1.12 cgd
510 1.67 bouyer /* If no drives, abort here */
511 1.67 bouyer if ((chp->ch_drive[0].drive_flags & DRIVE) == 0 &&
512 1.67 bouyer (chp->ch_drive[1].drive_flags & DRIVE) == 0)
513 1.74 enami goto out;
514 1.67 bouyer
515 1.12 cgd /*
516 1.31 bouyer * Attach an ATAPI bus, if needed.
517 1.12 cgd */
518 1.31 bouyer if ((chp->ch_drive[0].drive_flags & DRIVE_ATAPI) ||
519 1.31 bouyer (chp->ch_drive[1].drive_flags & DRIVE_ATAPI)) {
520 1.31 bouyer #if NATAPIBUS > 0
521 1.31 bouyer wdc_atapibus_attach(chp);
522 1.31 bouyer #else
523 1.31 bouyer /*
524 1.102 bouyer * Fake the autoconfig "not configured" message
525 1.31 bouyer */
526 1.123 thorpej aprint_normal("atapibus at %s channel %d not configured\n",
527 1.102 bouyer chp->wdc->sc_dev.dv_xname, chp->channel);
528 1.102 bouyer chp->atapibus = NULL;
529 1.31 bouyer #endif
530 1.31 bouyer }
531 1.31 bouyer
532 1.31 bouyer for (i = 0; i < 2; i++) {
533 1.102 bouyer struct ata_device adev;
534 1.67 bouyer if ((chp->ch_drive[i].drive_flags &
535 1.67 bouyer (DRIVE_ATA | DRIVE_OLD)) == 0) {
536 1.31 bouyer continue;
537 1.31 bouyer }
538 1.102 bouyer memset(&adev, 0, sizeof(struct ata_device));
539 1.102 bouyer adev.adev_bustype = &wdc_ata_bustype;
540 1.102 bouyer adev.adev_channel = chp->channel;
541 1.102 bouyer adev.adev_openings = 1;
542 1.102 bouyer adev.adev_drv_data = &chp->ch_drive[i];
543 1.122 thorpej chp->ata_drives[i] = config_found(&chp->wdc->sc_dev,
544 1.122 thorpej &adev, wdprint);
545 1.126 enami if (chp->ata_drives[i] != NULL)
546 1.31 bouyer wdc_probe_caps(&chp->ch_drive[i]);
547 1.32 bouyer }
548 1.32 bouyer
549 1.32 bouyer /*
550 1.32 bouyer * reset drive_flags for unnatached devices, reset state for attached
551 1.32 bouyer * ones
552 1.32 bouyer */
553 1.32 bouyer for (i = 0; i < 2; i++) {
554 1.32 bouyer if (chp->ch_drive[i].drv_softc == NULL)
555 1.32 bouyer chp->ch_drive[i].drive_flags = 0;
556 1.32 bouyer else
557 1.32 bouyer chp->ch_drive[i].state = 0;
558 1.2 bouyer }
559 1.12 cgd
560 1.12 cgd /*
561 1.31 bouyer * Reset channel. The probe, with some combinations of ATA/ATAPI
562 1.31 bouyer * devices keep it in a mostly working, but strange state (with busy
563 1.31 bouyer * led on)
564 1.12 cgd */
565 1.31 bouyer if ((chp->wdc->cap & WDC_CAPABILITY_NO_EXTRA_RESETS) == 0) {
566 1.95 bouyer delay(50);
567 1.31 bouyer wdcreset(chp, VERBOSE);
568 1.31 bouyer /*
569 1.31 bouyer * Read status registers to avoid spurious interrupts.
570 1.31 bouyer */
571 1.31 bouyer for (i = 1; i >= 0; i--) {
572 1.31 bouyer if (chp->ch_drive[i].drive_flags & DRIVE) {
573 1.107 dbj if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
574 1.107 dbj chp->wdc->select(chp,i);
575 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
576 1.31 bouyer wd_sdh, WDSD_IBM | (i << 4));
577 1.31 bouyer if (wait_for_unbusy(chp, 10000) < 0)
578 1.123 thorpej aprint_error("%s:%d:%d: device busy\n",
579 1.31 bouyer chp->wdc->sc_dev.dv_xname,
580 1.31 bouyer chp->channel, i);
581 1.31 bouyer }
582 1.31 bouyer }
583 1.31 bouyer }
584 1.74 enami
585 1.125 mycroft if (chp->wdc->cap & WDC_CAPABILITY_MODE)
586 1.125 mycroft chp->wdc->set_modes(chp);
587 1.125 mycroft wdc_print_modes(chp);
588 1.126 enami
589 1.126 enami #if NATARAID > 0
590 1.126 enami if (chp->wdc->cap & WDC_CAPABILITY_RAID)
591 1.126 enami for (i = 0; i < 2; i++)
592 1.126 enami if (chp->ata_drives[i] != NULL)
593 1.126 enami ata_raid_check_component(chp->ata_drives[i]);
594 1.126 enami #endif /* NATARAID > 0 */
595 1.125 mycroft
596 1.74 enami out:
597 1.44 thorpej wdc_delref(chp);
598 1.74 enami }
599 1.74 enami
600 1.74 enami /*
601 1.74 enami * Call activate routine of underlying devices.
602 1.74 enami */
603 1.74 enami int
604 1.74 enami wdcactivate(self, act)
605 1.74 enami struct device *self;
606 1.74 enami enum devact act;
607 1.74 enami {
608 1.74 enami struct wdc_softc *wdc = (struct wdc_softc *)self;
609 1.74 enami struct channel_softc *chp;
610 1.88 mrg struct device *sc = 0;
611 1.74 enami int s, i, j, error = 0;
612 1.74 enami
613 1.74 enami s = splbio();
614 1.74 enami switch (act) {
615 1.74 enami case DVACT_ACTIVATE:
616 1.74 enami error = EOPNOTSUPP;
617 1.74 enami break;
618 1.74 enami
619 1.74 enami case DVACT_DEACTIVATE:
620 1.74 enami for (i = 0; i < wdc->nchannels; i++) {
621 1.74 enami chp = wdc->channels[i];
622 1.74 enami
623 1.74 enami /*
624 1.74 enami * We might call deactivate routine for
625 1.74 enami * the children of atapibus twice (once via
626 1.74 enami * atapibus, once directly), but since
627 1.74 enami * config_deactivate maintains DVF_ACTIVE flag,
628 1.74 enami * it's safe.
629 1.74 enami */
630 1.74 enami sc = chp->atapibus;
631 1.74 enami if (sc != NULL) {
632 1.74 enami error = config_deactivate(sc);
633 1.74 enami if (error != 0)
634 1.74 enami goto out;
635 1.74 enami }
636 1.74 enami
637 1.74 enami for (j = 0; j < 2; j++) {
638 1.74 enami sc = chp->ch_drive[j].drv_softc;
639 1.74 enami WDCDEBUG_PRINT(("wdcactivate: %s:"
640 1.74 enami " deactivating %s\n", wdc->sc_dev.dv_xname,
641 1.74 enami sc == NULL ? "nodrv" : sc->dv_xname),
642 1.74 enami DEBUG_DETACH);
643 1.74 enami if (sc != NULL) {
644 1.74 enami error = config_deactivate(sc);
645 1.74 enami if (error != 0)
646 1.74 enami goto out;
647 1.74 enami }
648 1.74 enami }
649 1.74 enami }
650 1.74 enami break;
651 1.74 enami }
652 1.74 enami
653 1.74 enami out:
654 1.74 enami splx(s);
655 1.74 enami
656 1.74 enami #ifdef WDCDEBUG
657 1.88 mrg if (sc && error != 0)
658 1.74 enami WDCDEBUG_PRINT(("wdcactivate: %s: error %d deactivating %s\n",
659 1.74 enami wdc->sc_dev.dv_xname, error, sc->dv_xname), DEBUG_DETACH);
660 1.74 enami #endif
661 1.74 enami return (error);
662 1.74 enami }
663 1.74 enami
664 1.74 enami int
665 1.74 enami wdcdetach(self, flags)
666 1.74 enami struct device *self;
667 1.74 enami int flags;
668 1.74 enami {
669 1.74 enami struct wdc_softc *wdc = (struct wdc_softc *)self;
670 1.74 enami struct channel_softc *chp;
671 1.88 mrg struct device *sc = 0;
672 1.74 enami int i, j, error = 0;
673 1.74 enami
674 1.74 enami for (i = 0; i < wdc->nchannels; i++) {
675 1.74 enami chp = wdc->channels[i];
676 1.74 enami
677 1.74 enami /*
678 1.74 enami * Detach atapibus and its children.
679 1.74 enami */
680 1.74 enami sc = chp->atapibus;
681 1.74 enami if (sc != NULL) {
682 1.74 enami WDCDEBUG_PRINT(("wdcdetach: %s: detaching %s\n",
683 1.74 enami wdc->sc_dev.dv_xname, sc->dv_xname), DEBUG_DETACH);
684 1.74 enami error = config_detach(sc, flags);
685 1.74 enami if (error != 0)
686 1.74 enami goto out;
687 1.74 enami }
688 1.74 enami
689 1.74 enami /*
690 1.74 enami * Detach our other children.
691 1.74 enami */
692 1.74 enami for (j = 0; j < 2; j++) {
693 1.102 bouyer if (chp->ch_drive[j].drive_flags & DRIVE_ATAPI)
694 1.102 bouyer continue;
695 1.74 enami sc = chp->ch_drive[j].drv_softc;
696 1.74 enami WDCDEBUG_PRINT(("wdcdetach: %s: detaching %s\n",
697 1.74 enami wdc->sc_dev.dv_xname,
698 1.74 enami sc == NULL ? "nodrv" : sc->dv_xname),
699 1.74 enami DEBUG_DETACH);
700 1.74 enami if (sc != NULL) {
701 1.74 enami error = config_detach(sc, flags);
702 1.74 enami if (error != 0)
703 1.74 enami goto out;
704 1.74 enami }
705 1.74 enami }
706 1.75 enami
707 1.75 enami wdc_kill_pending(chp);
708 1.74 enami }
709 1.74 enami
710 1.74 enami out:
711 1.74 enami #ifdef WDCDEBUG
712 1.88 mrg if (sc && error != 0)
713 1.74 enami WDCDEBUG_PRINT(("wdcdetach: %s: error %d detaching %s\n",
714 1.74 enami wdc->sc_dev.dv_xname, error, sc->dv_xname), DEBUG_DETACH);
715 1.74 enami #endif
716 1.74 enami return (error);
717 1.31 bouyer }
718 1.31 bouyer
719 1.31 bouyer /*
720 1.31 bouyer * Start I/O on a controller, for the given channel.
721 1.31 bouyer * The first xfer may be not for our channel if the channel queues
722 1.31 bouyer * are shared.
723 1.31 bouyer */
724 1.31 bouyer void
725 1.45 drochner wdcstart(chp)
726 1.45 drochner struct channel_softc *chp;
727 1.31 bouyer {
728 1.31 bouyer struct wdc_xfer *xfer;
729 1.38 bouyer
730 1.38 bouyer #ifdef WDC_DIAGNOSTIC
731 1.38 bouyer int spl1, spl2;
732 1.38 bouyer
733 1.38 bouyer spl1 = splbio();
734 1.38 bouyer spl2 = splbio();
735 1.38 bouyer if (spl2 != spl1) {
736 1.38 bouyer printf("wdcstart: not at splbio()\n");
737 1.38 bouyer panic("wdcstart");
738 1.38 bouyer }
739 1.38 bouyer splx(spl2);
740 1.38 bouyer splx(spl1);
741 1.38 bouyer #endif /* WDC_DIAGNOSTIC */
742 1.12 cgd
743 1.31 bouyer /* is there a xfer ? */
744 1.45 drochner if ((xfer = chp->ch_queue->sc_xfer.tqh_first) == NULL)
745 1.31 bouyer return;
746 1.47 bouyer
747 1.47 bouyer /* adjust chp, in case we have a shared queue */
748 1.49 bouyer chp = xfer->chp;
749 1.47 bouyer
750 1.31 bouyer if ((chp->ch_flags & WDCF_ACTIVE) != 0 ) {
751 1.31 bouyer return; /* channel aleady active */
752 1.31 bouyer }
753 1.31 bouyer #ifdef DIAGNOSTIC
754 1.31 bouyer if ((chp->ch_flags & WDCF_IRQ_WAIT) != 0)
755 1.118 provos panic("wdcstart: channel waiting for irq");
756 1.31 bouyer #endif
757 1.45 drochner if (chp->wdc->cap & WDC_CAPABILITY_HWLOCK)
758 1.45 drochner if (!(*chp->wdc->claim_hw)(chp, 0))
759 1.31 bouyer return;
760 1.12 cgd
761 1.31 bouyer WDCDEBUG_PRINT(("wdcstart: xfer %p channel %d drive %d\n", xfer,
762 1.49 bouyer chp->channel, xfer->drive), DEBUG_XFERS);
763 1.31 bouyer chp->ch_flags |= WDCF_ACTIVE;
764 1.37 bouyer if (chp->ch_drive[xfer->drive].drive_flags & DRIVE_RESET) {
765 1.37 bouyer chp->ch_drive[xfer->drive].drive_flags &= ~DRIVE_RESET;
766 1.37 bouyer chp->ch_drive[xfer->drive].state = 0;
767 1.37 bouyer }
768 1.98 bjh21 if (chp->wdc->cap & WDC_CAPABILITY_NOIRQ)
769 1.98 bjh21 KASSERT(xfer->c_flags & C_POLL);
770 1.31 bouyer xfer->c_start(chp, xfer);
771 1.31 bouyer }
772 1.2 bouyer
773 1.31 bouyer /* restart an interrupted I/O */
774 1.31 bouyer void
775 1.31 bouyer wdcrestart(v)
776 1.31 bouyer void *v;
777 1.31 bouyer {
778 1.31 bouyer struct channel_softc *chp = v;
779 1.31 bouyer int s;
780 1.2 bouyer
781 1.31 bouyer s = splbio();
782 1.45 drochner wdcstart(chp);
783 1.31 bouyer splx(s);
784 1.2 bouyer }
785 1.31 bouyer
786 1.2 bouyer
787 1.31 bouyer /*
788 1.31 bouyer * Interrupt routine for the controller. Acknowledge the interrupt, check for
789 1.31 bouyer * errors on the current operation, mark it done if necessary, and start the
790 1.31 bouyer * next request. Also check for a partially done transfer, and continue with
791 1.31 bouyer * the next chunk if so.
792 1.31 bouyer */
793 1.12 cgd int
794 1.31 bouyer wdcintr(arg)
795 1.31 bouyer void *arg;
796 1.12 cgd {
797 1.31 bouyer struct channel_softc *chp = arg;
798 1.31 bouyer struct wdc_xfer *xfer;
799 1.76 bouyer int ret;
800 1.12 cgd
801 1.80 enami if ((chp->wdc->sc_dev.dv_flags & DVF_ACTIVE) == 0) {
802 1.80 enami WDCDEBUG_PRINT(("wdcintr: deactivated controller\n"),
803 1.80 enami DEBUG_INTR);
804 1.80 enami return (0);
805 1.80 enami }
806 1.31 bouyer if ((chp->ch_flags & WDCF_IRQ_WAIT) == 0) {
807 1.31 bouyer WDCDEBUG_PRINT(("wdcintr: inactive controller\n"), DEBUG_INTR);
808 1.113 bouyer /* try to clear the pending interrupt anyway */
809 1.113 bouyer (void)bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
810 1.80 enami return (0);
811 1.31 bouyer }
812 1.12 cgd
813 1.31 bouyer WDCDEBUG_PRINT(("wdcintr\n"), DEBUG_INTR);
814 1.84 bouyer xfer = chp->ch_queue->sc_xfer.tqh_first;
815 1.84 bouyer if (chp->ch_flags & WDCF_DMA_WAIT) {
816 1.84 bouyer chp->wdc->dma_status =
817 1.84 bouyer (*chp->wdc->dma_finish)(chp->wdc->dma_arg, chp->channel,
818 1.84 bouyer xfer->drive, 0);
819 1.84 bouyer if (chp->wdc->dma_status & WDC_DMAST_NOIRQ) {
820 1.84 bouyer /* IRQ not for us, not detected by DMA engine */
821 1.84 bouyer return 0;
822 1.84 bouyer }
823 1.84 bouyer chp->ch_flags &= ~WDCF_DMA_WAIT;
824 1.84 bouyer }
825 1.31 bouyer chp->ch_flags &= ~WDCF_IRQ_WAIT;
826 1.76 bouyer ret = xfer->c_intr(chp, xfer, 1);
827 1.76 bouyer if (ret == 0) /* irq was not for us, still waiting for irq */
828 1.76 bouyer chp->ch_flags |= WDCF_IRQ_WAIT;
829 1.76 bouyer return (ret);
830 1.12 cgd }
831 1.12 cgd
832 1.31 bouyer /* Put all disk in RESET state */
833 1.125 mycroft void
834 1.125 mycroft wdc_reset_channel(drvp)
835 1.31 bouyer struct ata_drive_datas *drvp;
836 1.2 bouyer {
837 1.31 bouyer struct channel_softc *chp = drvp->chnl_softc;
838 1.2 bouyer int drive;
839 1.34 bouyer WDCDEBUG_PRINT(("ata_reset_channel %s:%d for drive %d\n",
840 1.34 bouyer chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive),
841 1.34 bouyer DEBUG_FUNCS);
842 1.31 bouyer (void) wdcreset(chp, VERBOSE);
843 1.31 bouyer for (drive = 0; drive < 2; drive++) {
844 1.31 bouyer chp->ch_drive[drive].state = 0;
845 1.12 cgd }
846 1.31 bouyer }
847 1.12 cgd
848 1.31 bouyer int
849 1.31 bouyer wdcreset(chp, verb)
850 1.31 bouyer struct channel_softc *chp;
851 1.31 bouyer int verb;
852 1.31 bouyer {
853 1.31 bouyer int drv_mask1, drv_mask2;
854 1.2 bouyer
855 1.107 dbj if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
856 1.107 dbj chp->wdc->select(chp,0);
857 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
858 1.31 bouyer WDSD_IBM); /* master */
859 1.31 bouyer bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
860 1.31 bouyer WDCTL_RST | WDCTL_IDS);
861 1.31 bouyer delay(1000);
862 1.31 bouyer bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
863 1.31 bouyer WDCTL_IDS);
864 1.31 bouyer delay(1000);
865 1.31 bouyer (void) bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_error);
866 1.31 bouyer bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
867 1.31 bouyer WDCTL_4BIT);
868 1.2 bouyer
869 1.31 bouyer drv_mask1 = (chp->ch_drive[0].drive_flags & DRIVE) ? 0x01:0x00;
870 1.31 bouyer drv_mask1 |= (chp->ch_drive[1].drive_flags & DRIVE) ? 0x02:0x00;
871 1.31 bouyer drv_mask2 = __wdcwait_reset(chp, drv_mask1);
872 1.31 bouyer if (verb && drv_mask2 != drv_mask1) {
873 1.31 bouyer printf("%s channel %d: reset failed for",
874 1.31 bouyer chp->wdc->sc_dev.dv_xname, chp->channel);
875 1.31 bouyer if ((drv_mask1 & 0x01) != 0 && (drv_mask2 & 0x01) == 0)
876 1.31 bouyer printf(" drive 0");
877 1.31 bouyer if ((drv_mask1 & 0x02) != 0 && (drv_mask2 & 0x02) == 0)
878 1.31 bouyer printf(" drive 1");
879 1.31 bouyer printf("\n");
880 1.31 bouyer }
881 1.31 bouyer return (drv_mask1 != drv_mask2) ? 1 : 0;
882 1.31 bouyer }
883 1.31 bouyer
884 1.31 bouyer static int
885 1.31 bouyer __wdcwait_reset(chp, drv_mask)
886 1.31 bouyer struct channel_softc *chp;
887 1.31 bouyer int drv_mask;
888 1.31 bouyer {
889 1.31 bouyer int timeout;
890 1.31 bouyer u_int8_t st0, st1;
891 1.70 bouyer #ifdef WDCDEBUG
892 1.70 bouyer u_int8_t sc0, sn0, cl0, ch0;
893 1.70 bouyer u_int8_t sc1, sn1, cl1, ch1;
894 1.70 bouyer #endif
895 1.31 bouyer /* wait for BSY to deassert */
896 1.110 simonb for (timeout = 0; timeout < WDCNDELAY_RST; timeout++) {
897 1.109 bouyer if (chp->wdc && chp->wdc->cap & WDC_CAPABILITY_SELECT)
898 1.107 dbj chp->wdc->select(chp,0);
899 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
900 1.31 bouyer WDSD_IBM); /* master */
901 1.65 bouyer delay(10);
902 1.31 bouyer st0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
903 1.70 bouyer #ifdef WDCDEBUG
904 1.70 bouyer sc0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt);
905 1.70 bouyer sn0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_sector);
906 1.70 bouyer cl0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo);
907 1.70 bouyer ch0 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_hi);
908 1.70 bouyer #endif
909 1.109 bouyer if (chp->wdc && chp->wdc->cap & WDC_CAPABILITY_SELECT)
910 1.107 dbj chp->wdc->select(chp,1);
911 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
912 1.31 bouyer WDSD_IBM | 0x10); /* slave */
913 1.65 bouyer delay(10);
914 1.31 bouyer st1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
915 1.70 bouyer #ifdef WDCDEBUG
916 1.70 bouyer sc1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt);
917 1.70 bouyer sn1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_sector);
918 1.70 bouyer cl1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo);
919 1.70 bouyer ch1 = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_hi);
920 1.70 bouyer #endif
921 1.31 bouyer
922 1.31 bouyer if ((drv_mask & 0x01) == 0) {
923 1.31 bouyer /* no master */
924 1.31 bouyer if ((drv_mask & 0x02) != 0 && (st1 & WDCS_BSY) == 0) {
925 1.31 bouyer /* No master, slave is ready, it's done */
926 1.65 bouyer goto end;
927 1.31 bouyer }
928 1.31 bouyer } else if ((drv_mask & 0x02) == 0) {
929 1.31 bouyer /* no slave */
930 1.31 bouyer if ((drv_mask & 0x01) != 0 && (st0 & WDCS_BSY) == 0) {
931 1.31 bouyer /* No slave, master is ready, it's done */
932 1.65 bouyer goto end;
933 1.31 bouyer }
934 1.2 bouyer } else {
935 1.31 bouyer /* Wait for both master and slave to be ready */
936 1.31 bouyer if ((st0 & WDCS_BSY) == 0 && (st1 & WDCS_BSY) == 0) {
937 1.65 bouyer goto end;
938 1.2 bouyer }
939 1.2 bouyer }
940 1.31 bouyer delay(WDCDELAY);
941 1.2 bouyer }
942 1.116 wiz /* Reset timed out. Maybe it's because drv_mask was not right */
943 1.31 bouyer if (st0 & WDCS_BSY)
944 1.31 bouyer drv_mask &= ~0x01;
945 1.31 bouyer if (st1 & WDCS_BSY)
946 1.31 bouyer drv_mask &= ~0x02;
947 1.65 bouyer end:
948 1.70 bouyer WDCDEBUG_PRINT(("%s:%d:0: after reset, sc=0x%x sn=0x%x "
949 1.70 bouyer "cl=0x%x ch=0x%x\n",
950 1.70 bouyer chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
951 1.70 bouyer chp->channel, sc0, sn0, cl0, ch0), DEBUG_PROBE);
952 1.70 bouyer WDCDEBUG_PRINT(("%s:%d:1: after reset, sc=0x%x sn=0x%x "
953 1.70 bouyer "cl=0x%x ch=0x%x\n",
954 1.70 bouyer chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
955 1.70 bouyer chp->channel, sc1, sn1, cl1, ch1), DEBUG_PROBE);
956 1.70 bouyer
957 1.65 bouyer WDCDEBUG_PRINT(("%s:%d: wdcwait_reset() end, st0=0x%x, st1=0x%x\n",
958 1.65 bouyer chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", chp->channel,
959 1.65 bouyer st0, st1), DEBUG_PROBE);
960 1.65 bouyer
961 1.31 bouyer return drv_mask;
962 1.2 bouyer }
963 1.2 bouyer
964 1.2 bouyer /*
965 1.31 bouyer * Wait for a drive to be !BSY, and have mask in its status register.
966 1.31 bouyer * return -1 for a timeout after "timeout" ms.
967 1.2 bouyer */
968 1.31 bouyer int
969 1.31 bouyer wdcwait(chp, mask, bits, timeout)
970 1.31 bouyer struct channel_softc *chp;
971 1.31 bouyer int mask, bits, timeout;
972 1.2 bouyer {
973 1.31 bouyer u_char status;
974 1.31 bouyer int time = 0;
975 1.60 abs
976 1.60 abs WDCDEBUG_PRINT(("wdcwait %s:%d\n", chp->wdc ?chp->wdc->sc_dev.dv_xname
977 1.60 abs :"none", chp->channel), DEBUG_STATUS);
978 1.31 bouyer chp->ch_error = 0;
979 1.31 bouyer
980 1.31 bouyer timeout = timeout * 1000 / WDCDELAY; /* delay uses microseconds */
981 1.2 bouyer
982 1.31 bouyer for (;;) {
983 1.31 bouyer chp->ch_status = status =
984 1.31 bouyer bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
985 1.31 bouyer if ((status & WDCS_BSY) == 0 && (status & mask) == bits)
986 1.31 bouyer break;
987 1.31 bouyer if (++time > timeout) {
988 1.87 bouyer WDCDEBUG_PRINT(("wdcwait: timeout (time=%d), "
989 1.87 bouyer "status %x error %x (mask 0x%x bits 0x%x)\n",
990 1.87 bouyer time, status,
991 1.31 bouyer bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
992 1.77 bouyer wd_error), mask, bits),
993 1.87 bouyer DEBUG_STATUS | DEBUG_PROBE | DEBUG_DELAY);
994 1.31 bouyer return -1;
995 1.31 bouyer }
996 1.31 bouyer delay(WDCDELAY);
997 1.2 bouyer }
998 1.87 bouyer #ifdef WDCDEBUG
999 1.87 bouyer if (time > 0 && (wdcdebug_mask & DEBUG_DELAY))
1000 1.87 bouyer printf("wdcwait: did busy-wait, time=%d\n", time);
1001 1.87 bouyer #endif
1002 1.31 bouyer if (status & WDCS_ERR)
1003 1.31 bouyer chp->ch_error = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1004 1.31 bouyer wd_error);
1005 1.31 bouyer #ifdef WDCNDELAY_DEBUG
1006 1.31 bouyer /* After autoconfig, there should be no long delays. */
1007 1.31 bouyer if (!cold && time > WDCNDELAY_DEBUG) {
1008 1.31 bouyer struct wdc_xfer *xfer = chp->ch_queue->sc_xfer.tqh_first;
1009 1.31 bouyer if (xfer == NULL)
1010 1.31 bouyer printf("%s channel %d: warning: busy-wait took %dus\n",
1011 1.31 bouyer chp->wdc->sc_dev.dv_xname, chp->channel,
1012 1.31 bouyer WDCDELAY * time);
1013 1.31 bouyer else
1014 1.31 bouyer printf("%s:%d:%d: warning: busy-wait took %dus\n",
1015 1.49 bouyer chp->wdc->sc_dev.dv_xname, chp->channel,
1016 1.31 bouyer xfer->drive,
1017 1.31 bouyer WDCDELAY * time);
1018 1.2 bouyer }
1019 1.2 bouyer #endif
1020 1.31 bouyer return 0;
1021 1.2 bouyer }
1022 1.2 bouyer
1023 1.84 bouyer /*
1024 1.84 bouyer * Busy-wait for DMA to complete
1025 1.84 bouyer */
1026 1.84 bouyer int
1027 1.84 bouyer wdc_dmawait(chp, xfer, timeout)
1028 1.84 bouyer struct channel_softc *chp;
1029 1.84 bouyer struct wdc_xfer *xfer;
1030 1.84 bouyer int timeout;
1031 1.84 bouyer {
1032 1.84 bouyer int time;
1033 1.84 bouyer for (time = 0; time < timeout * 1000 / WDCDELAY; time++) {
1034 1.84 bouyer chp->wdc->dma_status =
1035 1.84 bouyer (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
1036 1.84 bouyer chp->channel, xfer->drive, 0);
1037 1.84 bouyer if ((chp->wdc->dma_status & WDC_DMAST_NOIRQ) == 0)
1038 1.84 bouyer return 0;
1039 1.84 bouyer delay(WDCDELAY);
1040 1.84 bouyer }
1041 1.84 bouyer /* timeout, force a DMA halt */
1042 1.84 bouyer chp->wdc->dma_status = (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
1043 1.84 bouyer chp->channel, xfer->drive, 1);
1044 1.84 bouyer return 1;
1045 1.84 bouyer }
1046 1.84 bouyer
1047 1.31 bouyer void
1048 1.31 bouyer wdctimeout(arg)
1049 1.31 bouyer void *arg;
1050 1.2 bouyer {
1051 1.31 bouyer struct channel_softc *chp = (struct channel_softc *)arg;
1052 1.31 bouyer struct wdc_xfer *xfer = chp->ch_queue->sc_xfer.tqh_first;
1053 1.31 bouyer int s;
1054 1.2 bouyer
1055 1.31 bouyer WDCDEBUG_PRINT(("wdctimeout\n"), DEBUG_FUNCS);
1056 1.31 bouyer
1057 1.31 bouyer s = splbio();
1058 1.31 bouyer if ((chp->ch_flags & WDCF_IRQ_WAIT) != 0) {
1059 1.31 bouyer __wdcerror(chp, "lost interrupt");
1060 1.88 mrg printf("\ttype: %s tc_bcount: %d tc_skip: %d\n",
1061 1.88 mrg (xfer->c_flags & C_ATAPI) ? "atapi" : "ata",
1062 1.88 mrg xfer->c_bcount,
1063 1.88 mrg xfer->c_skip);
1064 1.84 bouyer if (chp->ch_flags & WDCF_DMA_WAIT) {
1065 1.84 bouyer chp->wdc->dma_status =
1066 1.84 bouyer (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
1067 1.84 bouyer chp->channel, xfer->drive, 1);
1068 1.84 bouyer chp->ch_flags &= ~WDCF_DMA_WAIT;
1069 1.84 bouyer }
1070 1.31 bouyer /*
1071 1.119 drochner * Call the interrupt routine. If we just missed an interrupt,
1072 1.31 bouyer * it will do what's needed. Else, it will take the needed
1073 1.31 bouyer * action (reset the device).
1074 1.70 bouyer * Before that we need to reinstall the timeout callback,
1075 1.70 bouyer * in case it will miss another irq while in this transfer
1076 1.70 bouyer * We arbitray chose it to be 1s
1077 1.31 bouyer */
1078 1.81 thorpej callout_reset(&chp->ch_callout, hz, wdctimeout, chp);
1079 1.31 bouyer xfer->c_flags |= C_TIMEOU;
1080 1.31 bouyer chp->ch_flags &= ~WDCF_IRQ_WAIT;
1081 1.66 bouyer xfer->c_intr(chp, xfer, 1);
1082 1.31 bouyer } else
1083 1.31 bouyer __wdcerror(chp, "missing untimeout");
1084 1.31 bouyer splx(s);
1085 1.2 bouyer }
1086 1.2 bouyer
1087 1.31 bouyer /*
1088 1.31 bouyer * Probe drive's capabilites, for use by the controller later
1089 1.31 bouyer * Assumes drvp points to an existing drive.
1090 1.31 bouyer * XXX this should be a controller-indep function
1091 1.31 bouyer */
1092 1.2 bouyer void
1093 1.31 bouyer wdc_probe_caps(drvp)
1094 1.31 bouyer struct ata_drive_datas *drvp;
1095 1.2 bouyer {
1096 1.31 bouyer struct ataparams params, params2;
1097 1.31 bouyer struct channel_softc *chp = drvp->chnl_softc;
1098 1.31 bouyer struct device *drv_dev = drvp->drv_softc;
1099 1.31 bouyer struct wdc_softc *wdc = chp->wdc;
1100 1.31 bouyer int i, printed;
1101 1.31 bouyer char *sep = "";
1102 1.48 bouyer int cf_flags;
1103 1.31 bouyer
1104 1.125 mycroft if (ata_get_params(drvp, AT_WAIT, ¶ms) != CMD_OK) {
1105 1.31 bouyer /* IDENTIFY failed. Can't tell more about the device */
1106 1.2 bouyer return;
1107 1.2 bouyer }
1108 1.31 bouyer if ((wdc->cap & (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
1109 1.31 bouyer (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) {
1110 1.2 bouyer /*
1111 1.39 bouyer * Controller claims 16 and 32 bit transfers.
1112 1.39 bouyer * Re-do an IDENTIFY with 32-bit transfers,
1113 1.31 bouyer * and compare results.
1114 1.2 bouyer */
1115 1.31 bouyer drvp->drive_flags |= DRIVE_CAP32;
1116 1.125 mycroft ata_get_params(drvp, AT_WAIT, ¶ms2);
1117 1.31 bouyer if (memcmp(¶ms, ¶ms2, sizeof(struct ataparams)) != 0) {
1118 1.31 bouyer /* Not good. fall back to 16bits */
1119 1.31 bouyer drvp->drive_flags &= ~DRIVE_CAP32;
1120 1.31 bouyer } else {
1121 1.125 mycroft aprint_normal("%s: 32-bit data port\n",
1122 1.123 thorpej drv_dev->dv_xname);
1123 1.2 bouyer }
1124 1.2 bouyer }
1125 1.55 bouyer #if 0 /* Some ultra-DMA drives claims to only support ATA-3. sigh */
1126 1.55 bouyer if (params.atap_ata_major > 0x01 &&
1127 1.55 bouyer params.atap_ata_major != 0xffff) {
1128 1.55 bouyer for (i = 14; i > 0; i--) {
1129 1.55 bouyer if (params.atap_ata_major & (1 << i)) {
1130 1.125 mycroft aprint_normal("%s: ATA version %d\n",
1131 1.125 mycroft drv_dev->dv_xname, i);
1132 1.55 bouyer drvp->ata_vers = i;
1133 1.55 bouyer break;
1134 1.55 bouyer }
1135 1.55 bouyer }
1136 1.125 mycroft }
1137 1.55 bouyer #endif
1138 1.2 bouyer
1139 1.31 bouyer /* An ATAPI device is at last PIO mode 3 */
1140 1.31 bouyer if (drvp->drive_flags & DRIVE_ATAPI)
1141 1.31 bouyer drvp->PIO_mode = 3;
1142 1.2 bouyer
1143 1.2 bouyer /*
1144 1.31 bouyer * It's not in the specs, but it seems that some drive
1145 1.31 bouyer * returns 0xffff in atap_extensions when this field is invalid
1146 1.2 bouyer */
1147 1.31 bouyer if (params.atap_extensions != 0xffff &&
1148 1.31 bouyer (params.atap_extensions & WDC_EXT_MODES)) {
1149 1.31 bouyer printed = 0;
1150 1.31 bouyer /*
1151 1.31 bouyer * XXX some drives report something wrong here (they claim to
1152 1.31 bouyer * support PIO mode 8 !). As mode is coded on 3 bits in
1153 1.31 bouyer * SET FEATURE, limit it to 7 (so limit i to 4).
1154 1.116 wiz * If higher mode than 7 is found, abort.
1155 1.31 bouyer */
1156 1.39 bouyer for (i = 7; i >= 0; i--) {
1157 1.31 bouyer if ((params.atap_piomode_supp & (1 << i)) == 0)
1158 1.31 bouyer continue;
1159 1.39 bouyer if (i > 4)
1160 1.39 bouyer return;
1161 1.31 bouyer /*
1162 1.31 bouyer * See if mode is accepted.
1163 1.31 bouyer * If the controller can't set its PIO mode,
1164 1.31 bouyer * assume the defaults are good, so don't try
1165 1.31 bouyer * to set it
1166 1.31 bouyer */
1167 1.31 bouyer if ((wdc->cap & WDC_CAPABILITY_MODE) != 0)
1168 1.31 bouyer if (ata_set_mode(drvp, 0x08 | (i + 3),
1169 1.125 mycroft AT_WAIT) != CMD_OK)
1170 1.2 bouyer continue;
1171 1.31 bouyer if (!printed) {
1172 1.123 thorpej aprint_normal("%s: drive supports PIO mode %d",
1173 1.39 bouyer drv_dev->dv_xname, i + 3);
1174 1.31 bouyer sep = ",";
1175 1.31 bouyer printed = 1;
1176 1.31 bouyer }
1177 1.31 bouyer /*
1178 1.31 bouyer * If controller's driver can't set its PIO mode,
1179 1.31 bouyer * get the highter one for the drive.
1180 1.31 bouyer */
1181 1.31 bouyer if ((wdc->cap & WDC_CAPABILITY_MODE) == 0 ||
1182 1.52 bouyer wdc->PIO_cap >= i + 3) {
1183 1.31 bouyer drvp->PIO_mode = i + 3;
1184 1.48 bouyer drvp->PIO_cap = i + 3;
1185 1.2 bouyer break;
1186 1.2 bouyer }
1187 1.2 bouyer }
1188 1.31 bouyer if (!printed) {
1189 1.31 bouyer /*
1190 1.31 bouyer * We didn't find a valid PIO mode.
1191 1.31 bouyer * Assume the values returned for DMA are buggy too
1192 1.31 bouyer */
1193 1.31 bouyer return;
1194 1.2 bouyer }
1195 1.35 bouyer drvp->drive_flags |= DRIVE_MODE;
1196 1.31 bouyer printed = 0;
1197 1.31 bouyer for (i = 7; i >= 0; i--) {
1198 1.31 bouyer if ((params.atap_dmamode_supp & (1 << i)) == 0)
1199 1.31 bouyer continue;
1200 1.31 bouyer if ((wdc->cap & WDC_CAPABILITY_DMA) &&
1201 1.31 bouyer (wdc->cap & WDC_CAPABILITY_MODE))
1202 1.125 mycroft if (ata_set_mode(drvp, 0x20 | i, AT_WAIT)
1203 1.31 bouyer != CMD_OK)
1204 1.31 bouyer continue;
1205 1.31 bouyer if (!printed) {
1206 1.123 thorpej aprint_normal("%s DMA mode %d", sep, i);
1207 1.31 bouyer sep = ",";
1208 1.31 bouyer printed = 1;
1209 1.31 bouyer }
1210 1.31 bouyer if (wdc->cap & WDC_CAPABILITY_DMA) {
1211 1.31 bouyer if ((wdc->cap & WDC_CAPABILITY_MODE) &&
1212 1.52 bouyer wdc->DMA_cap < i)
1213 1.31 bouyer continue;
1214 1.31 bouyer drvp->DMA_mode = i;
1215 1.48 bouyer drvp->DMA_cap = i;
1216 1.31 bouyer drvp->drive_flags |= DRIVE_DMA;
1217 1.31 bouyer }
1218 1.2 bouyer break;
1219 1.2 bouyer }
1220 1.31 bouyer if (params.atap_extensions & WDC_EXT_UDMA_MODES) {
1221 1.71 bouyer printed = 0;
1222 1.31 bouyer for (i = 7; i >= 0; i--) {
1223 1.31 bouyer if ((params.atap_udmamode_supp & (1 << i))
1224 1.31 bouyer == 0)
1225 1.31 bouyer continue;
1226 1.31 bouyer if ((wdc->cap & WDC_CAPABILITY_MODE) &&
1227 1.31 bouyer (wdc->cap & WDC_CAPABILITY_UDMA))
1228 1.31 bouyer if (ata_set_mode(drvp, 0x40 | i,
1229 1.125 mycroft AT_WAIT) != CMD_OK)
1230 1.31 bouyer continue;
1231 1.71 bouyer if (!printed) {
1232 1.123 thorpej aprint_normal("%s Ultra-DMA mode %d",
1233 1.123 thorpej sep, i);
1234 1.93 wrstuden if (i == 2)
1235 1.123 thorpej aprint_normal(" (Ultra/33)");
1236 1.93 wrstuden else if (i == 4)
1237 1.123 thorpej aprint_normal(" (Ultra/66)");
1238 1.93 wrstuden else if (i == 5)
1239 1.123 thorpej aprint_normal(" (Ultra/100)");
1240 1.117 bouyer else if (i == 6)
1241 1.123 thorpej aprint_normal(" (Ultra/133)");
1242 1.71 bouyer sep = ",";
1243 1.71 bouyer printed = 1;
1244 1.71 bouyer }
1245 1.31 bouyer if (wdc->cap & WDC_CAPABILITY_UDMA) {
1246 1.50 bouyer if ((wdc->cap & WDC_CAPABILITY_MODE) &&
1247 1.52 bouyer wdc->UDMA_cap < i)
1248 1.50 bouyer continue;
1249 1.31 bouyer drvp->UDMA_mode = i;
1250 1.48 bouyer drvp->UDMA_cap = i;
1251 1.31 bouyer drvp->drive_flags |= DRIVE_UDMA;
1252 1.31 bouyer }
1253 1.31 bouyer break;
1254 1.31 bouyer }
1255 1.31 bouyer }
1256 1.123 thorpej aprint_normal("\n");
1257 1.55 bouyer }
1258 1.55 bouyer
1259 1.55 bouyer /* Try to guess ATA version here, if it didn't get reported */
1260 1.55 bouyer if (drvp->ata_vers == 0) {
1261 1.55 bouyer if (drvp->drive_flags & DRIVE_UDMA)
1262 1.55 bouyer drvp->ata_vers = 4; /* should be at last ATA-4 */
1263 1.55 bouyer else if (drvp->PIO_cap > 2)
1264 1.55 bouyer drvp->ata_vers = 2; /* should be at last ATA-2 */
1265 1.48 bouyer }
1266 1.48 bouyer cf_flags = drv_dev->dv_cfdata->cf_flags;
1267 1.48 bouyer if (cf_flags & ATA_CONFIG_PIO_SET) {
1268 1.48 bouyer drvp->PIO_mode =
1269 1.48 bouyer (cf_flags & ATA_CONFIG_PIO_MODES) >> ATA_CONFIG_PIO_OFF;
1270 1.48 bouyer drvp->drive_flags |= DRIVE_MODE;
1271 1.48 bouyer }
1272 1.48 bouyer if ((wdc->cap & WDC_CAPABILITY_DMA) == 0) {
1273 1.48 bouyer /* don't care about DMA modes */
1274 1.48 bouyer return;
1275 1.48 bouyer }
1276 1.48 bouyer if (cf_flags & ATA_CONFIG_DMA_SET) {
1277 1.48 bouyer if ((cf_flags & ATA_CONFIG_DMA_MODES) ==
1278 1.48 bouyer ATA_CONFIG_DMA_DISABLE) {
1279 1.48 bouyer drvp->drive_flags &= ~DRIVE_DMA;
1280 1.48 bouyer } else {
1281 1.48 bouyer drvp->DMA_mode = (cf_flags & ATA_CONFIG_DMA_MODES) >>
1282 1.48 bouyer ATA_CONFIG_DMA_OFF;
1283 1.48 bouyer drvp->drive_flags |= DRIVE_DMA | DRIVE_MODE;
1284 1.48 bouyer }
1285 1.101 bouyer }
1286 1.101 bouyer if ((wdc->cap & WDC_CAPABILITY_UDMA) == 0) {
1287 1.101 bouyer /* don't care about UDMA modes */
1288 1.101 bouyer return;
1289 1.48 bouyer }
1290 1.48 bouyer if (cf_flags & ATA_CONFIG_UDMA_SET) {
1291 1.48 bouyer if ((cf_flags & ATA_CONFIG_UDMA_MODES) ==
1292 1.48 bouyer ATA_CONFIG_UDMA_DISABLE) {
1293 1.48 bouyer drvp->drive_flags &= ~DRIVE_UDMA;
1294 1.48 bouyer } else {
1295 1.48 bouyer drvp->UDMA_mode = (cf_flags & ATA_CONFIG_UDMA_MODES) >>
1296 1.48 bouyer ATA_CONFIG_UDMA_OFF;
1297 1.48 bouyer drvp->drive_flags |= DRIVE_UDMA | DRIVE_MODE;
1298 1.48 bouyer }
1299 1.2 bouyer }
1300 1.54 bouyer }
1301 1.54 bouyer
1302 1.54 bouyer /*
1303 1.56 bouyer * downgrade the transfer mode of a drive after an error. return 1 if
1304 1.54 bouyer * downgrade was possible, 0 otherwise.
1305 1.54 bouyer */
1306 1.54 bouyer int
1307 1.54 bouyer wdc_downgrade_mode(drvp)
1308 1.54 bouyer struct ata_drive_datas *drvp;
1309 1.54 bouyer {
1310 1.54 bouyer struct channel_softc *chp = drvp->chnl_softc;
1311 1.54 bouyer struct device *drv_dev = drvp->drv_softc;
1312 1.54 bouyer struct wdc_softc *wdc = chp->wdc;
1313 1.54 bouyer int cf_flags = drv_dev->dv_cfdata->cf_flags;
1314 1.54 bouyer
1315 1.54 bouyer /* if drive or controller don't know its mode, we can't do much */
1316 1.54 bouyer if ((drvp->drive_flags & DRIVE_MODE) == 0 ||
1317 1.54 bouyer (wdc->cap & WDC_CAPABILITY_MODE) == 0)
1318 1.54 bouyer return 0;
1319 1.54 bouyer /* current drive mode was set by a config flag, let it this way */
1320 1.54 bouyer if ((cf_flags & ATA_CONFIG_PIO_SET) ||
1321 1.54 bouyer (cf_flags & ATA_CONFIG_DMA_SET) ||
1322 1.54 bouyer (cf_flags & ATA_CONFIG_UDMA_SET))
1323 1.54 bouyer return 0;
1324 1.54 bouyer
1325 1.61 bouyer /*
1326 1.73 bouyer * If we were using Ultra-DMA mode > 2, downgrade to mode 2 first.
1327 1.73 bouyer * Maybe we didn't properly notice the cable type
1328 1.78 bouyer * If we were using Ultra-DMA mode 2, downgrade to mode 1 first.
1329 1.78 bouyer * It helps in some cases.
1330 1.73 bouyer */
1331 1.78 bouyer if ((drvp->drive_flags & DRIVE_UDMA) && drvp->UDMA_mode >= 2) {
1332 1.78 bouyer drvp->UDMA_mode = (drvp->UDMA_mode == 2) ? 1 : 2;
1333 1.78 bouyer printf("%s: transfer error, downgrading to Ultra-DMA mode %d\n",
1334 1.73 bouyer drv_dev->dv_xname, drvp->UDMA_mode);
1335 1.73 bouyer }
1336 1.73 bouyer
1337 1.73 bouyer /*
1338 1.61 bouyer * If we were using ultra-DMA, don't downgrade to multiword DMA
1339 1.61 bouyer * if we noticed a CRC error. It has been noticed that CRC errors
1340 1.61 bouyer * in ultra-DMA lead to silent data corruption in multiword DMA.
1341 1.61 bouyer * Data corruption is less likely to occur in PIO mode.
1342 1.61 bouyer */
1343 1.73 bouyer else if ((drvp->drive_flags & DRIVE_UDMA) &&
1344 1.61 bouyer (drvp->drive_flags & DRIVE_DMAERR) == 0) {
1345 1.54 bouyer drvp->drive_flags &= ~DRIVE_UDMA;
1346 1.54 bouyer drvp->drive_flags |= DRIVE_DMA;
1347 1.54 bouyer drvp->DMA_mode = drvp->DMA_cap;
1348 1.56 bouyer printf("%s: transfer error, downgrading to DMA mode %d\n",
1349 1.54 bouyer drv_dev->dv_xname, drvp->DMA_mode);
1350 1.61 bouyer } else if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) {
1351 1.61 bouyer drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
1352 1.54 bouyer drvp->PIO_mode = drvp->PIO_cap;
1353 1.56 bouyer printf("%s: transfer error, downgrading to PIO mode %d\n",
1354 1.54 bouyer drv_dev->dv_xname, drvp->PIO_mode);
1355 1.54 bouyer } else /* already using PIO, can't downgrade */
1356 1.54 bouyer return 0;
1357 1.54 bouyer
1358 1.54 bouyer wdc->set_modes(chp);
1359 1.124 drochner /* reset the channel, which will schedule all drives for setup */
1360 1.54 bouyer wdc_reset_channel(drvp);
1361 1.54 bouyer return 1;
1362 1.2 bouyer }
1363 1.2 bouyer
1364 1.2 bouyer int
1365 1.31 bouyer wdc_exec_command(drvp, wdc_c)
1366 1.31 bouyer struct ata_drive_datas *drvp;
1367 1.31 bouyer struct wdc_command *wdc_c;
1368 1.31 bouyer {
1369 1.31 bouyer struct channel_softc *chp = drvp->chnl_softc;
1370 1.2 bouyer struct wdc_xfer *xfer;
1371 1.31 bouyer int s, ret;
1372 1.2 bouyer
1373 1.34 bouyer WDCDEBUG_PRINT(("wdc_exec_command %s:%d:%d\n",
1374 1.34 bouyer chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive),
1375 1.34 bouyer DEBUG_FUNCS);
1376 1.2 bouyer
1377 1.31 bouyer /* set up an xfer and queue. Wait for completion */
1378 1.31 bouyer xfer = wdc_get_xfer(wdc_c->flags & AT_WAIT ? WDC_CANSLEEP :
1379 1.31 bouyer WDC_NOSLEEP);
1380 1.31 bouyer if (xfer == NULL) {
1381 1.31 bouyer return WDC_TRY_AGAIN;
1382 1.31 bouyer }
1383 1.2 bouyer
1384 1.98 bjh21 if (chp->wdc->cap & WDC_CAPABILITY_NOIRQ)
1385 1.98 bjh21 wdc_c->flags |= AT_POLL;
1386 1.31 bouyer if (wdc_c->flags & AT_POLL)
1387 1.31 bouyer xfer->c_flags |= C_POLL;
1388 1.31 bouyer xfer->drive = drvp->drive;
1389 1.31 bouyer xfer->databuf = wdc_c->data;
1390 1.31 bouyer xfer->c_bcount = wdc_c->bcount;
1391 1.31 bouyer xfer->cmd = wdc_c;
1392 1.31 bouyer xfer->c_start = __wdccommand_start;
1393 1.31 bouyer xfer->c_intr = __wdccommand_intr;
1394 1.75 enami xfer->c_kill_xfer = __wdccommand_done;
1395 1.2 bouyer
1396 1.31 bouyer s = splbio();
1397 1.31 bouyer wdc_exec_xfer(chp, xfer);
1398 1.31 bouyer #ifdef DIAGNOSTIC
1399 1.31 bouyer if ((wdc_c->flags & AT_POLL) != 0 &&
1400 1.31 bouyer (wdc_c->flags & AT_DONE) == 0)
1401 1.118 provos panic("wdc_exec_command: polled command not done");
1402 1.2 bouyer #endif
1403 1.31 bouyer if (wdc_c->flags & AT_DONE) {
1404 1.31 bouyer ret = WDC_COMPLETE;
1405 1.31 bouyer } else {
1406 1.31 bouyer if (wdc_c->flags & AT_WAIT) {
1407 1.69 bouyer while ((wdc_c->flags & AT_DONE) == 0) {
1408 1.69 bouyer tsleep(wdc_c, PRIBIO, "wdccmd", 0);
1409 1.69 bouyer }
1410 1.31 bouyer ret = WDC_COMPLETE;
1411 1.31 bouyer } else {
1412 1.31 bouyer ret = WDC_QUEUED;
1413 1.2 bouyer }
1414 1.2 bouyer }
1415 1.31 bouyer splx(s);
1416 1.31 bouyer return ret;
1417 1.2 bouyer }
1418 1.2 bouyer
1419 1.2 bouyer void
1420 1.31 bouyer __wdccommand_start(chp, xfer)
1421 1.31 bouyer struct channel_softc *chp;
1422 1.2 bouyer struct wdc_xfer *xfer;
1423 1.31 bouyer {
1424 1.31 bouyer int drive = xfer->drive;
1425 1.31 bouyer struct wdc_command *wdc_c = xfer->cmd;
1426 1.31 bouyer
1427 1.34 bouyer WDCDEBUG_PRINT(("__wdccommand_start %s:%d:%d\n",
1428 1.34 bouyer chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
1429 1.34 bouyer DEBUG_FUNCS);
1430 1.31 bouyer
1431 1.107 dbj if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
1432 1.107 dbj chp->wdc->select(chp,drive);
1433 1.107 dbj
1434 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
1435 1.31 bouyer WDSD_IBM | (drive << 4));
1436 1.79 bouyer if (wdcwait(chp, wdc_c->r_st_bmask | WDCS_DRQ, wdc_c->r_st_bmask,
1437 1.31 bouyer wdc_c->timeout) != 0) {
1438 1.31 bouyer wdc_c->flags |= AT_TIMEOU;
1439 1.31 bouyer __wdccommand_done(chp, xfer);
1440 1.53 bouyer return;
1441 1.31 bouyer }
1442 1.31 bouyer wdccommand(chp, drive, wdc_c->r_command, wdc_c->r_cyl, wdc_c->r_head,
1443 1.31 bouyer wdc_c->r_sector, wdc_c->r_count, wdc_c->r_precomp);
1444 1.31 bouyer if ((wdc_c->flags & AT_POLL) == 0) {
1445 1.31 bouyer chp->ch_flags |= WDCF_IRQ_WAIT; /* wait for interrupt */
1446 1.81 thorpej callout_reset(&chp->ch_callout, wdc_c->timeout / 1000 * hz,
1447 1.81 thorpej wdctimeout, chp);
1448 1.31 bouyer return;
1449 1.2 bouyer }
1450 1.2 bouyer /*
1451 1.31 bouyer * Polled command. Wait for drive ready or drq. Done in intr().
1452 1.31 bouyer * Wait for at last 400ns for status bit to be valid.
1453 1.2 bouyer */
1454 1.31 bouyer delay(10);
1455 1.66 bouyer __wdccommand_intr(chp, xfer, 0);
1456 1.2 bouyer }
1457 1.2 bouyer
1458 1.2 bouyer int
1459 1.66 bouyer __wdccommand_intr(chp, xfer, irq)
1460 1.31 bouyer struct channel_softc *chp;
1461 1.31 bouyer struct wdc_xfer *xfer;
1462 1.66 bouyer int irq;
1463 1.2 bouyer {
1464 1.31 bouyer struct wdc_command *wdc_c = xfer->cmd;
1465 1.31 bouyer int bcount = wdc_c->bcount;
1466 1.31 bouyer char *data = wdc_c->data;
1467 1.31 bouyer
1468 1.114 bouyer again:
1469 1.34 bouyer WDCDEBUG_PRINT(("__wdccommand_intr %s:%d:%d\n",
1470 1.34 bouyer chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), DEBUG_INTR);
1471 1.114 bouyer if ((wdc_c->flags & AT_XFDONE) != 0) {
1472 1.114 bouyer /*
1473 1.114 bouyer * We have completed a data xfer. The drive should now be
1474 1.114 bouyer * in its initial state
1475 1.114 bouyer */
1476 1.114 bouyer if (wdcwait(chp, wdc_c->r_st_bmask | WDCS_DRQ,
1477 1.114 bouyer wdc_c->r_st_bmask, (irq == 0) ? wdc_c->timeout : 0) != 0) {
1478 1.114 bouyer if (irq && (xfer->c_flags & C_TIMEOU) == 0)
1479 1.114 bouyer return 0; /* IRQ was not for us */
1480 1.114 bouyer wdc_c->flags |= AT_TIMEOU;
1481 1.114 bouyer __wdccommand_done(chp, xfer);
1482 1.114 bouyer return 1;
1483 1.114 bouyer }
1484 1.114 bouyer wdc_c->flags |= AT_DONE;
1485 1.114 bouyer __wdccommand_done(chp, xfer);
1486 1.114 bouyer return 1;
1487 1.114 bouyer }
1488 1.31 bouyer if (wdcwait(chp, wdc_c->r_st_pmask, wdc_c->r_st_pmask,
1489 1.66 bouyer (irq == 0) ? wdc_c->timeout : 0)) {
1490 1.66 bouyer if (irq && (xfer->c_flags & C_TIMEOU) == 0)
1491 1.63 bouyer return 0; /* IRQ was not for us */
1492 1.63 bouyer wdc_c->flags |= AT_TIMEOU;
1493 1.31 bouyer __wdccommand_done(chp, xfer);
1494 1.2 bouyer return 1;
1495 1.2 bouyer }
1496 1.91 bouyer if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
1497 1.91 bouyer chp->wdc->irqack(chp);
1498 1.31 bouyer if (wdc_c->flags & AT_READ) {
1499 1.31 bouyer if (chp->ch_drive[xfer->drive].drive_flags & DRIVE_CAP32) {
1500 1.31 bouyer bus_space_read_multi_4(chp->data32iot, chp->data32ioh,
1501 1.31 bouyer 0, (u_int32_t*)data, bcount >> 2);
1502 1.31 bouyer data += bcount & 0xfffffffc;
1503 1.31 bouyer bcount = bcount & 0x03;
1504 1.31 bouyer }
1505 1.31 bouyer if (bcount > 0)
1506 1.31 bouyer bus_space_read_multi_2(chp->cmd_iot, chp->cmd_ioh,
1507 1.31 bouyer wd_data, (u_int16_t *)data, bcount >> 1);
1508 1.114 bouyer /* at this point the drive should be in its initial state */
1509 1.114 bouyer wdc_c->flags |= AT_XFDONE;
1510 1.114 bouyer if (wdcwait(chp, wdc_c->r_st_bmask | WDCS_DRQ,
1511 1.114 bouyer wdc_c->r_st_bmask, 100) != 0)
1512 1.114 bouyer wdc_c->flags |= AT_TIMEOU;
1513 1.31 bouyer } else if (wdc_c->flags & AT_WRITE) {
1514 1.31 bouyer if (chp->ch_drive[xfer->drive].drive_flags & DRIVE_CAP32) {
1515 1.31 bouyer bus_space_write_multi_4(chp->data32iot, chp->data32ioh,
1516 1.31 bouyer 0, (u_int32_t*)data, bcount >> 2);
1517 1.31 bouyer data += bcount & 0xfffffffc;
1518 1.31 bouyer bcount = bcount & 0x03;
1519 1.31 bouyer }
1520 1.31 bouyer if (bcount > 0)
1521 1.31 bouyer bus_space_write_multi_2(chp->cmd_iot, chp->cmd_ioh,
1522 1.31 bouyer wd_data, (u_int16_t *)data, bcount >> 1);
1523 1.114 bouyer wdc_c->flags |= AT_XFDONE;
1524 1.114 bouyer if ((wdc_c->flags & AT_POLL) == 0) {
1525 1.114 bouyer chp->ch_flags |= WDCF_IRQ_WAIT; /* wait for interrupt */
1526 1.114 bouyer callout_reset(&chp->ch_callout,
1527 1.114 bouyer wdc_c->timeout / 1000 * hz, wdctimeout, chp);
1528 1.114 bouyer return 1;
1529 1.114 bouyer } else {
1530 1.114 bouyer goto again;
1531 1.114 bouyer }
1532 1.2 bouyer }
1533 1.31 bouyer __wdccommand_done(chp, xfer);
1534 1.31 bouyer return 1;
1535 1.2 bouyer }
1536 1.2 bouyer
1537 1.2 bouyer void
1538 1.31 bouyer __wdccommand_done(chp, xfer)
1539 1.31 bouyer struct channel_softc *chp;
1540 1.31 bouyer struct wdc_xfer *xfer;
1541 1.2 bouyer {
1542 1.31 bouyer struct wdc_command *wdc_c = xfer->cmd;
1543 1.2 bouyer
1544 1.34 bouyer WDCDEBUG_PRINT(("__wdccommand_done %s:%d:%d\n",
1545 1.34 bouyer chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), DEBUG_FUNCS);
1546 1.70 bouyer
1547 1.81 thorpej callout_stop(&chp->ch_callout);
1548 1.70 bouyer
1549 1.31 bouyer if (chp->ch_status & WDCS_DWF)
1550 1.31 bouyer wdc_c->flags |= AT_DF;
1551 1.31 bouyer if (chp->ch_status & WDCS_ERR) {
1552 1.31 bouyer wdc_c->flags |= AT_ERROR;
1553 1.31 bouyer wdc_c->r_error = chp->ch_error;
1554 1.31 bouyer }
1555 1.31 bouyer wdc_c->flags |= AT_DONE;
1556 1.80 enami if ((wdc_c->flags & AT_READREG) != 0 &&
1557 1.80 enami (chp->wdc->sc_dev.dv_flags & DVF_ACTIVE) != 0 &&
1558 1.75 enami (wdc_c->flags & (AT_ERROR | AT_DF)) == 0) {
1559 1.46 kenh wdc_c->r_head = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1560 1.46 kenh wd_sdh);
1561 1.46 kenh wdc_c->r_cyl = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1562 1.46 kenh wd_cyl_hi) << 8;
1563 1.46 kenh wdc_c->r_cyl |= bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1564 1.46 kenh wd_cyl_lo);
1565 1.46 kenh wdc_c->r_sector = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1566 1.46 kenh wd_sector);
1567 1.46 kenh wdc_c->r_count = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1568 1.46 kenh wd_seccnt);
1569 1.46 kenh wdc_c->r_error = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1570 1.46 kenh wd_error);
1571 1.46 kenh wdc_c->r_precomp = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
1572 1.46 kenh wd_precomp);
1573 1.46 kenh }
1574 1.31 bouyer wdc_free_xfer(chp, xfer);
1575 1.71 bouyer if (wdc_c->flags & AT_WAIT)
1576 1.71 bouyer wakeup(wdc_c);
1577 1.71 bouyer else if (wdc_c->callback)
1578 1.71 bouyer wdc_c->callback(wdc_c->callback_arg);
1579 1.45 drochner wdcstart(chp);
1580 1.31 bouyer return;
1581 1.2 bouyer }
1582 1.2 bouyer
1583 1.2 bouyer /*
1584 1.31 bouyer * Send a command. The drive should be ready.
1585 1.2 bouyer * Assumes interrupts are blocked.
1586 1.2 bouyer */
1587 1.31 bouyer void
1588 1.31 bouyer wdccommand(chp, drive, command, cylin, head, sector, count, precomp)
1589 1.31 bouyer struct channel_softc *chp;
1590 1.31 bouyer u_int8_t drive;
1591 1.31 bouyer u_int8_t command;
1592 1.31 bouyer u_int16_t cylin;
1593 1.31 bouyer u_int8_t head, sector, count, precomp;
1594 1.31 bouyer {
1595 1.31 bouyer WDCDEBUG_PRINT(("wdccommand %s:%d:%d: command=0x%x cylin=%d head=%d "
1596 1.31 bouyer "sector=%d count=%d precomp=%d\n", chp->wdc->sc_dev.dv_xname,
1597 1.31 bouyer chp->channel, drive, command, cylin, head, sector, count, precomp),
1598 1.31 bouyer DEBUG_FUNCS);
1599 1.31 bouyer
1600 1.107 dbj if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
1601 1.107 dbj chp->wdc->select(chp,drive);
1602 1.107 dbj
1603 1.31 bouyer /* Select drive, head, and addressing mode. */
1604 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
1605 1.31 bouyer WDSD_IBM | (drive << 4) | head);
1606 1.31 bouyer /* Load parameters. wd_features(ATA/ATAPI) = wd_precomp(ST506) */
1607 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_precomp,
1608 1.31 bouyer precomp);
1609 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo, cylin);
1610 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_hi, cylin >> 8);
1611 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sector, sector);
1612 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt, count);
1613 1.108 christos
1614 1.108 christos /* Send command. */
1615 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_command, command);
1616 1.108 christos return;
1617 1.108 christos }
1618 1.108 christos
1619 1.108 christos /*
1620 1.108 christos * Send a 48-bit addressing command. The drive should be ready.
1621 1.108 christos * Assumes interrupts are blocked.
1622 1.108 christos */
1623 1.108 christos void
1624 1.108 christos wdccommandext(chp, drive, command, blkno, count)
1625 1.108 christos struct channel_softc *chp;
1626 1.108 christos u_int8_t drive;
1627 1.108 christos u_int8_t command;
1628 1.108 christos u_int64_t blkno;
1629 1.108 christos u_int16_t count;
1630 1.108 christos {
1631 1.108 christos WDCDEBUG_PRINT(("wdccommandext %s:%d:%d: command=0x%x blkno=%d "
1632 1.108 christos "count=%d\n", chp->wdc->sc_dev.dv_xname,
1633 1.108 christos chp->channel, drive, command, (u_int32_t) blkno, count),
1634 1.108 christos DEBUG_FUNCS);
1635 1.108 christos
1636 1.108 christos if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
1637 1.108 christos chp->wdc->select(chp,drive);
1638 1.108 christos
1639 1.108 christos /* Select drive, head, and addressing mode. */
1640 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
1641 1.108 christos (drive << 4) | WDSD_LBA);
1642 1.108 christos
1643 1.108 christos /* previous */
1644 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_features, 0);
1645 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt, count >> 8);
1646 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_lba_hi, blkno >> 40);
1647 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_lba_mi, blkno >> 32);
1648 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_lba_lo, blkno >> 24);
1649 1.108 christos
1650 1.108 christos /* current */
1651 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_features, 0);
1652 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_seccnt, count);
1653 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_lba_hi, blkno >> 16);
1654 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_lba_mi, blkno >> 8);
1655 1.108 christos bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_lba_lo, blkno);
1656 1.2 bouyer
1657 1.31 bouyer /* Send command. */
1658 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_command, command);
1659 1.31 bouyer return;
1660 1.2 bouyer }
1661 1.2 bouyer
1662 1.2 bouyer /*
1663 1.31 bouyer * Simplified version of wdccommand(). Unbusy/ready/drq must be
1664 1.31 bouyer * tested by the caller.
1665 1.2 bouyer */
1666 1.31 bouyer void
1667 1.31 bouyer wdccommandshort(chp, drive, command)
1668 1.31 bouyer struct channel_softc *chp;
1669 1.31 bouyer int drive;
1670 1.31 bouyer int command;
1671 1.2 bouyer {
1672 1.2 bouyer
1673 1.31 bouyer WDCDEBUG_PRINT(("wdccommandshort %s:%d:%d command 0x%x\n",
1674 1.31 bouyer chp->wdc->sc_dev.dv_xname, chp->channel, drive, command),
1675 1.31 bouyer DEBUG_FUNCS);
1676 1.107 dbj
1677 1.107 dbj if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
1678 1.107 dbj chp->wdc->select(chp,drive);
1679 1.2 bouyer
1680 1.31 bouyer /* Select drive. */
1681 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
1682 1.31 bouyer WDSD_IBM | (drive << 4));
1683 1.2 bouyer
1684 1.31 bouyer bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_command, command);
1685 1.31 bouyer }
1686 1.2 bouyer
1687 1.31 bouyer /* Add a command to the queue and start controller. Must be called at splbio */
1688 1.2 bouyer
1689 1.2 bouyer void
1690 1.31 bouyer wdc_exec_xfer(chp, xfer)
1691 1.31 bouyer struct channel_softc *chp;
1692 1.2 bouyer struct wdc_xfer *xfer;
1693 1.2 bouyer {
1694 1.33 bouyer WDCDEBUG_PRINT(("wdc_exec_xfer %p channel %d drive %d\n", xfer,
1695 1.33 bouyer chp->channel, xfer->drive), DEBUG_XFERS);
1696 1.2 bouyer
1697 1.31 bouyer /* complete xfer setup */
1698 1.49 bouyer xfer->chp = chp;
1699 1.2 bouyer
1700 1.31 bouyer /*
1701 1.31 bouyer * If we are a polled command, and the list is not empty,
1702 1.31 bouyer * we are doing a dump. Drop the list to allow the polled command
1703 1.31 bouyer * to complete, we're going to reboot soon anyway.
1704 1.31 bouyer */
1705 1.31 bouyer if ((xfer->c_flags & C_POLL) != 0 &&
1706 1.31 bouyer chp->ch_queue->sc_xfer.tqh_first != NULL) {
1707 1.31 bouyer TAILQ_INIT(&chp->ch_queue->sc_xfer);
1708 1.31 bouyer }
1709 1.2 bouyer /* insert at the end of command list */
1710 1.31 bouyer TAILQ_INSERT_TAIL(&chp->ch_queue->sc_xfer,xfer , c_xferchain);
1711 1.31 bouyer WDCDEBUG_PRINT(("wdcstart from wdc_exec_xfer, flags 0x%x\n",
1712 1.33 bouyer chp->ch_flags), DEBUG_XFERS);
1713 1.45 drochner wdcstart(chp);
1714 1.31 bouyer }
1715 1.2 bouyer
1716 1.2 bouyer struct wdc_xfer *
1717 1.2 bouyer wdc_get_xfer(flags)
1718 1.2 bouyer int flags;
1719 1.2 bouyer {
1720 1.2 bouyer struct wdc_xfer *xfer;
1721 1.72 bouyer int s;
1722 1.2 bouyer
1723 1.72 bouyer s = splbio();
1724 1.71 bouyer xfer = pool_get(&wdc_xfer_pool,
1725 1.71 bouyer ((flags & WDC_NOSLEEP) != 0 ? PR_NOWAIT : PR_WAITOK));
1726 1.72 bouyer splx(s);
1727 1.99 chs if (xfer != NULL) {
1728 1.99 chs memset(xfer, 0, sizeof(struct wdc_xfer));
1729 1.99 chs }
1730 1.2 bouyer return xfer;
1731 1.2 bouyer }
1732 1.2 bouyer
1733 1.2 bouyer void
1734 1.31 bouyer wdc_free_xfer(chp, xfer)
1735 1.31 bouyer struct channel_softc *chp;
1736 1.2 bouyer struct wdc_xfer *xfer;
1737 1.2 bouyer {
1738 1.31 bouyer struct wdc_softc *wdc = chp->wdc;
1739 1.2 bouyer int s;
1740 1.2 bouyer
1741 1.31 bouyer if (wdc->cap & WDC_CAPABILITY_HWLOCK)
1742 1.31 bouyer (*wdc->free_hw)(chp);
1743 1.2 bouyer s = splbio();
1744 1.31 bouyer chp->ch_flags &= ~WDCF_ACTIVE;
1745 1.31 bouyer TAILQ_REMOVE(&chp->ch_queue->sc_xfer, xfer, c_xferchain);
1746 1.72 bouyer pool_put(&wdc_xfer_pool, xfer);
1747 1.2 bouyer splx(s);
1748 1.75 enami }
1749 1.75 enami
1750 1.75 enami /*
1751 1.75 enami * Kill off all pending xfers for a channel_softc.
1752 1.75 enami *
1753 1.75 enami * Must be called at splbio().
1754 1.75 enami */
1755 1.75 enami void
1756 1.75 enami wdc_kill_pending(chp)
1757 1.75 enami struct channel_softc *chp;
1758 1.75 enami {
1759 1.75 enami struct wdc_xfer *xfer;
1760 1.75 enami
1761 1.75 enami while ((xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer)) != NULL) {
1762 1.75 enami chp = xfer->chp;
1763 1.75 enami (*xfer->c_kill_xfer)(chp, xfer);
1764 1.75 enami }
1765 1.2 bouyer }
1766 1.2 bouyer
1767 1.31 bouyer static void
1768 1.31 bouyer __wdcerror(chp, msg)
1769 1.31 bouyer struct channel_softc *chp;
1770 1.2 bouyer char *msg;
1771 1.2 bouyer {
1772 1.31 bouyer struct wdc_xfer *xfer = chp->ch_queue->sc_xfer.tqh_first;
1773 1.88 mrg
1774 1.2 bouyer if (xfer == NULL)
1775 1.31 bouyer printf("%s:%d: %s\n", chp->wdc->sc_dev.dv_xname, chp->channel,
1776 1.31 bouyer msg);
1777 1.2 bouyer else
1778 1.31 bouyer printf("%s:%d:%d: %s\n", chp->wdc->sc_dev.dv_xname,
1779 1.49 bouyer chp->channel, xfer->drive, msg);
1780 1.2 bouyer }
1781 1.2 bouyer
1782 1.2 bouyer /*
1783 1.2 bouyer * the bit bucket
1784 1.2 bouyer */
1785 1.2 bouyer void
1786 1.31 bouyer wdcbit_bucket(chp, size)
1787 1.31 bouyer struct channel_softc *chp;
1788 1.2 bouyer int size;
1789 1.2 bouyer {
1790 1.2 bouyer
1791 1.12 cgd for (; size >= 2; size -= 2)
1792 1.31 bouyer (void)bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, wd_data);
1793 1.12 cgd if (size)
1794 1.31 bouyer (void)bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_data);
1795 1.44 thorpej }
1796 1.44 thorpej
1797 1.44 thorpej int
1798 1.44 thorpej wdc_addref(chp)
1799 1.44 thorpej struct channel_softc *chp;
1800 1.44 thorpej {
1801 1.44 thorpej struct wdc_softc *wdc = chp->wdc;
1802 1.96 bouyer struct scsipi_adapter *adapt = &wdc->sc_atapi_adapter._generic;
1803 1.44 thorpej int s, error = 0;
1804 1.44 thorpej
1805 1.44 thorpej s = splbio();
1806 1.96 bouyer if (adapt->adapt_refcnt++ == 0 &&
1807 1.96 bouyer adapt->adapt_enable != NULL) {
1808 1.96 bouyer error = (*adapt->adapt_enable)(&wdc->sc_dev, 1);
1809 1.44 thorpej if (error)
1810 1.96 bouyer adapt->adapt_refcnt--;
1811 1.44 thorpej }
1812 1.44 thorpej splx(s);
1813 1.44 thorpej return (error);
1814 1.44 thorpej }
1815 1.44 thorpej
1816 1.44 thorpej void
1817 1.44 thorpej wdc_delref(chp)
1818 1.44 thorpej struct channel_softc *chp;
1819 1.44 thorpej {
1820 1.44 thorpej struct wdc_softc *wdc = chp->wdc;
1821 1.96 bouyer struct scsipi_adapter *adapt = &wdc->sc_atapi_adapter._generic;
1822 1.44 thorpej int s;
1823 1.44 thorpej
1824 1.44 thorpej s = splbio();
1825 1.96 bouyer if (adapt->adapt_refcnt-- == 1 &&
1826 1.96 bouyer adapt->adapt_enable != NULL)
1827 1.96 bouyer (void) (*adapt->adapt_enable)(&wdc->sc_dev, 0);
1828 1.44 thorpej splx(s);
1829 1.93 wrstuden }
1830 1.93 wrstuden
1831 1.93 wrstuden void
1832 1.93 wrstuden wdc_print_modes(struct channel_softc *chp)
1833 1.93 wrstuden {
1834 1.93 wrstuden int drive;
1835 1.93 wrstuden struct ata_drive_datas *drvp;
1836 1.93 wrstuden
1837 1.93 wrstuden for (drive = 0; drive < 2; drive++) {
1838 1.93 wrstuden drvp = &chp->ch_drive[drive];
1839 1.93 wrstuden if ((drvp->drive_flags & DRIVE) == 0)
1840 1.93 wrstuden continue;
1841 1.123 thorpej aprint_normal("%s(%s:%d:%d): using PIO mode %d",
1842 1.93 wrstuden drvp->drv_softc->dv_xname,
1843 1.93 wrstuden chp->wdc->sc_dev.dv_xname,
1844 1.93 wrstuden chp->channel, drive, drvp->PIO_mode);
1845 1.93 wrstuden if (drvp->drive_flags & DRIVE_DMA)
1846 1.123 thorpej aprint_normal(", DMA mode %d", drvp->DMA_mode);
1847 1.93 wrstuden if (drvp->drive_flags & DRIVE_UDMA) {
1848 1.123 thorpej aprint_normal(", Ultra-DMA mode %d", drvp->UDMA_mode);
1849 1.93 wrstuden if (drvp->UDMA_mode == 2)
1850 1.123 thorpej aprint_normal(" (Ultra/33)");
1851 1.93 wrstuden else if (drvp->UDMA_mode == 4)
1852 1.123 thorpej aprint_normal(" (Ultra/66)");
1853 1.93 wrstuden else if (drvp->UDMA_mode == 5)
1854 1.123 thorpej aprint_normal(" (Ultra/100)");
1855 1.123 thorpej else if (drvp->UDMA_mode == 6)
1856 1.123 thorpej aprint_normal(" (Ultra/133)");
1857 1.93 wrstuden }
1858 1.93 wrstuden if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA))
1859 1.123 thorpej aprint_normal(" (using DMA data transfers)");
1860 1.123 thorpej aprint_normal("\n");
1861 1.93 wrstuden }
1862 1.2 bouyer }
1863