Line data Source code
1 : /* $OpenBSD: wdc.c,v 1.134 2017/12/30 23:08:29 guenther Exp $ */
2 : /* $NetBSD: wdc.c,v 1.68 1999/06/23 19:00:17 bouyer Exp $ */
3 : /*
4 : * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : * 1. Redistributions of source code must retain the above copyright
10 : * notice, this list of conditions and the following disclaimer.
11 : * 2. Redistributions in binary form must reproduce the above copyright
12 : * notice, this list of conditions and the following disclaimer in the
13 : * documentation and/or other materials provided with the distribution.
14 : *
15 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 : */
26 :
27 : /*-
28 : * Copyright (c) 1998 The NetBSD Foundation, Inc.
29 : * All rights reserved.
30 : *
31 : * This code is derived from software contributed to The NetBSD Foundation
32 : * by Charles M. Hannum, by Onno van der Linden and by Manuel Bouyer.
33 : *
34 : * Redistribution and use in source and binary forms, with or without
35 : * modification, are permitted provided that the following conditions
36 : * are met:
37 : * 1. Redistributions of source code must retain the above copyright
38 : * notice, this list of conditions and the following disclaimer.
39 : * 2. Redistributions in binary form must reproduce the above copyright
40 : * notice, this list of conditions and the following disclaimer in the
41 : * documentation and/or other materials provided with the distribution.
42 : *
43 : * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
44 : * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
45 : * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
46 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
47 : * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
48 : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
49 : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
50 : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
51 : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
52 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
53 : * POSSIBILITY OF SUCH DAMAGE.
54 : */
55 :
56 : #include <sys/param.h>
57 : #include <sys/systm.h>
58 : #include <sys/kernel.h>
59 : #include <sys/conf.h>
60 : #include <sys/buf.h>
61 : #include <sys/device.h>
62 : #include <sys/malloc.h>
63 : #include <sys/syslog.h>
64 : #include <sys/disk.h>
65 : #include <sys/pool.h>
66 :
67 : #include <machine/intr.h>
68 : #include <machine/bus.h>
69 :
70 : #include <dev/ata/atavar.h>
71 : #include <dev/ata/atareg.h>
72 : #include <dev/ic/wdcreg.h>
73 : #include <dev/ic/wdcvar.h>
74 : #include <dev/ic/wdcevent.h>
75 :
76 : #include <scsi/scsi_all.h>
77 : #include <scsi/scsiconf.h>
78 :
79 : #define WDCDELAY 100 /* 100 microseconds */
80 : #define WDCNDELAY_RST (WDC_RESET_WAIT * 1000 / WDCDELAY)
81 : #if 0
82 : /* If you enable this, it will report any delays more than WDCDELAY * N long. */
83 : #define WDCNDELAY_DEBUG 50
84 : #endif /* 0 */
85 :
86 : struct pool wdc_xfer_pool;
87 : struct scsi_iopool wdc_xfer_iopool;
88 :
89 : void * wdc_xfer_get(void *);
90 : void wdc_xfer_put(void *, void *);
91 :
92 : void __wdcerror(struct channel_softc *, char *);
93 : int __wdcwait_reset(struct channel_softc *, int);
94 : void __wdccommand_done(struct channel_softc *, struct wdc_xfer *);
95 : void __wdccommand_start(struct channel_softc *, struct wdc_xfer *);
96 : int __wdccommand_intr(struct channel_softc *, struct wdc_xfer *, int);
97 : int wdprint(void *, const char *);
98 : void wdc_kill_pending(struct channel_softc *);
99 :
100 : #define DEBUG_INTR 0x01
101 : #define DEBUG_XFERS 0x02
102 : #define DEBUG_STATUS 0x04
103 : #define DEBUG_FUNCS 0x08
104 : #define DEBUG_PROBE 0x10
105 : #define DEBUG_STATUSX 0x20
106 : #define DEBUG_SDRIVE 0x40
107 : #define DEBUG_DETACH 0x80
108 :
109 : #ifdef WDCDEBUG
110 : #ifndef WDCDEBUG_MASK
111 : #define WDCDEBUG_MASK 0x00
112 : #endif
113 : int wdcdebug_mask = WDCDEBUG_MASK;
114 : int wdc_nxfer = 0;
115 : #define WDCDEBUG_PRINT(args, level) do { \
116 : if ((wdcdebug_mask & (level)) != 0) \
117 : printf args; \
118 : } while (0)
119 : #else
120 : #define WDCDEBUG_PRINT(args, level)
121 : #endif /* WDCDEBUG */
122 :
123 : int at_poll = AT_POLL;
124 :
125 : int wdc_floating_bus(struct channel_softc *, int);
126 : int wdc_preata_drive(struct channel_softc *, int);
127 : int wdc_ata_present(struct channel_softc *, int);
128 :
129 : struct cfdriver wdc_cd = {
130 : NULL, "wdc", DV_DULL
131 : };
132 :
133 : struct channel_softc_vtbl wdc_default_vtbl = {
134 : wdc_default_read_reg,
135 : wdc_default_write_reg,
136 : wdc_default_lba48_write_reg,
137 : wdc_default_read_raw_multi_2,
138 : wdc_default_write_raw_multi_2,
139 : wdc_default_read_raw_multi_4,
140 : wdc_default_write_raw_multi_4
141 : };
142 :
143 : #ifdef WDCDEBUG
144 : static char *wdc_log_buf = NULL;
145 : static unsigned int wdc_tail = 0;
146 : static unsigned int wdc_head = 0;
147 : static unsigned int wdc_log_cap = 16 * 1024;
148 : static int chp_idx = 1;
149 :
150 : void
151 : wdc_log(struct channel_softc *chp, enum wdcevent_type type,
152 : unsigned int size, char val[])
153 : {
154 : unsigned int request_size;
155 : char *ptr;
156 : int log_size;
157 : unsigned int head = wdc_head;
158 : unsigned int tail = wdc_tail;
159 :
160 : #ifdef DIAGNOSTIC
161 : if (head < 0 || head > wdc_log_cap ||
162 : tail < 0 || tail > wdc_log_cap) {
163 : printf ("wdc_log: head %x wdc_tail %x\n", head,
164 : tail);
165 : return;
166 : }
167 :
168 : if (size > wdc_log_cap / 2) {
169 : printf ("wdc_log: type %d size %x\n", type, size);
170 : return;
171 : }
172 : #endif
173 :
174 : if (wdc_log_buf == NULL) {
175 : wdc_log_buf = malloc(wdc_log_cap, M_DEVBUF, M_NOWAIT);
176 : if (wdc_log_buf == NULL)
177 : return;
178 : }
179 : if (chp->ch_log_idx == 0)
180 : chp->ch_log_idx = chp_idx++;
181 :
182 : request_size = size + 2;
183 :
184 : /* Check how many bytes are left */
185 : log_size = head - tail;
186 : if (log_size < 0) log_size += wdc_log_cap;
187 :
188 : if (log_size + request_size >= wdc_log_cap) {
189 : int nb = 0;
190 : int rec_size;
191 :
192 : while (nb <= (request_size * 2)) {
193 : if (wdc_log_buf[tail] == 0)
194 : rec_size = 1;
195 : else
196 : rec_size = (wdc_log_buf[tail + 1] & 0x1f) + 2;
197 : tail = (tail + rec_size) % wdc_log_cap;
198 : nb += rec_size;
199 : }
200 : }
201 :
202 : /* Avoid wrapping in the middle of a request */
203 : if (head + request_size >= wdc_log_cap) {
204 : memset(&wdc_log_buf[head], 0, wdc_log_cap - head);
205 : head = 0;
206 : }
207 :
208 : ptr = &wdc_log_buf[head];
209 : *ptr++ = type & 0xff;
210 : *ptr++ = ((chp->ch_log_idx & 0x7) << 5) | (size & 0x1f);
211 : memcpy(ptr, val, size);
212 :
213 : wdc_head = (head + request_size) % wdc_log_cap;
214 : wdc_tail = tail;
215 : }
216 :
217 : char *wdc_get_log(unsigned int *, unsigned int *);
218 :
219 : char *
220 : wdc_get_log(unsigned int * size, unsigned int *left)
221 : {
222 : int log_size;
223 : char *retbuf = NULL;
224 : int nb, tocopy;
225 : int s;
226 : unsigned int head = wdc_head;
227 : unsigned int tail = wdc_tail;
228 :
229 : s = splbio();
230 :
231 : log_size = (head - tail);
232 : if (left != NULL)
233 : *left = 0;
234 :
235 : if (log_size < 0)
236 : log_size += wdc_log_cap;
237 :
238 : tocopy = log_size;
239 : if ((u_int)tocopy > *size)
240 : tocopy = *size;
241 :
242 : if (wdc_log_buf == NULL) {
243 : *size = 0;
244 : *left = 0;
245 : goto out;
246 : }
247 :
248 : #ifdef DIAGNOSTIC
249 : if (head < 0 || head > wdc_log_cap ||
250 : tail < 0 || tail > wdc_log_cap) {
251 : printf ("wdc_log: head %x tail %x\n", head,
252 : tail);
253 : *size = 0;
254 : *left = 0;
255 : goto out;
256 : }
257 : #endif
258 :
259 : retbuf = malloc(tocopy, M_TEMP, M_NOWAIT);
260 : if (retbuf == NULL) {
261 : *size = 0;
262 : *left = log_size;
263 : goto out;
264 : }
265 :
266 : nb = 0;
267 : for (;;) {
268 : int rec_size;
269 :
270 : if (wdc_log_buf[tail] == 0)
271 : rec_size = 1;
272 : else
273 : rec_size = (wdc_log_buf[tail + 1] & 0x1f) + 2;
274 :
275 : if ((nb + rec_size) >= tocopy)
276 : break;
277 :
278 : memcpy(&retbuf[nb], &wdc_log_buf[tail], rec_size);
279 : tail = (tail + rec_size) % wdc_log_cap;
280 : nb += rec_size;
281 : }
282 :
283 : wdc_tail = tail;
284 : *size = nb;
285 : *left = log_size - nb;
286 :
287 : out:
288 : splx(s);
289 : return (retbuf);
290 : }
291 : #endif /* WDCDEBUG */
292 :
293 : u_int8_t
294 0 : wdc_default_read_reg(struct channel_softc *chp, enum wdc_regs reg)
295 : {
296 : #ifdef DIAGNOSTIC
297 0 : if (reg & _WDC_WRONLY) {
298 0 : printf ("wdc_default_read_reg: reading from a write-only register %d\n", reg);
299 0 : }
300 : #endif /* DIAGNOSTIC */
301 :
302 0 : if (reg & _WDC_AUX)
303 0 : return (bus_space_read_1(chp->ctl_iot, chp->ctl_ioh,
304 : reg & _WDC_REGMASK));
305 : else
306 0 : return (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
307 : reg & _WDC_REGMASK));
308 0 : }
309 :
310 : void
311 0 : wdc_default_write_reg(struct channel_softc *chp, enum wdc_regs reg, u_int8_t val)
312 : {
313 : #ifdef DIAGNOSTIC
314 0 : if (reg & _WDC_RDONLY) {
315 0 : printf ("wdc_default_write_reg: writing to a read-only register %d\n", reg);
316 0 : }
317 : #endif /* DIAGNOSTIC */
318 :
319 0 : if (reg & _WDC_AUX)
320 0 : bus_space_write_1(chp->ctl_iot, chp->ctl_ioh,
321 : reg & _WDC_REGMASK, val);
322 : else
323 0 : bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
324 : reg & _WDC_REGMASK, val);
325 0 : }
326 :
327 : void
328 0 : wdc_default_lba48_write_reg(struct channel_softc *chp, enum wdc_regs reg,
329 : u_int16_t val)
330 : {
331 : /* All registers are two byte deep FIFOs. */
332 0 : CHP_WRITE_REG(chp, reg, val >> 8);
333 0 : CHP_WRITE_REG(chp, reg, val);
334 0 : }
335 :
336 : void
337 0 : wdc_default_read_raw_multi_2(struct channel_softc *chp, void *data,
338 : unsigned int nbytes)
339 : {
340 0 : if (data == NULL) {
341 : unsigned int i;
342 :
343 0 : for (i = 0; i < nbytes; i += 2) {
344 0 : bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, 0);
345 : }
346 :
347 : return;
348 : }
349 :
350 0 : bus_space_read_raw_multi_2(chp->cmd_iot, chp->cmd_ioh, 0,
351 : data, nbytes);
352 0 : }
353 :
354 :
355 : void
356 0 : wdc_default_write_raw_multi_2(struct channel_softc *chp, void *data,
357 : unsigned int nbytes)
358 : {
359 0 : if (data == NULL) {
360 : unsigned int i;
361 :
362 0 : for (i = 0; i < nbytes; i += 2) {
363 0 : bus_space_write_2(chp->cmd_iot, chp->cmd_ioh, 0, 0);
364 : }
365 :
366 : return;
367 : }
368 :
369 0 : bus_space_write_raw_multi_2(chp->cmd_iot, chp->cmd_ioh, 0,
370 : data, nbytes);
371 0 : }
372 :
373 :
374 : void
375 0 : wdc_default_write_raw_multi_4(struct channel_softc *chp, void *data,
376 : unsigned int nbytes)
377 : {
378 0 : if (data == NULL) {
379 : unsigned int i;
380 :
381 0 : for (i = 0; i < nbytes; i += 4) {
382 0 : bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, 0, 0);
383 : }
384 :
385 : return;
386 : }
387 :
388 0 : bus_space_write_raw_multi_4(chp->cmd_iot, chp->cmd_ioh, 0,
389 : data, nbytes);
390 0 : }
391 :
392 :
393 : void
394 0 : wdc_default_read_raw_multi_4(struct channel_softc *chp, void *data,
395 : unsigned int nbytes)
396 : {
397 0 : if (data == NULL) {
398 : unsigned int i;
399 :
400 0 : for (i = 0; i < nbytes; i += 4) {
401 0 : bus_space_read_4(chp->cmd_iot, chp->cmd_ioh, 0);
402 : }
403 :
404 : return;
405 : }
406 :
407 0 : bus_space_read_raw_multi_4(chp->cmd_iot, chp->cmd_ioh, 0,
408 : data, nbytes);
409 0 : }
410 :
411 : int
412 0 : wdprint(void *aux, const char *pnp)
413 : {
414 0 : struct ata_atapi_attach *aa_link = aux;
415 0 : if (pnp)
416 0 : printf("drive at %s", pnp);
417 0 : printf(" channel %d drive %d", aa_link->aa_channel,
418 0 : aa_link->aa_drv_data->drive);
419 0 : return (UNCONF);
420 : }
421 :
422 : void
423 0 : wdc_disable_intr(struct channel_softc *chp)
424 : {
425 0 : CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_IDS);
426 0 : }
427 :
428 : void
429 0 : wdc_enable_intr(struct channel_softc *chp)
430 : {
431 0 : CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_4BIT);
432 0 : }
433 :
434 : void
435 0 : wdc_set_drive(struct channel_softc *chp, int drive)
436 : {
437 0 : CHP_WRITE_REG(chp, wdr_sdh, (drive << 4) | WDSD_IBM);
438 : WDC_LOG_SET_DRIVE(chp, drive);
439 0 : }
440 :
441 : int
442 0 : wdc_floating_bus(struct channel_softc *chp, int drive)
443 : {
444 : u_int8_t cumulative_status, status;
445 : int iter;
446 :
447 0 : wdc_set_drive(chp, drive);
448 0 : delay(10);
449 :
450 : /* Stolen from Phoenix BIOS Drive Autotyping document */
451 : cumulative_status = 0;
452 0 : for (iter = 0; iter < 100; iter++) {
453 0 : CHP_WRITE_REG(chp, wdr_seccnt, 0x7f);
454 0 : delay (1);
455 :
456 0 : status = CHP_READ_REG(chp, wdr_status);
457 :
458 : /* The other bits are meaningless if BSY is set */
459 0 : if (status & WDCS_BSY)
460 : continue;
461 :
462 0 : cumulative_status |= status;
463 :
464 : #define BAD_BIT_COMBO (WDCS_DRDY | WDCS_DSC | WDCS_DRQ | WDCS_ERR)
465 0 : if ((cumulative_status & BAD_BIT_COMBO) == BAD_BIT_COMBO)
466 0 : return 1;
467 : }
468 :
469 :
470 0 : return 0;
471 0 : }
472 :
473 : int
474 0 : wdc_preata_drive(struct channel_softc *chp, int drive)
475 : {
476 0 : if (wdc_floating_bus(chp, drive)) {
477 : WDCDEBUG_PRINT(("%s:%d:%d: floating bus detected\n",
478 : chp->wdc->sc_dev.dv_xname,
479 : chp->channel, drive), DEBUG_PROBE);
480 0 : return 0;
481 : }
482 :
483 0 : wdc_set_drive(chp, drive);
484 0 : delay(100);
485 0 : if (wdcwait(chp, WDCS_DRDY | WDCS_DRQ, WDCS_DRDY, 10000) != 0) {
486 : WDCDEBUG_PRINT(("%s:%d:%d: not ready\n",
487 : chp->wdc->sc_dev.dv_xname,
488 : chp->channel, drive), DEBUG_PROBE);
489 0 : return 0;
490 : }
491 :
492 0 : CHP_WRITE_REG(chp, wdr_command, WDCC_RECAL);
493 : WDC_LOG_ATA_CMDSHORT(chp, WDCC_RECAL);
494 0 : if (wdcwait(chp, WDCS_DRDY | WDCS_DRQ, WDCS_DRDY, 10000) != 0) {
495 : WDCDEBUG_PRINT(("%s:%d:%d: WDCC_RECAL failed\n",
496 : chp->wdc->sc_dev.dv_xname,
497 : chp->channel, drive), DEBUG_PROBE);
498 0 : return 0;
499 : }
500 :
501 0 : return 1;
502 0 : }
503 :
504 : int
505 0 : wdc_ata_present(struct channel_softc *chp, int drive)
506 : {
507 : int time_to_done;
508 : int retry_cnt = 0;
509 :
510 0 : wdc_set_drive(chp, drive);
511 0 : delay(10);
512 :
513 : retry:
514 : /*
515 : You're actually supposed to wait up to 10 seconds
516 : for DRDY. However, as a practical matter, most
517 : drives assert DRDY very quickly after dropping BSY.
518 :
519 : The 10 seconds wait is sub-optimal because, according
520 : to the ATA standard, the master should reply with 00
521 : for any reads to a non-existent slave.
522 : */
523 0 : time_to_done = wdc_wait_for_status(chp,
524 : (WDCS_DRDY | WDCS_DSC | WDCS_DRQ),
525 : (WDCS_DRDY | WDCS_DSC), 1000);
526 0 : if (time_to_done == -1) {
527 0 : if (retry_cnt == 0 && chp->ch_status == 0x00) {
528 : /* At least one flash card needs to be kicked */
529 0 : wdccommandshort(chp, drive, WDCC_CHECK_PWR);
530 0 : retry_cnt++;
531 0 : goto retry;
532 : }
533 : WDCDEBUG_PRINT(("%s:%d:%d: DRDY test timed out with status"
534 : " %02x\n",
535 : chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
536 : chp->channel, drive, chp->ch_status),
537 : DEBUG_PROBE);
538 0 : return 0;
539 : }
540 :
541 0 : if ((chp->ch_status & 0xfc) != (WDCS_DRDY | WDCS_DSC)) {
542 : WDCDEBUG_PRINT(("%s:%d:%d: status test for 0x50 failed with"
543 : " %02x\n",
544 : chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
545 : chp->channel, drive, chp->ch_status),
546 : DEBUG_PROBE);
547 :
548 0 : return 0;
549 : }
550 :
551 : WDCDEBUG_PRINT(("%s:%d:%d: waiting for ready %d msec\n",
552 : chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
553 : chp->channel, drive, time_to_done), DEBUG_PROBE);
554 :
555 : /*
556 : * Test register writability
557 : */
558 0 : CHP_WRITE_REG(chp, wdr_cyl_lo, 0xaa);
559 0 : CHP_WRITE_REG(chp, wdr_cyl_hi, 0x55);
560 0 : CHP_WRITE_REG(chp, wdr_seccnt, 0xff);
561 0 : DELAY(10);
562 :
563 0 : if (CHP_READ_REG(chp, wdr_cyl_lo) != 0xaa &&
564 0 : CHP_READ_REG(chp, wdr_cyl_hi) != 0x55) {
565 : WDCDEBUG_PRINT(("%s:%d:%d: register writability failed\n",
566 : chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
567 : chp->channel, drive), DEBUG_PROBE);
568 0 : return 0;
569 : }
570 :
571 0 : return 1;
572 0 : }
573 :
574 :
575 : /*
576 : * Test to see controller with at least one attached drive is there.
577 : * Returns a bit for each possible drive found (0x01 for drive 0,
578 : * 0x02 for drive 1).
579 : * Logic:
580 : * - If a status register is at 0x7f or 0xff, assume there is no drive here
581 : * (ISA has pull-up resistors). Similarly if the status register has
582 : * the value we last wrote to the bus (for IDE interfaces without pullups).
583 : * If no drive at all -> return.
584 : * - reset the controller, wait for it to complete (may take up to 31s !).
585 : * If timeout -> return.
586 : * - test ATA/ATAPI signatures. If at last one drive found -> return.
587 : * - try an ATA command on the master.
588 : */
589 :
590 : int
591 0 : wdcprobe(struct channel_softc *chp)
592 : {
593 : u_int8_t st0, st1, sc, sn, cl, ch;
594 : u_int8_t ret_value = 0x03;
595 : u_int8_t drive;
596 : #ifdef WDCDEBUG
597 : int savedmask = wdcdebug_mask;
598 : #endif
599 :
600 0 : if (chp->_vtbl == 0) {
601 0 : int s = splbio();
602 0 : chp->_vtbl = &wdc_default_vtbl;
603 0 : splx(s);
604 0 : }
605 :
606 : #ifdef WDCDEBUG
607 : if ((chp->ch_flags & WDCF_VERBOSE_PROBE) ||
608 : (chp->wdc &&
609 : (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)))
610 : wdcdebug_mask |= DEBUG_PROBE;
611 : #endif /* WDCDEBUG */
612 :
613 0 : if (chp->wdc == NULL ||
614 0 : (chp->wdc->cap & WDC_CAPABILITY_NO_EXTRA_RESETS) == 0) {
615 : /* Sample the statuses of drive 0 and 1 into st0 and st1 */
616 0 : wdc_set_drive(chp, 0);
617 0 : delay(10);
618 0 : st0 = CHP_READ_REG(chp, wdr_status);
619 : WDC_LOG_STATUS(chp, st0);
620 0 : wdc_set_drive(chp, 1);
621 0 : delay(10);
622 0 : st1 = CHP_READ_REG(chp, wdr_status);
623 : WDC_LOG_STATUS(chp, st1);
624 :
625 : WDCDEBUG_PRINT(("%s:%d: before reset, st0=0x%b, st1=0x%b\n",
626 : chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
627 : chp->channel, st0, WDCS_BITS, st1, WDCS_BITS),
628 : DEBUG_PROBE);
629 :
630 0 : if (st0 == 0xff || st0 == WDSD_IBM)
631 0 : ret_value &= ~0x01;
632 0 : if (st1 == 0xff || st1 == (WDSD_IBM | 0x10))
633 0 : ret_value &= ~0x02;
634 0 : if (ret_value == 0)
635 0 : return 0;
636 : }
637 :
638 : /* reset the channel */
639 0 : wdc_do_reset(chp);
640 :
641 0 : ret_value = __wdcwait_reset(chp, ret_value);
642 : WDCDEBUG_PRINT(("%s:%d: after reset, ret_value=0x%d\n",
643 : chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", chp->channel,
644 : ret_value), DEBUG_PROBE);
645 :
646 0 : if (ret_value == 0)
647 0 : return 0;
648 :
649 0 : if (chp->wdc && (chp->wdc->quirks & WDC_QUIRK_NOATAPI))
650 : goto noatapi;
651 :
652 : /*
653 : * Use signatures to find potential ATAPI drives
654 : */
655 0 : for (drive = 0; drive < 2; drive++) {
656 0 : if ((ret_value & (0x01 << drive)) == 0)
657 : continue;
658 0 : wdc_set_drive(chp, drive);
659 0 : delay(10);
660 : /* Save registers contents */
661 0 : st0 = CHP_READ_REG(chp, wdr_status);
662 0 : sc = CHP_READ_REG(chp, wdr_seccnt);
663 0 : sn = CHP_READ_REG(chp, wdr_sector);
664 0 : cl = CHP_READ_REG(chp, wdr_cyl_lo);
665 0 : ch = CHP_READ_REG(chp, wdr_cyl_hi);
666 : WDC_LOG_REG(chp, wdr_cyl_lo, (ch << 8) | cl);
667 :
668 : WDCDEBUG_PRINT(("%s:%d:%d: after reset, st=0x%b, sc=0x%x"
669 : " sn=0x%x cl=0x%x ch=0x%x\n",
670 : chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
671 : chp->channel, drive, st0, WDCS_BITS, sc, sn, cl, ch),
672 : DEBUG_PROBE);
673 : /*
674 : * This is a simplification of the test in the ATAPI
675 : * spec since not all drives seem to set the other regs
676 : * correctly.
677 : */
678 0 : if (cl == 0x14 && ch == 0xeb)
679 0 : chp->ch_drive[drive].drive_flags |= DRIVE_ATAPI;
680 : }
681 :
682 : noatapi:
683 0 : if (chp->wdc && (chp->wdc->quirks & WDC_QUIRK_NOATA))
684 : goto noata;
685 :
686 : /*
687 : * Detect ATA drives by poking around the registers
688 : */
689 0 : for (drive = 0; drive < 2; drive++) {
690 0 : if ((ret_value & (0x01 << drive)) == 0)
691 : continue;
692 0 : if (chp->ch_drive[drive].drive_flags & DRIVE_ATAPI)
693 : continue;
694 :
695 0 : wdc_disable_intr(chp);
696 : /* ATA detect */
697 0 : if (wdc_ata_present(chp, drive)) {
698 0 : chp->ch_drive[drive].drive_flags |= DRIVE_ATA;
699 0 : if (chp->wdc == NULL ||
700 0 : (chp->wdc->cap & WDC_CAPABILITY_PREATA) != 0)
701 0 : chp->ch_drive[drive].drive_flags |= DRIVE_OLD;
702 : } else {
703 0 : ret_value &= ~(1 << drive);
704 : }
705 0 : wdc_enable_intr(chp);
706 0 : }
707 :
708 : noata:
709 :
710 : #ifdef WDCDEBUG
711 : wdcdebug_mask = savedmask;
712 : #endif
713 0 : return (ret_value);
714 0 : }
715 :
716 : struct channel_queue *
717 0 : wdc_alloc_queue(void)
718 : {
719 : static int inited = 0;
720 : struct channel_queue *queue;
721 :
722 : /* Initialize global data. */
723 0 : if (inited == 0) {
724 : /* Initialize the wdc_xfer pool. */
725 0 : pool_init(&wdc_xfer_pool, sizeof(struct wdc_xfer), 0, IPL_BIO,
726 : 0, "wdcxfer", NULL);
727 0 : scsi_iopool_init(&wdc_xfer_iopool, NULL,
728 : wdc_xfer_get, wdc_xfer_put);
729 0 : inited = 1;
730 0 : }
731 :
732 0 : queue = malloc(sizeof(*queue), M_DEVBUF, M_NOWAIT);
733 0 : if (queue != NULL) {
734 0 : TAILQ_INIT(&queue->sc_xfer);
735 0 : }
736 0 : return (queue);
737 : }
738 :
739 : void
740 0 : wdc_free_queue(struct channel_queue *queue)
741 : {
742 0 : free(queue, M_DEVBUF, sizeof(*queue));
743 0 : }
744 :
745 : void
746 0 : wdcattach(struct channel_softc *chp)
747 : {
748 : int i;
749 0 : struct ata_atapi_attach aa_link;
750 : #ifdef WDCDEBUG
751 : int savedmask = wdcdebug_mask;
752 : #endif
753 :
754 0 : if (!cold)
755 0 : at_poll = AT_WAIT;
756 :
757 0 : if (chp->wdc->reset == NULL)
758 0 : chp->wdc->reset = wdc_do_reset;
759 :
760 0 : timeout_set(&chp->ch_timo, wdctimeout, chp);
761 :
762 0 : if (!chp->_vtbl)
763 0 : chp->_vtbl = &wdc_default_vtbl;
764 :
765 0 : for (i = 0; i < 2; i++) {
766 0 : chp->ch_drive[i].chnl_softc = chp;
767 0 : chp->ch_drive[i].drive = i;
768 : }
769 :
770 0 : if (chp->wdc->drv_probe != NULL) {
771 0 : chp->wdc->drv_probe(chp);
772 0 : } else {
773 0 : if (wdcprobe(chp) == 0)
774 : /* If no drives, abort attach here. */
775 0 : return;
776 : }
777 :
778 : /* ATAPI drives need settling time. Give them 250ms */
779 0 : if ((chp->ch_drive[0].drive_flags & DRIVE_ATAPI) ||
780 0 : (chp->ch_drive[1].drive_flags & DRIVE_ATAPI)) {
781 0 : delay(250 * 1000);
782 0 : }
783 :
784 : #ifdef WDCDEBUG
785 : if (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)
786 : wdcdebug_mask |= DEBUG_PROBE;
787 :
788 : if ((chp->ch_drive[0].drive_flags & DRIVE_ATAPI) ||
789 : (chp->ch_drive[1].drive_flags & DRIVE_ATAPI)) {
790 : wdcdebug_mask = DEBUG_PROBE;
791 : }
792 : #endif /* WDCDEBUG */
793 :
794 0 : for (i = 0; i < 2; i++) {
795 0 : struct ata_drive_datas *drvp = &chp->ch_drive[i];
796 :
797 : /* If controller can't do 16bit flag the drives as 32bit */
798 0 : if ((chp->wdc->cap &
799 0 : (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
800 : WDC_CAPABILITY_DATA32)
801 0 : drvp->drive_flags |= DRIVE_CAP32;
802 :
803 0 : if ((drvp->drive_flags & DRIVE) == 0)
804 0 : continue;
805 :
806 0 : if (i == 1 && ((chp->ch_drive[0].drive_flags & DRIVE) == 0))
807 0 : chp->ch_flags |= WDCF_ONESLAVE;
808 : /*
809 : * Wait a bit, some devices are weird just after a reset.
810 : * Then issue a IDENTIFY command, to try to detect slave ghost.
811 : */
812 0 : delay(5000);
813 0 : if (ata_get_params(&chp->ch_drive[i], at_poll, &drvp->id) ==
814 : CMD_OK) {
815 : /* If IDENTIFY succeeded, this is not an OLD ctrl */
816 0 : drvp->drive_flags &= ~DRIVE_OLD;
817 0 : } else {
818 0 : bzero(&drvp->id, sizeof(struct ataparams));
819 0 : drvp->drive_flags &=
820 : ~(DRIVE_ATA | DRIVE_ATAPI);
821 : WDCDEBUG_PRINT(("%s:%d:%d: IDENTIFY failed\n",
822 : chp->wdc->sc_dev.dv_xname,
823 : chp->channel, i), DEBUG_PROBE);
824 :
825 0 : if ((drvp->drive_flags & DRIVE_OLD) &&
826 0 : !wdc_preata_drive(chp, i))
827 0 : drvp->drive_flags &= ~DRIVE_OLD;
828 : }
829 0 : }
830 :
831 : WDCDEBUG_PRINT(("wdcattach: ch_drive_flags 0x%x 0x%x\n",
832 : chp->ch_drive[0].drive_flags, chp->ch_drive[1].drive_flags),
833 : DEBUG_PROBE);
834 :
835 : /* If no drives, abort here */
836 0 : if ((chp->ch_drive[0].drive_flags & DRIVE) == 0 &&
837 0 : (chp->ch_drive[1].drive_flags & DRIVE) == 0)
838 : goto exit;
839 :
840 0 : for (i = 0; i < 2; i++) {
841 0 : if ((chp->ch_drive[i].drive_flags & DRIVE) == 0) {
842 : continue;
843 : }
844 0 : bzero(&aa_link, sizeof(struct ata_atapi_attach));
845 0 : if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI)
846 0 : aa_link.aa_type = T_ATAPI;
847 : else
848 0 : aa_link.aa_type = T_ATA;
849 0 : aa_link.aa_channel = chp->channel;
850 0 : aa_link.aa_openings = 1;
851 0 : aa_link.aa_drv_data = &chp->ch_drive[i];
852 0 : config_found(&chp->wdc->sc_dev, (void *)&aa_link, wdprint);
853 0 : }
854 :
855 : /*
856 : * reset drive_flags for unattached devices, reset state for attached
857 : * ones
858 : */
859 0 : for (i = 0; i < 2; i++) {
860 0 : if (chp->ch_drive[i].drive_name[0] == 0)
861 0 : chp->ch_drive[i].drive_flags = 0;
862 : }
863 :
864 : exit:
865 : #ifdef WDCDEBUG
866 : wdcdebug_mask = savedmask;
867 : #endif
868 0 : return; /* for the ``exit'' label above */
869 0 : }
870 :
871 : /*
872 : * Start I/O on a controller, for the given channel.
873 : * The first xfer may be not for our channel if the channel queues
874 : * are shared.
875 : */
876 : void
877 0 : wdcstart(struct channel_softc *chp)
878 : {
879 : struct wdc_xfer *xfer;
880 :
881 0 : splassert(IPL_BIO);
882 :
883 : /* is there a xfer ? */
884 0 : if ((xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer)) == NULL) {
885 0 : return;
886 : }
887 :
888 : /* adjust chp, in case we have a shared queue */
889 0 : chp = xfer->chp;
890 :
891 0 : if ((chp->ch_flags & WDCF_ACTIVE) != 0 ) {
892 0 : return; /* channel already active */
893 : }
894 : #ifdef DIAGNOSTIC
895 0 : if ((chp->ch_flags & WDCF_IRQ_WAIT) != 0)
896 0 : panic("wdcstart: channel waiting for irq");
897 : #endif /* DIAGNOSTIC */
898 :
899 : WDCDEBUG_PRINT(("wdcstart: xfer %p channel %d drive %d\n", xfer,
900 : chp->channel, xfer->drive), DEBUG_XFERS);
901 0 : chp->ch_flags |= WDCF_ACTIVE;
902 0 : if (chp->ch_drive[xfer->drive].drive_flags & DRIVE_RESET) {
903 0 : chp->ch_drive[xfer->drive].drive_flags &= ~DRIVE_RESET;
904 0 : chp->ch_drive[xfer->drive].state = 0;
905 0 : }
906 0 : xfer->c_start(chp, xfer);
907 0 : }
908 :
909 : int
910 0 : wdcdetach(struct channel_softc *chp, int flags)
911 : {
912 : int s, rv;
913 :
914 0 : s = splbio();
915 0 : chp->dying = 1;
916 :
917 0 : wdc_kill_pending(chp);
918 0 : timeout_del(&chp->ch_timo);
919 :
920 0 : rv = config_detach_children((struct device *)chp->wdc, flags);
921 0 : splx(s);
922 :
923 0 : return (rv);
924 : }
925 :
926 : /*
927 : * Interrupt routine for the controller. Acknowledge the interrupt, check for
928 : * errors on the current operation, mark it done if necessary, and start the
929 : * next request. Also check for a partially done transfer, and continue with
930 : * the next chunk if so.
931 : */
932 : int
933 0 : wdcintr(void *arg)
934 : {
935 0 : struct channel_softc *chp = arg;
936 : struct wdc_xfer *xfer;
937 : u_int8_t st = 0;
938 : int ret = 0;
939 :
940 0 : if ((chp->ch_flags & WDCF_IRQ_WAIT) == 0) {
941 : /* Acknowledge interrupt by reading status */
942 0 : if (chp->_vtbl == 0)
943 0 : st = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
944 : wdr_status & _WDC_REGMASK);
945 : else
946 0 : st = CHP_READ_REG(chp, wdr_status);
947 0 : if (st == 0xff)
948 0 : return (-1);
949 :
950 : WDCDEBUG_PRINT(("wdcintr: inactive controller\n"), DEBUG_INTR);
951 0 : return ret;
952 : }
953 :
954 : WDCDEBUG_PRINT(("wdcintr\n"), DEBUG_INTR);
955 0 : xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer);
956 0 : if (chp->ch_flags & WDCF_DMA_WAIT) {
957 0 : chp->wdc->dma_status =
958 0 : (*chp->wdc->dma_finish)(chp->wdc->dma_arg, chp->channel,
959 0 : xfer->drive, 0);
960 0 : if (chp->wdc->dma_status == 0xff)
961 0 : return (-1);
962 0 : if (chp->wdc->dma_status & WDC_DMAST_NOIRQ) {
963 : /* IRQ not for us, not detected by DMA engine */
964 0 : return 0;
965 : }
966 0 : chp->ch_flags &= ~WDCF_DMA_WAIT;
967 0 : }
968 :
969 0 : chp->ch_flags &= ~WDCF_IRQ_WAIT;
970 0 : ret = xfer->c_intr(chp, xfer, 1);
971 0 : if (ret == 0) /* irq was not for us, still waiting for irq */
972 0 : chp->ch_flags |= WDCF_IRQ_WAIT;
973 0 : return (ret);
974 0 : }
975 :
976 : /* Put all disk in RESET state */
977 : void
978 0 : wdc_reset_channel(struct ata_drive_datas *drvp, int nowait)
979 : {
980 0 : struct channel_softc *chp = drvp->chnl_softc;
981 : int drive;
982 :
983 : WDCDEBUG_PRINT(("ata_reset_channel %s:%d for drive %d\n",
984 : chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive),
985 : DEBUG_FUNCS);
986 0 : (void) wdcreset(chp, nowait ? NOWAIT : VERBOSE);
987 0 : for (drive = 0; drive < 2; drive++) {
988 0 : chp->ch_drive[drive].state = 0;
989 : }
990 0 : }
991 :
992 : int
993 0 : wdcreset(struct channel_softc *chp, int flags)
994 : {
995 : int drv_mask1, drv_mask2;
996 :
997 0 : if (!chp->_vtbl)
998 0 : chp->_vtbl = &wdc_default_vtbl;
999 :
1000 0 : chp->wdc->reset(chp);
1001 :
1002 0 : if (flags & NOWAIT)
1003 0 : return 0;
1004 :
1005 0 : drv_mask1 = (chp->ch_drive[0].drive_flags & DRIVE) ? 0x01:0x00;
1006 0 : drv_mask1 |= (chp->ch_drive[1].drive_flags & DRIVE) ? 0x02:0x00;
1007 0 : drv_mask2 = __wdcwait_reset(chp, drv_mask1);
1008 :
1009 0 : if ((flags & VERBOSE) && drv_mask2 != drv_mask1) {
1010 0 : printf("%s channel %d: reset failed for",
1011 0 : chp->wdc->sc_dev.dv_xname, chp->channel);
1012 0 : if ((drv_mask1 & 0x01) != 0 && (drv_mask2 & 0x01) == 0)
1013 0 : printf(" drive 0");
1014 0 : if ((drv_mask1 & 0x02) != 0 && (drv_mask2 & 0x02) == 0)
1015 0 : printf(" drive 1");
1016 0 : printf("\n");
1017 0 : }
1018 :
1019 0 : return (drv_mask1 != drv_mask2) ? 1 : 0;
1020 0 : }
1021 :
1022 : void
1023 0 : wdc_do_reset(struct channel_softc *chp)
1024 : {
1025 0 : wdc_set_drive(chp, 0);
1026 0 : DELAY(10);
1027 0 : CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_4BIT | WDCTL_RST);
1028 0 : delay(10000);
1029 0 : CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_4BIT);
1030 0 : delay(10000);
1031 0 : }
1032 :
1033 : int
1034 0 : __wdcwait_reset(struct channel_softc *chp, int drv_mask)
1035 : {
1036 : int timeout;
1037 : u_int8_t st0, er0, st1, er1;
1038 :
1039 : /* wait for BSY to deassert */
1040 0 : for (timeout = 0; timeout < WDCNDELAY_RST; timeout++) {
1041 0 : wdc_set_drive(chp, 0);
1042 0 : delay(10);
1043 0 : st0 = CHP_READ_REG(chp, wdr_status);
1044 0 : er0 = CHP_READ_REG(chp, wdr_error);
1045 0 : wdc_set_drive(chp, 1);
1046 0 : delay(10);
1047 0 : st1 = CHP_READ_REG(chp, wdr_status);
1048 0 : er1 = CHP_READ_REG(chp, wdr_error);
1049 :
1050 0 : if ((drv_mask & 0x01) == 0) {
1051 : /* no master */
1052 0 : if ((drv_mask & 0x02) != 0 && (st1 & WDCS_BSY) == 0) {
1053 : /* No master, slave is ready, it's done */
1054 : goto end;
1055 : }
1056 0 : } else if ((drv_mask & 0x02) == 0) {
1057 : /* no slave */
1058 0 : if ((drv_mask & 0x01) != 0 && (st0 & WDCS_BSY) == 0) {
1059 : /* No slave, master is ready, it's done */
1060 : goto end;
1061 : }
1062 : } else {
1063 : /* Wait for both master and slave to be ready */
1064 0 : if ((st0 & WDCS_BSY) == 0 && (st1 & WDCS_BSY) == 0) {
1065 : goto end;
1066 : }
1067 : }
1068 0 : delay(WDCDELAY);
1069 : }
1070 : /* Reset timed out. Maybe it's because drv_mask was not right */
1071 0 : if (st0 & WDCS_BSY)
1072 0 : drv_mask &= ~0x01;
1073 0 : if (st1 & WDCS_BSY)
1074 0 : drv_mask &= ~0x02;
1075 : end:
1076 : WDCDEBUG_PRINT(("%s:%d: wdcwait_reset() end, st0=0x%b, er0=0x%x, "
1077 : "st1=0x%b, er1=0x%x, reset time=%d msec\n",
1078 : chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", chp->channel,
1079 : st0, WDCS_BITS, er0, st1, WDCS_BITS, er1,
1080 : timeout * WDCDELAY / 1000), DEBUG_PROBE);
1081 :
1082 0 : return drv_mask;
1083 : }
1084 :
1085 : /*
1086 : * Wait for a drive to be !BSY, and have mask in its status register.
1087 : * return -1 for a timeout after "timeout" ms.
1088 : */
1089 : int
1090 0 : wdc_wait_for_status(struct channel_softc *chp, int mask, int bits, int timeout)
1091 : {
1092 : u_char status;
1093 : int time = 0;
1094 :
1095 : WDCDEBUG_PRINT(("wdcwait %s:%d\n", chp->wdc ?chp->wdc->sc_dev.dv_xname
1096 : :"none", chp->channel), DEBUG_STATUS);
1097 0 : chp->ch_error = 0;
1098 :
1099 0 : timeout = timeout * 1000 / WDCDELAY; /* delay uses microseconds */
1100 :
1101 0 : for (;;) {
1102 0 : chp->ch_status = status = CHP_READ_REG(chp, wdr_status);
1103 : WDC_LOG_STATUS(chp, chp->ch_status);
1104 :
1105 0 : if (status == 0xff) {
1106 0 : if ((chp->ch_flags & WDCF_ONESLAVE)) {
1107 0 : wdc_set_drive(chp, 1);
1108 0 : chp->ch_status = status =
1109 0 : CHP_READ_REG(chp, wdr_status);
1110 : WDC_LOG_STATUS(chp, chp->ch_status);
1111 0 : }
1112 : }
1113 0 : if ((status & WDCS_BSY) == 0 && (status & mask) == bits)
1114 : break;
1115 0 : if (++time > timeout) {
1116 : WDCDEBUG_PRINT(("wdcwait: timeout, status 0x%b "
1117 : "error 0x%x\n", status, WDCS_BITS,
1118 : CHP_READ_REG(chp, wdr_error)),
1119 : DEBUG_STATUSX | DEBUG_STATUS);
1120 0 : return -1;
1121 : }
1122 0 : delay(WDCDELAY);
1123 : }
1124 0 : if (status & WDCS_ERR) {
1125 0 : chp->ch_error = CHP_READ_REG(chp, wdr_error);
1126 : WDC_LOG_ERROR(chp, chp->ch_error);
1127 :
1128 : WDCDEBUG_PRINT(("wdcwait: error %x\n", chp->ch_error),
1129 : DEBUG_STATUSX | DEBUG_STATUS);
1130 0 : }
1131 :
1132 : #ifdef WDCNDELAY_DEBUG
1133 : /* After autoconfig, there should be no long delays. */
1134 : if (!cold && time > WDCNDELAY_DEBUG) {
1135 : struct wdc_xfer *xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer);
1136 : if (xfer == NULL)
1137 : printf("%s channel %d: warning: busy-wait took %dus\n",
1138 : chp->wdc->sc_dev.dv_xname, chp->channel,
1139 : WDCDELAY * time);
1140 : else
1141 : printf("%s:%d:%d: warning: busy-wait took %dus\n",
1142 : chp->wdc->sc_dev.dv_xname, chp->channel,
1143 : xfer->drive,
1144 : WDCDELAY * time);
1145 : }
1146 : #endif /* WDCNDELAY_DEBUG */
1147 0 : return time;
1148 0 : }
1149 :
1150 : /*
1151 : * Busy-wait for DMA to complete
1152 : */
1153 : int
1154 0 : wdc_dmawait(struct channel_softc *chp, struct wdc_xfer *xfer, int timeout)
1155 : {
1156 : int time;
1157 0 : for (time = 0; time < timeout * 1000 / WDCDELAY; time++) {
1158 0 : chp->wdc->dma_status =
1159 0 : (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
1160 : chp->channel, xfer->drive, 0);
1161 0 : if ((chp->wdc->dma_status & WDC_DMAST_NOIRQ) == 0)
1162 0 : return 0;
1163 0 : if (chp->wdc->dma_status == 0xff) {
1164 0 : chp->dying = 1;
1165 0 : return -1;
1166 : }
1167 0 : delay(WDCDELAY);
1168 : }
1169 : /* timeout, force a DMA halt */
1170 0 : chp->wdc->dma_status = (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
1171 : chp->channel, xfer->drive, 1);
1172 0 : return 1;
1173 0 : }
1174 :
1175 : void
1176 0 : wdctimeout(void *arg)
1177 : {
1178 0 : struct channel_softc *chp = (struct channel_softc *)arg;
1179 : struct wdc_xfer *xfer;
1180 : int s;
1181 :
1182 : WDCDEBUG_PRINT(("wdctimeout\n"), DEBUG_FUNCS);
1183 :
1184 0 : s = splbio();
1185 0 : xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer);
1186 :
1187 : /* Did we lose a race with the interrupt? */
1188 0 : if (xfer == NULL ||
1189 0 : !timeout_triggered(&chp->ch_timo)) {
1190 0 : splx(s);
1191 0 : return;
1192 : }
1193 0 : if ((chp->ch_flags & WDCF_IRQ_WAIT) != 0) {
1194 0 : __wdcerror(chp, "timeout");
1195 0 : printf("\ttype: %s\n", (xfer->c_flags & C_ATAPI) ?
1196 : "atapi":"ata");
1197 0 : printf("\tc_bcount: %d\n", xfer->c_bcount);
1198 0 : printf("\tc_skip: %d\n", xfer->c_skip);
1199 0 : if (chp->ch_flags & WDCF_DMA_WAIT) {
1200 0 : chp->wdc->dma_status =
1201 0 : (*chp->wdc->dma_finish)(chp->wdc->dma_arg,
1202 0 : chp->channel, xfer->drive, 1);
1203 0 : chp->ch_flags &= ~WDCF_DMA_WAIT;
1204 0 : }
1205 : /*
1206 : * Call the interrupt routine. If we just missed and interrupt,
1207 : * it will do what's needed. Else, it will take the needed
1208 : * action (reset the device).
1209 : */
1210 0 : xfer->c_flags |= C_TIMEOU;
1211 0 : chp->ch_flags &= ~WDCF_IRQ_WAIT;
1212 0 : xfer->c_intr(chp, xfer, 1);
1213 0 : } else
1214 0 : __wdcerror(chp, "missing untimeout");
1215 0 : splx(s);
1216 0 : }
1217 :
1218 : /*
1219 : * Probe drive's capabilities, for use by the controller later.
1220 : * Assumes drvp points to an existing drive.
1221 : * XXX this should be a controller-indep function
1222 : */
1223 : void
1224 0 : wdc_probe_caps(struct ata_drive_datas *drvp, struct ataparams *params)
1225 : {
1226 0 : struct channel_softc *chp = drvp->chnl_softc;
1227 0 : struct wdc_softc *wdc = chp->wdc;
1228 : int i, valid_mode_found;
1229 0 : int cf_flags = drvp->cf_flags;
1230 :
1231 0 : if ((wdc->cap & (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
1232 : (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) {
1233 0 : struct ataparams params2;
1234 :
1235 : /*
1236 : * Controller claims 16 and 32 bit transfers.
1237 : * Re-do an IDENTIFY with 32-bit transfers,
1238 : * and compare results.
1239 : */
1240 0 : drvp->drive_flags |= DRIVE_CAP32;
1241 0 : ata_get_params(drvp, at_poll, ¶ms2);
1242 0 : if (bcmp(params, ¶ms2, sizeof(struct ataparams)) != 0) {
1243 : /* Not good. fall back to 16bits */
1244 0 : drvp->drive_flags &= ~DRIVE_CAP32;
1245 0 : }
1246 0 : }
1247 : #if 0 /* Some ultra-DMA drives claims to only support ATA-3. sigh */
1248 : if (params->atap_ata_major > 0x01 &&
1249 : params->atap_ata_major != 0xffff) {
1250 : for (i = 14; i > 0; i--) {
1251 : if (params->atap_ata_major & (1 << i)) {
1252 : printf("%sATA version %d\n", sep, i);
1253 : drvp->ata_vers = i;
1254 : break;
1255 : }
1256 : }
1257 : } else
1258 : #endif /* 0 */
1259 : /* Use PIO mode 3 as a default value for ATAPI devices */
1260 0 : if (drvp->drive_flags & DRIVE_ATAPI)
1261 0 : drvp->PIO_mode = 3;
1262 :
1263 : WDCDEBUG_PRINT(("wdc_probe_caps: wdc_cap 0x%x cf_flags 0x%x\n",
1264 : wdc->cap, cf_flags), DEBUG_PROBE);
1265 :
1266 : valid_mode_found = 0;
1267 :
1268 : WDCDEBUG_PRINT(("%s: atap_oldpiotiming=%d\n", __func__,
1269 : params->atap_oldpiotiming), DEBUG_PROBE);
1270 : /*
1271 : * ATA-4 compliant devices contain PIO mode
1272 : * number in atap_oldpiotiming.
1273 : */
1274 0 : if (params->atap_oldpiotiming <= 2) {
1275 0 : drvp->PIO_cap = params->atap_oldpiotiming;
1276 : valid_mode_found = 1;
1277 0 : drvp->drive_flags |= DRIVE_MODE;
1278 0 : } else if (params->atap_oldpiotiming > 180) {
1279 : /*
1280 : * ATA-2 compliant devices contain cycle
1281 : * time in atap_oldpiotiming.
1282 : * A device with a cycle time of 180ns
1283 : * or less is at least PIO mode 3 and
1284 : * should be reporting that in
1285 : * atap_piomode_supp, so ignore it here.
1286 : */
1287 0 : if (params->atap_oldpiotiming <= 240) {
1288 0 : drvp->PIO_cap = 2;
1289 0 : } else {
1290 0 : drvp->PIO_cap = 1;
1291 : }
1292 : valid_mode_found = 1;
1293 0 : drvp->drive_flags |= DRIVE_MODE;
1294 0 : }
1295 0 : if (valid_mode_found)
1296 0 : drvp->PIO_mode = drvp->PIO_cap;
1297 :
1298 : WDCDEBUG_PRINT(("%s: atap_extensions=0x%x, atap_piomode_supp=0x%x, "
1299 : "atap_dmamode_supp=0x%x, atap_udmamode_supp=0x%x\n",
1300 : __func__, params->atap_extensions, params->atap_piomode_supp,
1301 : params->atap_dmamode_supp, params->atap_udmamode_supp),
1302 : DEBUG_PROBE);
1303 :
1304 : /*
1305 : * It's not in the specs, but it seems that some drive
1306 : * returns 0xffff in atap_extensions when this field is invalid
1307 : */
1308 0 : if (params->atap_extensions != 0xffff &&
1309 0 : (params->atap_extensions & WDC_EXT_MODES)) {
1310 : /*
1311 : * XXX some drives report something wrong here (they claim to
1312 : * support PIO mode 8 !). As mode is coded on 3 bits in
1313 : * SET FEATURE, limit it to 7 (so limit i to 4).
1314 : * If higher mode than 7 is found, abort.
1315 : */
1316 0 : for (i = 7; i >= 0; i--) {
1317 0 : if ((params->atap_piomode_supp & (1 << i)) == 0)
1318 : continue;
1319 0 : if (i > 4)
1320 0 : return;
1321 :
1322 : valid_mode_found = 1;
1323 :
1324 0 : if ((wdc->cap & WDC_CAPABILITY_MODE) == 0) {
1325 0 : drvp->PIO_cap = i + 3;
1326 0 : continue;
1327 : }
1328 :
1329 : /*
1330 : * See if mode is accepted.
1331 : * If the controller can't set its PIO mode,
1332 : * assume the BIOS set it up correctly
1333 : */
1334 0 : if (ata_set_mode(drvp, 0x08 | (i + 3),
1335 0 : at_poll) != CMD_OK)
1336 : continue;
1337 :
1338 : /*
1339 : * If controller's driver can't set its PIO mode,
1340 : * set the highest one the controller supports
1341 : */
1342 0 : if (wdc->PIO_cap >= i + 3) {
1343 0 : drvp->PIO_mode = i + 3;
1344 0 : drvp->PIO_cap = i + 3;
1345 0 : break;
1346 : }
1347 : }
1348 0 : if (!valid_mode_found) {
1349 : /*
1350 : * We didn't find a valid PIO mode.
1351 : * Assume the values returned for DMA are buggy too
1352 : */
1353 0 : return;
1354 : }
1355 0 : drvp->drive_flags |= DRIVE_MODE;
1356 :
1357 : /* Some controllers don't support ATAPI DMA */
1358 0 : if ((drvp->drive_flags & DRIVE_ATAPI) &&
1359 0 : (wdc->cap & WDC_CAPABILITY_NO_ATAPI_DMA))
1360 0 : return;
1361 :
1362 : valid_mode_found = 0;
1363 0 : for (i = 7; i >= 0; i--) {
1364 0 : if ((params->atap_dmamode_supp & (1 << i)) == 0)
1365 : continue;
1366 0 : if ((wdc->cap & WDC_CAPABILITY_DMA) &&
1367 0 : (wdc->cap & WDC_CAPABILITY_MODE))
1368 0 : if (ata_set_mode(drvp, 0x20 | i, at_poll)
1369 0 : != CMD_OK)
1370 : continue;
1371 :
1372 : valid_mode_found = 1;
1373 :
1374 0 : if (wdc->cap & WDC_CAPABILITY_DMA) {
1375 0 : if ((wdc->cap & WDC_CAPABILITY_MODE) &&
1376 0 : wdc->DMA_cap < i)
1377 : continue;
1378 0 : drvp->DMA_mode = i;
1379 0 : drvp->DMA_cap = i;
1380 0 : drvp->drive_flags |= DRIVE_DMA;
1381 0 : }
1382 : break;
1383 : }
1384 0 : if (params->atap_extensions & WDC_EXT_UDMA_MODES) {
1385 0 : for (i = 7; i >= 0; i--) {
1386 0 : if ((params->atap_udmamode_supp & (1 << i))
1387 0 : == 0)
1388 : continue;
1389 0 : if ((wdc->cap & WDC_CAPABILITY_MODE) &&
1390 0 : (wdc->cap & WDC_CAPABILITY_UDMA))
1391 0 : if (ata_set_mode(drvp, 0x40 | i,
1392 0 : at_poll) != CMD_OK)
1393 : continue;
1394 0 : if (wdc->cap & WDC_CAPABILITY_UDMA) {
1395 0 : if ((wdc->cap & WDC_CAPABILITY_MODE) &&
1396 0 : wdc->UDMA_cap < i)
1397 : continue;
1398 0 : drvp->UDMA_mode = i;
1399 0 : drvp->UDMA_cap = i;
1400 0 : drvp->drive_flags |= DRIVE_UDMA;
1401 0 : }
1402 : break;
1403 : }
1404 : }
1405 : }
1406 :
1407 : /* Try to guess ATA version here, if it didn't get reported */
1408 0 : if (drvp->ata_vers == 0) {
1409 0 : if (drvp->drive_flags & DRIVE_UDMA)
1410 0 : drvp->ata_vers = 4; /* should be at last ATA-4 */
1411 0 : else if (drvp->PIO_cap > 2)
1412 0 : drvp->ata_vers = 2; /* should be at last ATA-2 */
1413 : }
1414 0 : if (cf_flags & ATA_CONFIG_PIO_SET) {
1415 0 : drvp->PIO_mode =
1416 0 : (cf_flags & ATA_CONFIG_PIO_MODES) >> ATA_CONFIG_PIO_OFF;
1417 0 : drvp->drive_flags |= DRIVE_MODE;
1418 0 : }
1419 0 : if ((wdc->cap & WDC_CAPABILITY_DMA) == 0) {
1420 : /* don't care about DMA modes */
1421 0 : return;
1422 : }
1423 0 : if (cf_flags & ATA_CONFIG_DMA_SET) {
1424 0 : if ((cf_flags & ATA_CONFIG_DMA_MODES) ==
1425 : ATA_CONFIG_DMA_DISABLE) {
1426 0 : drvp->drive_flags &= ~DRIVE_DMA;
1427 0 : } else {
1428 0 : drvp->DMA_mode = (cf_flags & ATA_CONFIG_DMA_MODES) >>
1429 : ATA_CONFIG_DMA_OFF;
1430 0 : drvp->drive_flags |= DRIVE_DMA | DRIVE_MODE;
1431 : }
1432 : }
1433 0 : if ((wdc->cap & WDC_CAPABILITY_UDMA) == 0) {
1434 : /* don't care about UDMA modes */
1435 0 : return;
1436 : }
1437 0 : if (cf_flags & ATA_CONFIG_UDMA_SET) {
1438 0 : if ((cf_flags & ATA_CONFIG_UDMA_MODES) ==
1439 : ATA_CONFIG_UDMA_DISABLE) {
1440 0 : drvp->drive_flags &= ~DRIVE_UDMA;
1441 0 : } else {
1442 0 : drvp->UDMA_mode = (cf_flags & ATA_CONFIG_UDMA_MODES) >>
1443 : ATA_CONFIG_UDMA_OFF;
1444 0 : drvp->drive_flags |= DRIVE_UDMA | DRIVE_MODE;
1445 : }
1446 : }
1447 0 : }
1448 :
1449 : void
1450 0 : wdc_output_bytes(struct ata_drive_datas *drvp, void *bytes, unsigned int buflen)
1451 : {
1452 0 : struct channel_softc *chp = drvp->chnl_softc;
1453 : unsigned int off = 0;
1454 : unsigned int len = buflen, roundlen;
1455 :
1456 0 : if (drvp->drive_flags & DRIVE_CAP32) {
1457 0 : roundlen = len & ~3;
1458 :
1459 0 : CHP_WRITE_RAW_MULTI_4(chp,
1460 : (void *)((u_int8_t *)bytes + off), roundlen);
1461 :
1462 : off += roundlen;
1463 0 : len -= roundlen;
1464 0 : }
1465 :
1466 0 : if (len > 0) {
1467 0 : roundlen = (len + 1) & ~0x1;
1468 :
1469 0 : CHP_WRITE_RAW_MULTI_2(chp,
1470 : (void *)((u_int8_t *)bytes + off), roundlen);
1471 0 : }
1472 0 : }
1473 :
1474 : void
1475 0 : wdc_input_bytes(struct ata_drive_datas *drvp, void *bytes, unsigned int buflen)
1476 : {
1477 0 : struct channel_softc *chp = drvp->chnl_softc;
1478 : unsigned int off = 0;
1479 : unsigned int len = buflen, roundlen;
1480 :
1481 0 : if (drvp->drive_flags & DRIVE_CAP32) {
1482 0 : roundlen = len & ~3;
1483 :
1484 0 : CHP_READ_RAW_MULTI_4(chp,
1485 : (void *)((u_int8_t *)bytes + off), roundlen);
1486 :
1487 : off += roundlen;
1488 0 : len -= roundlen;
1489 0 : }
1490 :
1491 0 : if (len > 0) {
1492 0 : roundlen = (len + 1) & ~0x1;
1493 :
1494 0 : CHP_READ_RAW_MULTI_2(chp,
1495 : (void *)((u_int8_t *)bytes + off), roundlen);
1496 0 : }
1497 0 : }
1498 :
1499 : void
1500 0 : wdc_print_caps(struct ata_drive_datas *drvp)
1501 : {
1502 : /* This is actually a lie until we fix the _probe_caps
1503 : algorithm. Don't print out lies */
1504 : #if 0
1505 : printf("%s: can use ", drvp->drive_name);
1506 :
1507 : if (drvp->drive_flags & DRIVE_CAP32) {
1508 : printf("32-bit");
1509 : } else
1510 : printf("16-bit");
1511 :
1512 : printf(", PIO mode %d", drvp->PIO_cap);
1513 :
1514 : if (drvp->drive_flags & DRIVE_DMA) {
1515 : printf(", DMA mode %d", drvp->DMA_cap);
1516 : }
1517 :
1518 : if (drvp->drive_flags & DRIVE_UDMA) {
1519 : printf(", Ultra-DMA mode %d", drvp->UDMA_cap);
1520 : }
1521 :
1522 : printf("\n");
1523 : #endif /* 0 */
1524 0 : }
1525 :
1526 : void
1527 0 : wdc_print_current_modes(struct channel_softc *chp)
1528 : {
1529 : int drive;
1530 : struct ata_drive_datas *drvp;
1531 :
1532 0 : for (drive = 0; drive < 2; drive++) {
1533 0 : drvp = &chp->ch_drive[drive];
1534 0 : if ((drvp->drive_flags & DRIVE) == 0)
1535 : continue;
1536 :
1537 0 : printf("%s(%s:%d:%d):",
1538 0 : drvp->drive_name,
1539 0 : chp->wdc->sc_dev.dv_xname, chp->channel, drive);
1540 :
1541 0 : if ((chp->wdc->cap & WDC_CAPABILITY_MODE) == 0 &&
1542 0 : !(drvp->cf_flags & ATA_CONFIG_PIO_SET))
1543 0 : printf(" using BIOS timings");
1544 : else
1545 0 : printf(" using PIO mode %d", drvp->PIO_mode);
1546 0 : if (drvp->drive_flags & DRIVE_DMA)
1547 0 : printf(", DMA mode %d", drvp->DMA_mode);
1548 0 : if (drvp->drive_flags & DRIVE_UDMA)
1549 0 : printf(", Ultra-DMA mode %d", drvp->UDMA_mode);
1550 0 : printf("\n");
1551 0 : }
1552 0 : }
1553 :
1554 : /*
1555 : * downgrade the transfer mode of a drive after an error. return 1 if
1556 : * downgrade was possible, 0 otherwise.
1557 : */
1558 : int
1559 0 : wdc_downgrade_mode(struct ata_drive_datas *drvp)
1560 : {
1561 0 : struct channel_softc *chp = drvp->chnl_softc;
1562 0 : struct wdc_softc *wdc = chp->wdc;
1563 0 : int cf_flags = drvp->cf_flags;
1564 :
1565 : /* if drive or controller don't know its mode, we can't do much */
1566 0 : if ((drvp->drive_flags & DRIVE_MODE) == 0 ||
1567 0 : (wdc->cap & WDC_CAPABILITY_MODE) == 0)
1568 0 : return 0;
1569 : /* current drive mode was set by a config flag, let it this way */
1570 0 : if ((cf_flags & ATA_CONFIG_PIO_SET) ||
1571 0 : (cf_flags & ATA_CONFIG_DMA_SET) ||
1572 0 : (cf_flags & ATA_CONFIG_UDMA_SET))
1573 0 : return 0;
1574 :
1575 : /*
1576 : * We'd ideally like to use an Ultra DMA mode since they have the
1577 : * protection of a CRC. So we try each Ultra DMA mode and see if
1578 : * we can find any working combo
1579 : */
1580 0 : if ((drvp->drive_flags & DRIVE_UDMA) && drvp->UDMA_mode > 0) {
1581 0 : drvp->UDMA_mode = drvp->UDMA_mode - 1;
1582 0 : printf("%s: transfer error, downgrading to Ultra-DMA mode %d\n",
1583 0 : drvp->drive_name, drvp->UDMA_mode);
1584 0 : } else if ((drvp->drive_flags & DRIVE_UDMA) &&
1585 0 : (drvp->drive_flags & DRIVE_DMAERR) == 0) {
1586 : /*
1587 : * If we were using ultra-DMA, don't downgrade to
1588 : * multiword DMA if we noticed a CRC error. It has
1589 : * been noticed that CRC errors in ultra-DMA lead to
1590 : * silent data corruption in multiword DMA. Data
1591 : * corruption is less likely to occur in PIO mode.
1592 : */
1593 0 : drvp->drive_flags &= ~DRIVE_UDMA;
1594 0 : drvp->drive_flags |= DRIVE_DMA;
1595 0 : drvp->DMA_mode = drvp->DMA_cap;
1596 0 : printf("%s: transfer error, downgrading to DMA mode %d\n",
1597 0 : drvp->drive_name, drvp->DMA_mode);
1598 0 : } else if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) {
1599 0 : drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
1600 0 : drvp->PIO_mode = drvp->PIO_cap;
1601 0 : printf("%s: transfer error, downgrading to PIO mode %d\n",
1602 0 : drvp->drive_name, drvp->PIO_mode);
1603 : } else /* already using PIO, can't downgrade */
1604 0 : return 0;
1605 :
1606 0 : wdc->set_modes(chp);
1607 : /* reset the channel, which will schedule all drives for setup */
1608 0 : wdc_reset_channel(drvp, 0);
1609 0 : return 1;
1610 0 : }
1611 :
1612 : int
1613 0 : wdc_exec_command(struct ata_drive_datas *drvp, struct wdc_command *wdc_c)
1614 : {
1615 0 : struct channel_softc *chp = drvp->chnl_softc;
1616 : struct wdc_xfer *xfer;
1617 : int s, ret;
1618 :
1619 : WDCDEBUG_PRINT(("wdc_exec_command %s:%d:%d\n",
1620 : chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive),
1621 : DEBUG_FUNCS);
1622 :
1623 : /* set up an xfer and queue. Wait for completion */
1624 0 : xfer = wdc_get_xfer(wdc_c->flags & AT_WAIT ? WDC_CANSLEEP :
1625 : WDC_NOSLEEP);
1626 0 : if (xfer == NULL) {
1627 0 : return WDC_TRY_AGAIN;
1628 : }
1629 :
1630 0 : if (wdc_c->flags & AT_POLL)
1631 0 : xfer->c_flags |= C_POLL;
1632 0 : xfer->drive = drvp->drive;
1633 0 : xfer->databuf = wdc_c->data;
1634 0 : xfer->c_bcount = wdc_c->bcount;
1635 0 : xfer->cmd = wdc_c;
1636 0 : xfer->c_start = __wdccommand_start;
1637 0 : xfer->c_intr = __wdccommand_intr;
1638 0 : xfer->c_kill_xfer = __wdccommand_done;
1639 :
1640 0 : s = splbio();
1641 0 : wdc_exec_xfer(chp, xfer);
1642 : #ifdef DIAGNOSTIC
1643 0 : if ((wdc_c->flags & AT_POLL) != 0 &&
1644 0 : (wdc_c->flags & AT_DONE) == 0)
1645 0 : panic("wdc_exec_command: polled command not done");
1646 : #endif /* DIAGNOSTIC */
1647 0 : if (wdc_c->flags & AT_DONE) {
1648 : ret = WDC_COMPLETE;
1649 0 : } else {
1650 0 : if (wdc_c->flags & AT_WAIT) {
1651 : WDCDEBUG_PRINT(("wdc_exec_command sleeping\n"),
1652 : DEBUG_FUNCS);
1653 :
1654 0 : while ((wdc_c->flags & AT_DONE) == 0) {
1655 0 : tsleep(wdc_c, PRIBIO, "wdccmd", 0);
1656 : }
1657 : ret = WDC_COMPLETE;
1658 0 : } else {
1659 : ret = WDC_QUEUED;
1660 : }
1661 : }
1662 0 : splx(s);
1663 0 : return ret;
1664 0 : }
1665 :
1666 : void
1667 0 : __wdccommand_start(struct channel_softc *chp, struct wdc_xfer *xfer)
1668 : {
1669 0 : int drive = xfer->drive;
1670 0 : struct wdc_command *wdc_c = xfer->cmd;
1671 :
1672 : WDCDEBUG_PRINT(("__wdccommand_start %s:%d:%d\n",
1673 : chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
1674 : DEBUG_FUNCS);
1675 :
1676 : /*
1677 : * Disable interrupts if we're polling
1678 : */
1679 0 : if (xfer->c_flags & C_POLL) {
1680 0 : wdc_disable_intr(chp);
1681 0 : }
1682 :
1683 0 : wdc_set_drive(chp, drive);
1684 0 : DELAY(1);
1685 :
1686 : /*
1687 : * For resets, we don't really care to make sure that
1688 : * the bus is free
1689 : */
1690 0 : if (wdc_c->r_command != ATAPI_SOFT_RESET) {
1691 0 : if (wdcwait(chp, wdc_c->r_st_bmask | WDCS_DRQ,
1692 0 : wdc_c->r_st_bmask, wdc_c->timeout) != 0) {
1693 : goto timeout;
1694 : }
1695 : } else
1696 0 : DELAY(10);
1697 :
1698 0 : wdccommand(chp, drive, wdc_c->r_command, wdc_c->r_cyl, wdc_c->r_head,
1699 0 : wdc_c->r_sector, wdc_c->r_count, wdc_c->r_features);
1700 :
1701 0 : if ((wdc_c->flags & AT_WRITE) == AT_WRITE) {
1702 : /* wait at least 400ns before reading status register */
1703 0 : DELAY(10);
1704 0 : if (wait_for_unbusy(chp, wdc_c->timeout) != 0)
1705 : goto timeout;
1706 :
1707 0 : if ((chp->ch_status & (WDCS_DRQ | WDCS_ERR)) == WDCS_ERR) {
1708 0 : __wdccommand_done(chp, xfer);
1709 0 : return;
1710 : }
1711 :
1712 0 : if (wait_for_drq(chp, wdc_c->timeout) != 0)
1713 : goto timeout;
1714 :
1715 0 : wdc_output_bytes(&chp->ch_drive[drive],
1716 0 : wdc_c->data, wdc_c->bcount);
1717 0 : }
1718 :
1719 0 : if ((wdc_c->flags & AT_POLL) == 0) {
1720 0 : chp->ch_flags |= WDCF_IRQ_WAIT; /* wait for interrupt */
1721 0 : timeout_add_msec(&chp->ch_timo, wdc_c->timeout);
1722 0 : return;
1723 : }
1724 :
1725 : /*
1726 : * Polled command. Wait for drive ready or drq. Done in intr().
1727 : * Wait for at last 400ns for status bit to be valid.
1728 : */
1729 0 : delay(10);
1730 0 : __wdccommand_intr(chp, xfer, 0);
1731 0 : return;
1732 :
1733 : timeout:
1734 0 : wdc_c->flags |= AT_TIMEOU;
1735 0 : __wdccommand_done(chp, xfer);
1736 0 : }
1737 :
1738 : int
1739 0 : __wdccommand_intr(struct channel_softc *chp, struct wdc_xfer *xfer, int irq)
1740 : {
1741 0 : struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
1742 0 : struct wdc_command *wdc_c = xfer->cmd;
1743 0 : int bcount = wdc_c->bcount;
1744 0 : char *data = wdc_c->data;
1745 :
1746 : WDCDEBUG_PRINT(("__wdccommand_intr %s:%d:%d\n",
1747 : chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), DEBUG_INTR);
1748 0 : if (wdcwait(chp, wdc_c->r_st_pmask, wdc_c->r_st_pmask,
1749 : (irq == 0) ? wdc_c->timeout : 0)) {
1750 0 : if (chp->dying) {
1751 0 : __wdccommand_done(chp, xfer);
1752 0 : return -1;
1753 : }
1754 0 : if (irq && (xfer->c_flags & C_TIMEOU) == 0)
1755 0 : return 0; /* IRQ was not for us */
1756 0 : wdc_c->flags |= AT_TIMEOU;
1757 0 : goto out;
1758 : }
1759 0 : if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
1760 0 : chp->wdc->irqack(chp);
1761 0 : if (wdc_c->flags & AT_READ) {
1762 0 : if ((chp->ch_status & WDCS_DRQ) == 0) {
1763 0 : wdc_c->flags |= AT_TIMEOU;
1764 0 : goto out;
1765 : }
1766 0 : wdc_input_bytes(drvp, data, bcount);
1767 : /* Should we wait for device to indicate idle? */
1768 0 : }
1769 : out:
1770 0 : __wdccommand_done(chp, xfer);
1771 : WDCDEBUG_PRINT(("__wdccommand_intr returned\n"), DEBUG_INTR);
1772 0 : return 1;
1773 0 : }
1774 :
1775 : void
1776 0 : __wdccommand_done(struct channel_softc *chp, struct wdc_xfer *xfer)
1777 : {
1778 0 : struct wdc_command *wdc_c = xfer->cmd;
1779 :
1780 : WDCDEBUG_PRINT(("__wdccommand_done %s:%d:%d %02x\n",
1781 : chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
1782 : chp->ch_status), DEBUG_FUNCS);
1783 0 : if (chp->dying)
1784 : goto killit;
1785 0 : if (chp->ch_status & WDCS_DWF)
1786 0 : wdc_c->flags |= AT_DF;
1787 0 : if (chp->ch_status & WDCS_ERR) {
1788 0 : wdc_c->flags |= AT_ERROR;
1789 0 : wdc_c->r_error = chp->ch_error;
1790 0 : }
1791 0 : wdc_c->flags |= AT_DONE;
1792 0 : if ((wdc_c->flags & AT_READREG) != 0 &&
1793 0 : (wdc_c->flags & (AT_ERROR | AT_DF)) == 0) {
1794 0 : wdc_c->r_head = CHP_READ_REG(chp, wdr_sdh);
1795 0 : wdc_c->r_cyl = CHP_READ_REG(chp, wdr_cyl_hi) << 8;
1796 0 : wdc_c->r_cyl |= CHP_READ_REG(chp, wdr_cyl_lo);
1797 0 : wdc_c->r_sector = CHP_READ_REG(chp, wdr_sector);
1798 0 : wdc_c->r_count = CHP_READ_REG(chp, wdr_seccnt);
1799 0 : wdc_c->r_error = CHP_READ_REG(chp, wdr_error);
1800 0 : wdc_c->r_features = wdc_c->r_error;
1801 0 : }
1802 :
1803 : killit:
1804 0 : if (xfer->c_flags & C_POLL) {
1805 0 : wdc_enable_intr(chp);
1806 0 : } else
1807 0 : timeout_del(&chp->ch_timo);
1808 :
1809 0 : wdc_free_xfer(chp, xfer);
1810 : WDCDEBUG_PRINT(("__wdccommand_done before callback\n"), DEBUG_INTR);
1811 :
1812 0 : if (chp->dying)
1813 0 : return;
1814 :
1815 0 : if (wdc_c->flags & AT_WAIT)
1816 0 : wakeup(wdc_c);
1817 : else
1818 0 : if (wdc_c->callback)
1819 0 : wdc_c->callback(wdc_c->callback_arg);
1820 0 : wdcstart(chp);
1821 : WDCDEBUG_PRINT(("__wdccommand_done returned\n"), DEBUG_INTR);
1822 0 : }
1823 :
1824 : /*
1825 : * Send a command. The drive should be ready.
1826 : * Assumes interrupts are blocked.
1827 : */
1828 : void
1829 0 : wdccommand(struct channel_softc *chp, u_int8_t drive, u_int8_t command,
1830 : u_int16_t cylin, u_int8_t head, u_int8_t sector, u_int8_t count,
1831 : u_int8_t features)
1832 : {
1833 : WDCDEBUG_PRINT(("wdccommand %s:%d:%d: command=0x%x cylin=%d head=%d "
1834 : "sector=%d count=%d features=%d\n", chp->wdc->sc_dev.dv_xname,
1835 : chp->channel, drive, command, cylin, head, sector, count, features),
1836 : DEBUG_FUNCS);
1837 : WDC_LOG_ATA_CMDLONG(chp, head, features, cylin, cylin >> 8, sector,
1838 : count, command);
1839 :
1840 : /* Select drive, head, and addressing mode. */
1841 0 : CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (drive << 4) | head);
1842 :
1843 : /* Load parameters. */
1844 0 : CHP_WRITE_REG(chp, wdr_features, features);
1845 0 : CHP_WRITE_REG(chp, wdr_cyl_lo, cylin);
1846 0 : CHP_WRITE_REG(chp, wdr_cyl_hi, cylin >> 8);
1847 0 : CHP_WRITE_REG(chp, wdr_sector, sector);
1848 0 : CHP_WRITE_REG(chp, wdr_seccnt, count);
1849 :
1850 : /* Send command. */
1851 0 : CHP_WRITE_REG(chp, wdr_command, command);
1852 0 : }
1853 :
1854 : /*
1855 : * Send a 48-bit addressing command. The drive should be ready.
1856 : * Assumes interrupts are blocked.
1857 : */
1858 : void
1859 0 : wdccommandext(struct channel_softc *chp, u_int8_t drive, u_int8_t command,
1860 : u_int64_t blkno, u_int16_t count)
1861 : {
1862 : WDCDEBUG_PRINT(("wdccommandext %s:%d:%d: command=0x%x blkno=%llu "
1863 : "count=%d\n", chp->wdc->sc_dev.dv_xname,
1864 : chp->channel, drive, command, blkno, count),
1865 : DEBUG_FUNCS);
1866 : WDC_LOG_ATA_CMDEXT(chp, blkno >> 40, blkno >> 16, blkno >> 32,
1867 : blkno >> 8, blkno >> 24, blkno, count >> 8, count, command);
1868 :
1869 : /* Select drive and LBA mode. */
1870 0 : CHP_WRITE_REG(chp, wdr_sdh, (drive << 4) | WDSD_LBA);
1871 :
1872 : /* Load parameters. */
1873 0 : CHP_LBA48_WRITE_REG(chp, wdr_lba_hi,
1874 : ((blkno >> 32) & 0xff00) | ((blkno >> 16) & 0xff));
1875 0 : CHP_LBA48_WRITE_REG(chp, wdr_lba_mi,
1876 : ((blkno >> 24) & 0xff00) | ((blkno >> 8) & 0xff));
1877 0 : CHP_LBA48_WRITE_REG(chp, wdr_lba_lo,
1878 : ((blkno >> 16) & 0xff00) | (blkno & 0xff));
1879 0 : CHP_LBA48_WRITE_REG(chp, wdr_seccnt, count);
1880 :
1881 : /* Send command. */
1882 0 : CHP_WRITE_REG(chp, wdr_command, command);
1883 0 : }
1884 :
1885 : /*
1886 : * Simplified version of wdccommand(). Unbusy/ready/drq must be
1887 : * tested by the caller.
1888 : */
1889 : void
1890 0 : wdccommandshort(struct channel_softc *chp, int drive, int command)
1891 : {
1892 :
1893 : WDCDEBUG_PRINT(("wdccommandshort %s:%d:%d command 0x%x\n",
1894 : chp->wdc->sc_dev.dv_xname, chp->channel, drive, command),
1895 : DEBUG_FUNCS);
1896 : WDC_LOG_ATA_CMDSHORT(chp, command);
1897 :
1898 : /* Select drive. */
1899 0 : CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (drive << 4));
1900 0 : CHP_WRITE_REG(chp, wdr_command, command);
1901 0 : }
1902 :
1903 : /* Add a command to the queue and start controller. Must be called at splbio */
1904 :
1905 : void
1906 0 : wdc_exec_xfer(struct channel_softc *chp, struct wdc_xfer *xfer)
1907 : {
1908 : WDCDEBUG_PRINT(("wdc_exec_xfer %p flags 0x%x channel %d drive %d\n",
1909 : xfer, xfer->c_flags, chp->channel, xfer->drive), DEBUG_XFERS);
1910 :
1911 : /* complete xfer setup */
1912 0 : xfer->chp = chp;
1913 :
1914 : /*
1915 : * If we are a polled command, and the list is not empty,
1916 : * we are doing a dump. Drop the list to allow the polled command
1917 : * to complete, we're going to reboot soon anyway.
1918 : */
1919 0 : if ((xfer->c_flags & C_POLL) != 0 &&
1920 0 : !TAILQ_EMPTY(&chp->ch_queue->sc_xfer)) {
1921 0 : TAILQ_INIT(&chp->ch_queue->sc_xfer);
1922 0 : }
1923 : /* insert at the end of command list */
1924 0 : TAILQ_INSERT_TAIL(&chp->ch_queue->sc_xfer,xfer , c_xferchain);
1925 : WDCDEBUG_PRINT(("wdcstart from wdc_exec_xfer, flags 0x%x\n",
1926 : chp->ch_flags), DEBUG_XFERS);
1927 0 : wdcstart(chp);
1928 0 : }
1929 :
1930 : void *
1931 0 : wdc_xfer_get(void *null)
1932 : {
1933 0 : return (pool_get(&wdc_xfer_pool, PR_NOWAIT | PR_ZERO));
1934 : }
1935 :
1936 : void
1937 0 : wdc_scrub_xfer(struct wdc_xfer *xfer)
1938 : {
1939 0 : memset(xfer, 0, sizeof(*xfer));
1940 0 : xfer->c_flags = C_SCSIXFER;
1941 0 : }
1942 :
1943 : void
1944 0 : wdc_xfer_put(void *null, void *xxfer)
1945 : {
1946 0 : struct wdc_xfer *xfer = xxfer;
1947 : int put = 0;
1948 : int s;
1949 :
1950 0 : s = splbio();
1951 0 : if (ISSET(xfer->c_flags, C_SCSIXFER))
1952 0 : CLR(xfer->c_flags, C_SCSIXFER);
1953 : else
1954 : put = 1;
1955 0 : splx(s);
1956 :
1957 0 : if (put)
1958 0 : pool_put(&wdc_xfer_pool, xfer);
1959 0 : }
1960 :
1961 : struct wdc_xfer *
1962 0 : wdc_get_xfer(int flags)
1963 : {
1964 0 : return (scsi_io_get(&wdc_xfer_iopool,
1965 0 : ISSET(flags, WDC_NOSLEEP) ? SCSI_NOSLEEP : 0));
1966 : }
1967 :
1968 : void
1969 0 : wdc_free_xfer(struct channel_softc *chp, struct wdc_xfer *xfer)
1970 : {
1971 : int put = 0;
1972 : int s;
1973 :
1974 0 : if (xfer->c_flags & C_PRIVATEXFER) {
1975 0 : chp->ch_flags &= ~WDCF_ACTIVE;
1976 0 : TAILQ_REMOVE(&chp->ch_queue->sc_xfer, xfer, c_xferchain);
1977 0 : return;
1978 : }
1979 :
1980 0 : s = splbio();
1981 0 : chp->ch_flags &= ~WDCF_ACTIVE;
1982 0 : TAILQ_REMOVE(&chp->ch_queue->sc_xfer, xfer, c_xferchain);
1983 0 : if (ISSET(xfer->c_flags, C_SCSIXFER))
1984 0 : CLR(xfer->c_flags, C_SCSIXFER);
1985 : else
1986 : put = 1;
1987 0 : splx(s);
1988 :
1989 0 : if (put)
1990 0 : scsi_io_put(&wdc_xfer_iopool, xfer);
1991 0 : }
1992 :
1993 :
1994 : /*
1995 : * Kill off all pending xfers for a channel_softc.
1996 : *
1997 : * Must be called at splbio().
1998 : */
1999 : void
2000 0 : wdc_kill_pending(struct channel_softc *chp)
2001 : {
2002 : struct wdc_xfer *xfer;
2003 :
2004 0 : while ((xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer)) != NULL) {
2005 0 : chp = xfer->chp;
2006 0 : (*xfer->c_kill_xfer)(chp, xfer);
2007 : }
2008 0 : }
2009 :
2010 : void
2011 0 : __wdcerror(struct channel_softc *chp, char *msg)
2012 : {
2013 0 : struct wdc_xfer *xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer);
2014 0 : if (xfer == NULL)
2015 0 : printf("%s:%d: %s\n", chp->wdc->sc_dev.dv_xname, chp->channel,
2016 : msg);
2017 : else
2018 0 : printf("%s(%s:%d:%d): %s\n",
2019 0 : chp->ch_drive[xfer->drive].drive_name,
2020 0 : chp->wdc->sc_dev.dv_xname,
2021 0 : chp->channel, xfer->drive, msg);
2022 0 : }
2023 :
2024 : /*
2025 : * the bit bucket
2026 : */
2027 : void
2028 0 : wdcbit_bucket(struct channel_softc *chp, int size)
2029 : {
2030 0 : CHP_READ_RAW_MULTI_2(chp, NULL, size);
2031 0 : }
2032 :
2033 :
2034 : #include <sys/ataio.h>
2035 : #include <sys/fcntl.h>
2036 :
2037 : int wdc_ioc_ata_cmd(struct ata_drive_datas *, atareq_t *);
2038 :
2039 : int
2040 0 : wdc_ioc_ata_cmd(struct ata_drive_datas *drvp, atareq_t *atareq)
2041 : {
2042 0 : struct wdc_command wdc_c;
2043 : int err = 0;
2044 :
2045 : /*
2046 : * Make sure a timeout was supplied in the ioctl request
2047 : */
2048 0 : if (atareq->timeout == 0)
2049 0 : return (EINVAL);
2050 :
2051 0 : if (atareq->datalen > MAXPHYS)
2052 0 : return (EINVAL);
2053 :
2054 0 : bzero(&wdc_c, sizeof(wdc_c));
2055 :
2056 0 : if (atareq->datalen > 0) {
2057 0 : wdc_c.data = dma_alloc(atareq->datalen, PR_NOWAIT | PR_ZERO);
2058 0 : if (wdc_c.data == NULL) {
2059 : err = ENOMEM;
2060 0 : goto err;
2061 : }
2062 0 : wdc_c.bcount = atareq->datalen;
2063 0 : }
2064 :
2065 0 : wdc_c.flags = AT_WAIT;
2066 0 : if (atareq->flags & ATACMD_READ)
2067 0 : wdc_c.flags |= AT_READ;
2068 0 : if (atareq->flags & ATACMD_WRITE) {
2069 0 : if (atareq->datalen > 0) {
2070 0 : err = copyin(atareq->databuf, wdc_c.data,
2071 : atareq->datalen);
2072 0 : if (err != 0)
2073 : goto err;
2074 : }
2075 0 : wdc_c.flags |= AT_WRITE;
2076 0 : }
2077 0 : if (atareq->flags & ATACMD_READREG)
2078 0 : wdc_c.flags |= AT_READREG;
2079 :
2080 0 : wdc_c.timeout = atareq->timeout;
2081 0 : wdc_c.r_command = atareq->command;
2082 0 : wdc_c.r_head = atareq->head & 0x0f;
2083 0 : wdc_c.r_cyl = atareq->cylinder;
2084 0 : wdc_c.r_sector = atareq->sec_num;
2085 0 : wdc_c.r_count = atareq->sec_count;
2086 0 : wdc_c.r_features = atareq->features;
2087 0 : if (drvp->drive_flags & DRIVE_ATAPI) {
2088 0 : if (wdc_c.r_command == WDCC_IDENTIFY)
2089 0 : wdc_c.r_command = ATAPI_IDENTIFY_DEVICE;
2090 : } else {
2091 0 : wdc_c.r_st_bmask = WDCS_DRDY;
2092 0 : wdc_c.r_st_pmask = WDCS_DRDY;
2093 : }
2094 :
2095 0 : if (wdc_exec_command(drvp, &wdc_c) != WDC_COMPLETE) {
2096 0 : atareq->retsts = ATACMD_ERROR;
2097 0 : goto copyout;
2098 : }
2099 :
2100 0 : if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
2101 0 : if (wdc_c.flags & AT_ERROR) {
2102 0 : atareq->retsts = ATACMD_ERROR;
2103 0 : atareq->error = wdc_c.r_error;
2104 0 : } else if (wdc_c.flags & AT_DF)
2105 0 : atareq->retsts = ATACMD_DF;
2106 : else
2107 0 : atareq->retsts = ATACMD_TIMEOUT;
2108 : } else {
2109 0 : atareq->retsts = ATACMD_OK;
2110 0 : if (atareq->flags & ATACMD_READREG) {
2111 0 : atareq->head = wdc_c.r_head;
2112 0 : atareq->cylinder = wdc_c.r_cyl;
2113 0 : atareq->sec_num = wdc_c.r_sector;
2114 0 : atareq->sec_count = wdc_c.r_count;
2115 0 : atareq->features = wdc_c.r_features;
2116 0 : atareq->error = wdc_c.r_error;
2117 0 : }
2118 : }
2119 :
2120 : copyout:
2121 0 : if (atareq->datalen > 0 && atareq->flags & ATACMD_READ) {
2122 0 : err = copyout(wdc_c.data, atareq->databuf, atareq->datalen);
2123 0 : if (err != 0)
2124 : goto err;
2125 : }
2126 :
2127 : err:
2128 0 : if (wdc_c.data)
2129 0 : dma_free(wdc_c.data, atareq->datalen);
2130 0 : return (err);
2131 0 : }
2132 :
2133 : int
2134 0 : wdc_ioctl(struct ata_drive_datas *drvp, u_long xfer, caddr_t addr, int flag,
2135 : struct proc *p)
2136 : {
2137 : int error = 0;
2138 :
2139 0 : switch (xfer) {
2140 : #ifdef WDCDEBUG
2141 : case ATAIOGETTRACE: {
2142 : atagettrace_t *agt = (atagettrace_t *)addr;
2143 : unsigned int size = 0;
2144 : char *log_to_copy;
2145 :
2146 : size = agt->buf_size;
2147 : if (size > 65536) {
2148 : size = 65536;
2149 : }
2150 :
2151 : log_to_copy = wdc_get_log(&size, &agt->bytes_left);
2152 :
2153 : if (log_to_copy != NULL) {
2154 : error = copyout(log_to_copy, agt->buf, size);
2155 : free(log_to_copy, M_TEMP, 0);
2156 : }
2157 :
2158 : agt->bytes_copied = size;
2159 : break;
2160 : }
2161 : #endif /* WDCDEBUG */
2162 :
2163 : case ATAIOCCOMMAND: {
2164 0 : atareq_t *atareq = (atareq_t *)addr;
2165 :
2166 : /*
2167 : * Make sure this command is (relatively) safe first
2168 : */
2169 0 : if ((flag & FWRITE) == 0 && atareq->flags & ATACMD_WRITE)
2170 0 : error = EPERM;
2171 : else
2172 0 : error = wdc_ioc_ata_cmd(drvp, atareq);
2173 : break;
2174 : }
2175 :
2176 : default:
2177 : error = ENOTTY;
2178 0 : goto exit;
2179 0 : }
2180 :
2181 : exit:
2182 0 : return (error);
2183 : }
|