xref: /openbsd-src/sys/dev/ata/wd.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /*	$OpenBSD: wd.c,v 1.108 2011/07/06 04:49:36 matthew Exp $ */
2 /*	$NetBSD: wd.c,v 1.193 1999/02/28 17:15:27 explorer Exp $ */
3 
4 /*
5  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *	notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *	notice, this list of conditions and the following disclaimer in the
14  *	documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /*-
29  * Copyright (c) 1998 The NetBSD Foundation, Inc.
30  * All rights reserved.
31  *
32  * This code is derived from software contributed to The NetBSD Foundation
33  * by Charles M. Hannum and by Onno van der Linden.
34  *
35  * Redistribution and use in source and binary forms, with or without
36  * modification, are permitted provided that the following conditions
37  * are met:
38  * 1. Redistributions of source code must retain the above copyright
39  *    notice, this list of conditions and the following disclaimer.
40  * 2. Redistributions in binary form must reproduce the above copyright
41  *    notice, this list of conditions and the following disclaimer in the
42  *    documentation and/or other materials provided with the distribution.
43  *
44  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
45  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
46  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
48  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
49  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
50  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
51  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
52  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
54  * POSSIBILITY OF SUCH DAMAGE.
55  */
56 
57 #if 0
58 #include "rnd.h"
59 #endif
60 
61 #include <sys/param.h>
62 #include <sys/systm.h>
63 #include <sys/kernel.h>
64 #include <sys/conf.h>
65 #include <sys/file.h>
66 #include <sys/stat.h>
67 #include <sys/ioctl.h>
68 #include <sys/mutex.h>
69 #include <sys/buf.h>
70 #include <sys/uio.h>
71 #include <sys/malloc.h>
72 #include <sys/device.h>
73 #include <sys/disklabel.h>
74 #include <sys/disk.h>
75 #include <sys/syslog.h>
76 #include <sys/proc.h>
77 #include <sys/vnode.h>
78 #include <sys/dkio.h>
79 #include <sys/reboot.h>
80 
81 #include <uvm/uvm_extern.h>
82 
83 #include <machine/intr.h>
84 #include <machine/bus.h>
85 
86 #include <dev/ata/atareg.h>
87 #include <dev/ata/atavar.h>
88 #include <dev/ata/wdvar.h>
89 #include <dev/ic/wdcreg.h>
90 #include <dev/ic/wdcvar.h>
91 #if 0
92 #include "locators.h"
93 #endif
94 
95 #define	LBA48_THRESHOLD		(0xfffffff)	/* 128GB / DEV_BSIZE */
96 
97 #define	WDIORETRIES_SINGLE 4	/* number of retries before single-sector */
98 #define	WDIORETRIES	5	/* number of retries before giving up */
99 #define	RECOVERYTIME hz/2	/* time to wait before retrying a cmd */
100 
101 #define DEBUG_INTR   0x01
102 #define DEBUG_XFERS  0x02
103 #define DEBUG_STATUS 0x04
104 #define DEBUG_FUNCS  0x08
105 #define DEBUG_PROBE  0x10
106 #ifdef WDCDEBUG
107 extern int wdcdebug_wd_mask; /* init'ed in ata_wdc.c */
108 #define WDCDEBUG_PRINT(args, level) do {	\
109 	if ((wdcdebug_wd_mask & (level)) != 0)	\
110 		printf args;			\
111 } while (0)
112 #else
113 #define WDCDEBUG_PRINT(args, level)
114 #endif
115 
116 
117 #define sc_drive sc_wdc_bio.drive
118 #define sc_mode sc_wdc_bio.mode
119 #define sc_multi sc_wdc_bio.multi
120 
121 int	wdprobe(struct device *, void *, void *);
122 void	wdattach(struct device *, struct device *, void *);
123 int	wddetach(struct device *, int);
124 int	wdactivate(struct device *, int);
125 int	wdprint(void *, char *);
126 
127 struct cfattach wd_ca = {
128 	sizeof(struct wd_softc), wdprobe, wdattach,
129 	wddetach, wdactivate
130 };
131 
132 struct cfdriver wd_cd = {
133 	NULL, "wd", DV_DISK
134 };
135 
136 void  wdgetdefaultlabel(struct wd_softc *, struct disklabel *);
137 int   wdgetdisklabel(dev_t dev, struct wd_softc *, struct disklabel *, int);
138 void  wdstrategy(struct buf *);
139 void  wdstart(void *);
140 void  __wdstart(struct wd_softc*, struct buf *);
141 void  wdrestart(void *);
142 int   wd_get_params(struct wd_softc *, u_int8_t, struct ataparams *);
143 void  wd_flushcache(struct wd_softc *, int);
144 void  wd_standby(struct wd_softc *, int);
145 void  wd_shutdown(void *);
146 
147 /* XXX: these should go elsewhere */
148 cdev_decl(wd);
149 bdev_decl(wd);
150 
151 #define wdlookup(unit) (struct wd_softc *)disk_lookup(&wd_cd, (unit))
152 
153 
154 int
155 wdprobe(struct device *parent, void *match_, void *aux)
156 {
157 	struct ata_atapi_attach *aa_link = aux;
158 	struct cfdata *match = match_;
159 
160 	if (aa_link == NULL)
161 		return 0;
162 	if (aa_link->aa_type != T_ATA)
163 		return 0;
164 
165 	if (match->cf_loc[0] != -1 &&
166 	    match->cf_loc[0] != aa_link->aa_channel)
167 		return 0;
168 
169 	if (match->cf_loc[1] != -1 &&
170 	    match->cf_loc[1] != aa_link->aa_drv_data->drive)
171 		return 0;
172 
173 	return 1;
174 }
175 
176 void
177 wdattach(struct device *parent, struct device *self, void *aux)
178 {
179 	struct wd_softc *wd = (void *)self;
180 	struct ata_atapi_attach *aa_link= aux;
181 	struct wdc_command wdc_c;
182 	int i, blank;
183 	char buf[41], c, *p, *q;
184 	WDCDEBUG_PRINT(("wdattach\n"), DEBUG_FUNCS | DEBUG_PROBE);
185 
186 	wd->openings = aa_link->aa_openings;
187 	wd->drvp = aa_link->aa_drv_data;
188 
189 	strlcpy(wd->drvp->drive_name, wd->sc_dev.dv_xname,
190 	    sizeof(wd->drvp->drive_name));
191 	wd->drvp->cf_flags = wd->sc_dev.dv_cfdata->cf_flags;
192 
193 	if ((NERRS_MAX - 2) > 0)
194 		wd->drvp->n_dmaerrs = NERRS_MAX - 2;
195 	else
196 		wd->drvp->n_dmaerrs = 0;
197 
198 	/* read our drive info */
199 	if (wd_get_params(wd, at_poll, &wd->sc_params) != 0) {
200 		printf("%s: IDENTIFY failed\n", wd->sc_dev.dv_xname);
201 		return;
202 	}
203 
204 	for (blank = 0, p = wd->sc_params.atap_model, q = buf, i = 0;
205 	    i < sizeof(wd->sc_params.atap_model); i++) {
206 		c = *p++;
207 		if (c == '\0')
208 			break;
209 		if (c != ' ') {
210 			if (blank) {
211 				*q++ = ' ';
212 				blank = 0;
213 			}
214 			*q++ = c;
215 		} else
216 			blank = 1;
217 		}
218 	*q++ = '\0';
219 
220 	printf(": <%s>\n", buf);
221 
222 	wdc_probe_caps(wd->drvp, &wd->sc_params);
223 	wdc_print_caps(wd->drvp);
224 
225 	if ((wd->sc_params.atap_multi & 0xff) > 1) {
226 		wd->sc_multi = wd->sc_params.atap_multi & 0xff;
227 	} else {
228 		wd->sc_multi = 1;
229 	}
230 
231 	printf("%s: %d-sector PIO,", wd->sc_dev.dv_xname, wd->sc_multi);
232 
233 	/* use 48-bit LBA if enabled */
234 	/* XXX: shall we use it if drive capacity < 137Gb? */
235 	if ((wd->sc_params.atap_cmd2_en & ATAPI_CMD2_48AD) != 0)
236 		wd->sc_flags |= WDF_LBA48;
237 
238 	/* Prior to ATA-4, LBA was optional. */
239 	if ((wd->sc_params.atap_capabilities1 & WDC_CAP_LBA) != 0)
240 		wd->sc_flags |= WDF_LBA;
241 #if 0
242 	/* ATA-4 requires LBA. */
243 	if (wd->sc_params.atap_ataversion != 0xffff &&
244 	    wd->sc_params.atap_ataversion >= WDC_VER_ATA4)
245 		wd->sc_flags |= WDF_LBA;
246 #endif
247 
248 	if ((wd->sc_flags & WDF_LBA48) != 0) {
249 		wd->sc_capacity =
250 		    (((u_int64_t)wd->sc_params.atap_max_lba[3] << 48) |
251 		     ((u_int64_t)wd->sc_params.atap_max_lba[2] << 32) |
252 		     ((u_int64_t)wd->sc_params.atap_max_lba[1] << 16) |
253 		      (u_int64_t)wd->sc_params.atap_max_lba[0]);
254 		printf(" LBA48, %lluMB, %llu sectors\n",
255 		    wd->sc_capacity / (1048576 / DEV_BSIZE),
256 		    wd->sc_capacity);
257 	} else if ((wd->sc_flags & WDF_LBA) != 0) {
258 		wd->sc_capacity =
259 		    (wd->sc_params.atap_capacity[1] << 16) |
260 		    wd->sc_params.atap_capacity[0];
261 		printf(" LBA, %lluMB, %llu sectors\n",
262 		    wd->sc_capacity / (1048576 / DEV_BSIZE),
263 		    wd->sc_capacity);
264 	} else {
265 		wd->sc_capacity =
266 		    wd->sc_params.atap_cylinders *
267 		    wd->sc_params.atap_heads *
268 		    wd->sc_params.atap_sectors;
269 		printf(" CHS, %lluMB, %d cyl, %d head, %d sec, %llu sectors\n",
270 		    wd->sc_capacity / (1048576 / DEV_BSIZE),
271 		    wd->sc_params.atap_cylinders,
272 		    wd->sc_params.atap_heads,
273 		    wd->sc_params.atap_sectors,
274 		    wd->sc_capacity);
275 	}
276 	WDCDEBUG_PRINT(("%s: atap_dmatiming_mimi=%d, atap_dmatiming_recom=%d\n",
277 	    self->dv_xname, wd->sc_params.atap_dmatiming_mimi,
278 	    wd->sc_params.atap_dmatiming_recom), DEBUG_PROBE);
279 
280 	/* use read look ahead if supported */
281 	if (wd->sc_params.atap_cmd_set1 & WDC_CMD1_AHEAD) {
282 		bzero(&wdc_c, sizeof(struct wdc_command));
283 		wdc_c.r_command = SET_FEATURES;
284 		wdc_c.r_precomp = WDSF_READAHEAD_EN;
285 		wdc_c.timeout = 1000;
286 		wdc_c.flags = at_poll;
287 
288 		if (wdc_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) {
289 			printf("%s: enable look ahead command didn't "
290 			    "complete\n", wd->sc_dev.dv_xname);
291 		}
292 	}
293 
294 	/* use write cache if supported */
295 	if (wd->sc_params.atap_cmd_set1 & WDC_CMD1_CACHE) {
296 		bzero(&wdc_c, sizeof(struct wdc_command));
297 		wdc_c.r_command = SET_FEATURES;
298 		wdc_c.r_precomp = WDSF_EN_WR_CACHE;
299 		wdc_c.timeout = 1000;
300 		wdc_c.flags = at_poll;
301 
302 		if (wdc_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) {
303 			printf("%s: enable write cache command didn't "
304 			    "complete\n", wd->sc_dev.dv_xname);
305 		}
306 	}
307 
308 	/*
309 	 * FREEZE LOCK the drive so malicous users can't lock it on us.
310 	 * As there is no harm in issuing this to drives that don't
311 	 * support the security feature set we just send it, and don't
312 	 * bother checking if the drive sends a command abort to tell us it
313 	 * doesn't support it.
314 	 */
315 	bzero(&wdc_c, sizeof(struct wdc_command));
316 
317 	wdc_c.r_command = WDCC_SEC_FREEZE_LOCK;
318 	wdc_c.timeout = 1000;
319 	wdc_c.flags = at_poll;
320 	if (wdc_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) {
321 		printf("%s: freeze lock command didn't complete\n",
322 		    wd->sc_dev.dv_xname);
323 	}
324 
325 	/*
326 	 * Initialize disk structures.
327 	 */
328 	wd->sc_dk.dk_name = wd->sc_dev.dv_xname;
329 	bufq_init(&wd->sc_bufq, BUFQ_DEFAULT);
330 	wd->sc_sdhook = shutdownhook_establish(wd_shutdown, wd);
331 	if (wd->sc_sdhook == NULL)
332 		printf("%s: WARNING: unable to establish shutdown hook\n",
333 		    wd->sc_dev.dv_xname);
334 	timeout_set(&wd->sc_restart_timeout, wdrestart, wd);
335 
336 	/* Attach disk. */
337 	disk_attach(&wd->sc_dev, &wd->sc_dk);
338 	wd->sc_wdc_bio.lp = wd->sc_dk.dk_label;
339 }
340 
341 int
342 wdactivate(struct device *self, int act)
343 {
344 	struct wd_softc *wd = (void *)self;
345 	int rv = 0;
346 
347 	switch (act) {
348 	case DVACT_SUSPEND:
349 		wd_flushcache(wd, AT_POLL);
350 		wd_standby(wd, AT_POLL);
351 		break;
352 	case DVACT_RESUME:
353 		/*
354 		 * Do two resets separated by a small delay. The
355 		 * first wakes the controller, the second resets
356 		 * the channel.
357 		 */
358 		wdc_disable_intr(wd->drvp->chnl_softc);
359 		wdc_reset_channel(wd->drvp, 1);
360 		delay(10000);
361 		wdc_reset_channel(wd->drvp, 0);
362 		wdc_enable_intr(wd->drvp->chnl_softc);
363 		wd_get_params(wd, at_poll, &wd->sc_params);
364 		break;
365 	}
366 	return (rv);
367 }
368 
369 int
370 wddetach(struct device *self, int flags)
371 {
372 	struct wd_softc *sc = (struct wd_softc *)self;
373 
374 	timeout_del(&sc->sc_restart_timeout);
375 
376 	bufq_drain(&sc->sc_bufq);
377 
378 	disk_gone(wdopen, self->dv_unit);
379 
380 	/* Get rid of the shutdown hook. */
381 	if (sc->sc_sdhook != NULL)
382 		shutdownhook_disestablish(sc->sc_sdhook);
383 
384 	/* Detach disk. */
385 	bufq_destroy(&sc->sc_bufq);
386 	disk_detach(&sc->sc_dk);
387 
388 	return (0);
389 }
390 
391 /*
392  * Read/write routine for a buffer.  Validates the arguments and schedules the
393  * transfer.  Does not wait for the transfer to complete.
394  */
395 void
396 wdstrategy(struct buf *bp)
397 {
398 	struct wd_softc *wd;
399 	int s;
400 
401 	wd = wdlookup(DISKUNIT(bp->b_dev));
402 	if (wd == NULL) {
403 		bp->b_error = ENXIO;
404 		goto bad;
405 	}
406 
407 	WDCDEBUG_PRINT(("wdstrategy (%s)\n", wd->sc_dev.dv_xname),
408 	    DEBUG_XFERS);
409 
410 	/* If device invalidated (e.g. media change, door open), error. */
411 	if ((wd->sc_flags & WDF_LOADED) == 0) {
412 		bp->b_error = EIO;
413 		goto bad;
414 	}
415 
416 	/* Validate the request. */
417 	if (bounds_check_with_label(bp, wd->sc_dk.dk_label) == -1)
418 		goto done;
419 
420 	/* Check that the number of sectors can fit in a byte. */
421 	if ((bp->b_bcount / wd->sc_dk.dk_label->d_secsize) >= (1 << NBBY)) {
422 		bp->b_error = EINVAL;
423 		goto bad;
424 	}
425 
426 	/* Queue transfer on drive, activate drive and controller if idle. */
427 	bufq_queue(&wd->sc_bufq, bp);
428 	s = splbio();
429 	wdstart(wd);
430 	splx(s);
431 	device_unref(&wd->sc_dev);
432 	return;
433 
434  bad:
435 	bp->b_flags |= B_ERROR;
436 	bp->b_resid = bp->b_bcount;
437  done:
438 	s = splbio();
439 	biodone(bp);
440 	splx(s);
441 	if (wd != NULL)
442 		device_unref(&wd->sc_dev);
443 }
444 
445 /*
446  * Queue a drive for I/O.
447  */
448 void
449 wdstart(void *arg)
450 {
451 	struct wd_softc *wd = arg;
452 	struct buf *bp = NULL;
453 
454 	WDCDEBUG_PRINT(("wdstart %s\n", wd->sc_dev.dv_xname),
455 	    DEBUG_XFERS);
456 	while (wd->openings > 0) {
457 
458 		/* Is there a buf for us ? */
459 		if ((bp = bufq_dequeue(&wd->sc_bufq)) == NULL)
460 			return;
461 		/*
462 		 * Make the command. First lock the device
463 		 */
464 		wd->openings--;
465 
466 		wd->retries = 0;
467 		__wdstart(wd, bp);
468 	}
469 }
470 
471 void
472 __wdstart(struct wd_softc *wd, struct buf *bp)
473 {
474 	daddr64_t nblks;
475 
476 	wd->sc_wdc_bio.blkno = bp->b_blkno +
477 	    DL_GETPOFFSET(&wd->sc_dk.dk_label->d_partitions[DISKPART(bp->b_dev)]);
478 	wd->sc_wdc_bio.blkno /= (wd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
479 	wd->sc_wdc_bio.blkdone =0;
480 	wd->sc_bp = bp;
481 	/*
482 	 * If we're retrying, retry in single-sector mode. This will give us
483 	 * the sector number of the problem, and will eventually allow the
484 	 * transfer to succeed.
485 	 */
486 	if (wd->retries >= WDIORETRIES_SINGLE)
487 		wd->sc_wdc_bio.flags = ATA_SINGLE;
488 	else
489 		wd->sc_wdc_bio.flags = 0;
490 	nblks = bp->b_bcount / wd->sc_dk.dk_label->d_secsize;
491 	if ((wd->sc_flags & WDF_LBA48) &&
492 	    /* use LBA48 only if really need */
493 	    ((wd->sc_wdc_bio.blkno + nblks - 1 >= LBA48_THRESHOLD) ||
494 	     (nblks > 0xff)))
495 		wd->sc_wdc_bio.flags |= ATA_LBA48;
496 	if (wd->sc_flags & WDF_LBA)
497 		wd->sc_wdc_bio.flags |= ATA_LBA;
498 	if (bp->b_flags & B_READ)
499 		wd->sc_wdc_bio.flags |= ATA_READ;
500 	wd->sc_wdc_bio.bcount = bp->b_bcount;
501 	wd->sc_wdc_bio.databuf = bp->b_data;
502 	wd->sc_wdc_bio.wd = wd;
503 	/* Instrumentation. */
504 	disk_busy(&wd->sc_dk);
505 	switch (wdc_ata_bio(wd->drvp, &wd->sc_wdc_bio)) {
506 	case WDC_TRY_AGAIN:
507 		timeout_add_sec(&wd->sc_restart_timeout, 1);
508 		break;
509 	case WDC_QUEUED:
510 		break;
511 	case WDC_COMPLETE:
512 		/*
513 		 * This code is never executed because we never set
514 		 * the ATA_POLL flag above
515 		 */
516 #if 0
517 		if (wd->sc_wdc_bio.flags & ATA_POLL)
518 			wddone(wd);
519 #endif
520 		break;
521 	default:
522 		panic("__wdstart: bad return code from wdc_ata_bio()");
523 	}
524 }
525 
526 void
527 wddone(void *v)
528 {
529 	struct wd_softc *wd = v;
530 	struct buf *bp = wd->sc_bp;
531 	char buf[256], *errbuf = buf;
532 	WDCDEBUG_PRINT(("wddone %s\n", wd->sc_dev.dv_xname),
533 	    DEBUG_XFERS);
534 
535 	bp->b_resid = wd->sc_wdc_bio.bcount;
536 	errbuf[0] = '\0';
537 	switch (wd->sc_wdc_bio.error) {
538 	case ERR_NODEV:
539 		bp->b_flags |= B_ERROR;
540 		bp->b_error = ENXIO;
541 		break;
542 	case ERR_DMA:
543 		errbuf = "DMA error";
544 		goto retry;
545 	case ERR_DF:
546 		errbuf = "device fault";
547 		goto retry;
548 	case TIMEOUT:
549 		errbuf = "device timeout";
550 		goto retry;
551 	case ERROR:
552 		/* Don't care about media change bits */
553 		if (wd->sc_wdc_bio.r_error != 0 &&
554 		    (wd->sc_wdc_bio.r_error & ~(WDCE_MC | WDCE_MCR)) == 0)
555 			goto noerror;
556 		ata_perror(wd->drvp, wd->sc_wdc_bio.r_error, errbuf,
557 		    sizeof buf);
558 retry:
559 		/* Just reset and retry. Can we do more ? */
560 		wdc_reset_channel(wd->drvp, 0);
561 		diskerr(bp, "wd", errbuf, LOG_PRINTF,
562 		    wd->sc_wdc_bio.blkdone, wd->sc_dk.dk_label);
563 		if (wd->retries++ < WDIORETRIES) {
564 			printf(", retrying\n");
565 			timeout_add(&wd->sc_restart_timeout, RECOVERYTIME);
566 			return;
567 		}
568 		printf("\n");
569 		bp->b_flags |= B_ERROR;
570 		bp->b_error = EIO;
571 		break;
572 	case NOERROR:
573 noerror:	if ((wd->sc_wdc_bio.flags & ATA_CORR) || wd->retries > 0)
574 			printf("%s: soft error (corrected)\n",
575 			    wd->sc_dev.dv_xname);
576 	}
577 	disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid),
578 	    (bp->b_flags & B_READ));
579 	biodone(bp);
580 	wd->openings++;
581 	wdstart(wd);
582 }
583 
584 void
585 wdrestart(void *v)
586 {
587 	struct wd_softc *wd = v;
588 	struct buf *bp = wd->sc_bp;
589 	struct channel_softc *chnl;
590 	int s;
591 	WDCDEBUG_PRINT(("wdrestart %s\n", wd->sc_dev.dv_xname),
592 	    DEBUG_XFERS);
593 
594 	chnl = (struct channel_softc *)(wd->drvp->chnl_softc);
595 	if (chnl->dying)
596 		return;
597 
598 	s = splbio();
599 	disk_unbusy(&wd->sc_dk, 0, (bp->b_flags & B_READ));
600 	__wdstart(v, bp);
601 	splx(s);
602 }
603 
604 int
605 wdread(dev_t dev, struct uio *uio, int flags)
606 {
607 
608 	WDCDEBUG_PRINT(("wdread\n"), DEBUG_XFERS);
609 	return (physio(wdstrategy, dev, B_READ, minphys, uio));
610 }
611 
612 int
613 wdwrite(dev_t dev, struct uio *uio, int flags)
614 {
615 
616 	WDCDEBUG_PRINT(("wdwrite\n"), DEBUG_XFERS);
617 	return (physio(wdstrategy, dev, B_WRITE, minphys, uio));
618 }
619 
620 int
621 wdopen(dev_t dev, int flag, int fmt, struct proc *p)
622 {
623 	struct wd_softc *wd;
624 	struct channel_softc *chnl;
625 	int unit, part;
626 	int error;
627 
628 	WDCDEBUG_PRINT(("wdopen\n"), DEBUG_FUNCS);
629 
630 	unit = DISKUNIT(dev);
631 	wd = wdlookup(unit);
632 	if (wd == NULL)
633 		return ENXIO;
634 	chnl = (struct channel_softc *)(wd->drvp->chnl_softc);
635 	if (chnl->dying)
636 		return (ENXIO);
637 
638 	/*
639 	 * If this is the first open of this device, add a reference
640 	 * to the adapter.
641 	 */
642 	if ((error = disk_lock(&wd->sc_dk)) != 0)
643 		goto bad4;
644 
645 	if (wd->sc_dk.dk_openmask != 0) {
646 		/*
647 		 * If any partition is open, but the disk has been invalidated,
648 		 * disallow further opens.
649 		 */
650 		if ((wd->sc_flags & WDF_LOADED) == 0) {
651 			error = EIO;
652 			goto bad3;
653 		}
654 	} else {
655 		if ((wd->sc_flags & WDF_LOADED) == 0) {
656 			wd->sc_flags |= WDF_LOADED;
657 
658 			/* Load the physical device parameters. */
659 			wd_get_params(wd, AT_WAIT, &wd->sc_params);
660 
661 			/* Load the partition info if not already loaded. */
662 			if (wdgetdisklabel(dev, wd,
663 			    wd->sc_dk.dk_label, 0) == EIO) {
664 				error = EIO;
665 				goto bad;
666 			}
667 		}
668 	}
669 
670 	part = DISKPART(dev);
671 
672 	if ((error = disk_openpart(&wd->sc_dk, part, fmt, 1)) != 0)
673 		goto bad;
674 
675 	disk_unlock(&wd->sc_dk);
676 	device_unref(&wd->sc_dev);
677 	return 0;
678 
679 bad:
680 	if (wd->sc_dk.dk_openmask == 0) {
681 	}
682 
683 bad3:
684 	disk_unlock(&wd->sc_dk);
685 bad4:
686 	device_unref(&wd->sc_dev);
687 	return error;
688 }
689 
690 int
691 wdclose(dev_t dev, int flag, int fmt, struct proc *p)
692 {
693 	struct wd_softc *wd;
694 	int part = DISKPART(dev);
695 
696 	wd = wdlookup(DISKUNIT(dev));
697 	if (wd == NULL)
698 		return ENXIO;
699 
700 	WDCDEBUG_PRINT(("wdclose\n"), DEBUG_FUNCS);
701 
702 	disk_lock_nointr(&wd->sc_dk);
703 
704 	disk_closepart(&wd->sc_dk, part, fmt);
705 
706 	if (wd->sc_dk.dk_openmask == 0) {
707 		wd_flushcache(wd, 0);
708 		/* XXXX Must wait for I/O to complete! */
709 	}
710 
711 	disk_unlock(&wd->sc_dk);
712 
713 	device_unref(&wd->sc_dev);
714 	return (0);
715 }
716 
717 void
718 wdgetdefaultlabel(struct wd_softc *wd, struct disklabel *lp)
719 {
720 	WDCDEBUG_PRINT(("wdgetdefaultlabel\n"), DEBUG_FUNCS);
721 	bzero(lp, sizeof(struct disklabel));
722 
723 	lp->d_secsize = DEV_BSIZE;
724 	DL_SETDSIZE(lp, wd->sc_capacity);
725 	lp->d_ntracks = wd->sc_params.atap_heads;
726 	lp->d_nsectors = wd->sc_params.atap_sectors;
727 	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
728 	lp->d_ncylinders = DL_GETDSIZE(lp) / lp->d_secpercyl;
729 	if (wd->drvp->ata_vers == -1) {
730 		lp->d_type = DTYPE_ST506;
731 		strncpy(lp->d_typename, "ST506/MFM/RLL", sizeof lp->d_typename);
732 	} else {
733 		lp->d_type = DTYPE_ESDI;
734 		strncpy(lp->d_typename, "ESDI/IDE disk", sizeof lp->d_typename);
735 	}
736 	/* XXX - user viscopy() like sd.c */
737 	strncpy(lp->d_packname, wd->sc_params.atap_model, sizeof lp->d_packname);
738 	lp->d_flags = 0;
739 	lp->d_version = 1;
740 
741 	lp->d_magic = DISKMAGIC;
742 	lp->d_magic2 = DISKMAGIC;
743 	lp->d_checksum = dkcksum(lp);
744 }
745 
746 /*
747  * Fabricate a default disk label, and try to read the correct one.
748  */
749 int
750 wdgetdisklabel(dev_t dev, struct wd_softc *wd, struct disklabel *lp,
751     int spoofonly)
752 {
753 	int error;
754 
755 	WDCDEBUG_PRINT(("wdgetdisklabel\n"), DEBUG_FUNCS);
756 
757 	wdgetdefaultlabel(wd, lp);
758 
759 	if (wd->drvp->state > RECAL)
760 		wd->drvp->drive_flags |= DRIVE_RESET;
761 	error = readdisklabel(DISKLABELDEV(dev), wdstrategy, lp,
762 	    spoofonly);
763 	if (wd->drvp->state > RECAL)
764 		wd->drvp->drive_flags |= DRIVE_RESET;
765 	return (error);
766 }
767 
768 int
769 wdioctl(dev_t dev, u_long xfer, caddr_t addr, int flag, struct proc *p)
770 {
771 	struct wd_softc *wd;
772 	struct disklabel *lp;
773 	int error = 0;
774 
775 	WDCDEBUG_PRINT(("wdioctl\n"), DEBUG_FUNCS);
776 
777 	wd = wdlookup(DISKUNIT(dev));
778 	if (wd == NULL)
779 		return ENXIO;
780 
781 	if ((wd->sc_flags & WDF_LOADED) == 0) {
782 		error = EIO;
783 		goto exit;
784 	}
785 
786 	switch (xfer) {
787 	case DIOCRLDINFO:
788 		lp = malloc(sizeof(*lp), M_TEMP, M_WAITOK);
789 		wdgetdisklabel(dev, wd, lp, 0);
790 		bcopy(lp, wd->sc_dk.dk_label, sizeof(*lp));
791 		free(lp, M_TEMP);
792 		goto exit;
793 
794 	case DIOCGPDINFO:
795 		wdgetdisklabel(dev, wd, (struct disklabel *)addr, 1);
796 		goto exit;
797 
798 	case DIOCGDINFO:
799 		*(struct disklabel *)addr = *(wd->sc_dk.dk_label);
800 		goto exit;
801 
802 	case DIOCGPART:
803 		((struct partinfo *)addr)->disklab = wd->sc_dk.dk_label;
804 		((struct partinfo *)addr)->part =
805 		    &wd->sc_dk.dk_label->d_partitions[DISKPART(dev)];
806 		goto exit;
807 
808 	case DIOCWDINFO:
809 	case DIOCSDINFO:
810 		if ((flag & FWRITE) == 0) {
811 			error = EBADF;
812 			goto exit;
813 		}
814 
815 		if ((error = disk_lock(&wd->sc_dk)) != 0)
816 			goto exit;
817 
818 		error = setdisklabel(wd->sc_dk.dk_label,
819 		    (struct disklabel *)addr, wd->sc_dk.dk_openmask);
820 		if (error == 0) {
821 			if (wd->drvp->state > RECAL)
822 				wd->drvp->drive_flags |= DRIVE_RESET;
823 			if (xfer == DIOCWDINFO)
824 				error = writedisklabel(DISKLABELDEV(dev),
825 				    wdstrategy, wd->sc_dk.dk_label);
826 		}
827 
828 		disk_unlock(&wd->sc_dk);
829 		goto exit;
830 
831 #ifdef notyet
832 	case DIOCWFORMAT:
833 		if ((flag & FWRITE) == 0)
834 			return EBADF;
835 		{
836 		struct format_op *fop;
837 		struct iovec aiov;
838 		struct uio auio;
839 
840 		fop = (struct format_op *)addr;
841 		aiov.iov_base = fop->df_buf;
842 		aiov.iov_len = fop->df_count;
843 		auio.uio_iov = &aiov;
844 		auio.uio_iovcnt = 1;
845 		auio.uio_resid = fop->df_count;
846 		auio.uio_segflg = 0;
847 		auio.uio_offset =
848 			fop->df_startblk * wd->sc_dk.dk_label->d_secsize;
849 		auio.uio_procp = p;
850 		error = physio(wdformat, dev, B_WRITE, minphys, &auio);
851 		fop->df_count -= auio.uio_resid;
852 		fop->df_reg[0] = wdc->sc_status;
853 		fop->df_reg[1] = wdc->sc_error;
854 		goto exit;
855 		}
856 #endif
857 
858 	default:
859 		error = wdc_ioctl(wd->drvp, xfer, addr, flag, p);
860 		goto exit;
861 	}
862 
863 #ifdef DIAGNOSTIC
864 	panic("wdioctl: impossible");
865 #endif
866 
867  exit:
868 	device_unref(&wd->sc_dev);
869 	return (error);
870 }
871 
872 #ifdef B_FORMAT
873 int
874 wdformat(struct buf *bp)
875 {
876 
877 	bp->b_flags |= B_FORMAT;
878 	return wdstrategy(bp);
879 }
880 #endif
881 
882 daddr64_t
883 wdsize(dev_t dev)
884 {
885 	struct wd_softc *wd;
886 	int part, omask;
887 	int64_t size;
888 
889 	WDCDEBUG_PRINT(("wdsize\n"), DEBUG_FUNCS);
890 
891 	wd = wdlookup(DISKUNIT(dev));
892 	if (wd == NULL)
893 		return (-1);
894 
895 	part = DISKPART(dev);
896 	omask = wd->sc_dk.dk_openmask & (1 << part);
897 
898 	if (omask == 0 && wdopen(dev, 0, S_IFBLK, NULL) != 0) {
899 		size = -1;
900 		goto exit;
901 	}
902 
903 	size = DL_GETPSIZE(&wd->sc_dk.dk_label->d_partitions[part]) *
904 	    (wd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
905 	if (omask == 0 && wdclose(dev, 0, S_IFBLK, NULL) != 0)
906 		size = -1;
907 
908  exit:
909 	device_unref(&wd->sc_dev);
910 	return (size);
911 }
912 
913 /* #define WD_DUMP_NOT_TRUSTED if you just want to watch */
914 static int wddoingadump = 0;
915 static int wddumprecalibrated = 0;
916 static int wddumpmulti = 1;
917 
918 /*
919  * Dump core after a system crash.
920  */
921 int
922 wddump(dev_t dev, daddr64_t blkno, caddr_t va, size_t size)
923 {
924 	struct wd_softc *wd;	/* disk unit to do the I/O */
925 	struct disklabel *lp;   /* disk's disklabel */
926 	int unit, part;
927 	int nblks;	/* total number of sectors left to write */
928 	int err;
929 	char errbuf[256];
930 
931 	/* Check if recursive dump; if so, punt. */
932 	if (wddoingadump)
933 		return EFAULT;
934 	wddoingadump = 1;
935 
936 	unit = DISKUNIT(dev);
937 	wd = wdlookup(unit);
938 	if (wd == NULL)
939 		return ENXIO;
940 
941 	part = DISKPART(dev);
942 
943 	/* Make sure it was initialized. */
944 	if (wd->drvp->state < READY)
945 		return ENXIO;
946 
947 	/* Convert to disk sectors.  Request must be a multiple of size. */
948 	lp = wd->sc_dk.dk_label;
949 	if ((size % lp->d_secsize) != 0)
950 		return EFAULT;
951 	nblks = size / lp->d_secsize;
952 	blkno = blkno / (lp->d_secsize / DEV_BSIZE);
953 
954 	/* Check transfer bounds against partition size. */
955 	if ((blkno < 0) || ((blkno + nblks) > DL_GETPSIZE(&lp->d_partitions[part])))
956 		return EINVAL;
957 
958 	/* Offset block number to start of partition. */
959 	blkno += DL_GETPOFFSET(&lp->d_partitions[part]);
960 
961 	/* Recalibrate, if first dump transfer. */
962 	if (wddumprecalibrated == 0) {
963 		wddumpmulti = wd->sc_multi;
964 		wddumprecalibrated = 1;
965 		wd->drvp->state = RECAL;
966 	}
967 
968 	while (nblks > 0) {
969 		wd->sc_wdc_bio.blkno = blkno;
970 		wd->sc_wdc_bio.flags = ATA_POLL;
971 		if (wd->sc_flags & WDF_LBA48)
972 			wd->sc_wdc_bio.flags |= ATA_LBA48;
973 		if (wd->sc_flags & WDF_LBA)
974 			wd->sc_wdc_bio.flags |= ATA_LBA;
975 		wd->sc_wdc_bio.bcount =
976 			min(nblks, wddumpmulti) * lp->d_secsize;
977 		wd->sc_wdc_bio.databuf = va;
978 		wd->sc_wdc_bio.wd = wd;
979 #ifndef WD_DUMP_NOT_TRUSTED
980 		switch (wdc_ata_bio(wd->drvp, &wd->sc_wdc_bio)) {
981 		case WDC_TRY_AGAIN:
982 			panic("wddump: try again");
983 			break;
984 		case WDC_QUEUED:
985 			panic("wddump: polled command has been queued");
986 			break;
987 		case WDC_COMPLETE:
988 			break;
989 		}
990 		switch(wd->sc_wdc_bio.error) {
991 		case TIMEOUT:
992 			printf("wddump: device timed out");
993 			err = EIO;
994 			break;
995 		case ERR_DF:
996 			printf("wddump: drive fault");
997 			err = EIO;
998 			break;
999 		case ERR_DMA:
1000 			printf("wddump: DMA error");
1001 			err = EIO;
1002 			break;
1003 		case ERROR:
1004 			errbuf[0] = '\0';
1005 			ata_perror(wd->drvp, wd->sc_wdc_bio.r_error, errbuf,
1006 			    sizeof errbuf);
1007 			printf("wddump: %s", errbuf);
1008 			err = EIO;
1009 			break;
1010 		case NOERROR:
1011 			err = 0;
1012 			break;
1013 		default:
1014 			panic("wddump: unknown error type");
1015 		}
1016 		if (err != 0) {
1017 			printf("\n");
1018 			return err;
1019 		}
1020 #else	/* WD_DUMP_NOT_TRUSTED */
1021 		/* Let's just talk about this first... */
1022 		printf("wd%d: dump addr 0x%x, cylin %d, head %d, sector %d\n",
1023 		    unit, va, cylin, head, sector);
1024 		delay(500 * 1000);	/* half a second */
1025 #endif
1026 
1027 		/* update block count */
1028 		nblks -= min(nblks, wddumpmulti);
1029 		blkno += min(nblks, wddumpmulti);
1030 		va += min(nblks, wddumpmulti) * lp->d_secsize;
1031 	}
1032 
1033 	wddoingadump = 0;
1034 	return 0;
1035 }
1036 
1037 int
1038 wd_get_params(struct wd_softc *wd, u_int8_t flags, struct ataparams *params)
1039 {
1040 	switch (ata_get_params(wd->drvp, flags, params)) {
1041 	case CMD_AGAIN:
1042 		return 1;
1043 	case CMD_ERR:
1044 		/* If we already have drive parameters, reuse them. */
1045 		if (wd->sc_params.atap_cylinders != 0) {
1046 			if (params != &wd->sc_params)
1047 				bcopy(&wd->sc_params, params,
1048 				    sizeof(struct ataparams));
1049 			return 0;
1050 		}
1051 		/*
1052 		 * We `know' there's a drive here; just assume it's old.
1053 		 * This geometry is only used to read the MBR and print a
1054 		 * (false) attach message.
1055 		 */
1056 		bzero(params, sizeof(struct ataparams));
1057 		strncpy(params->atap_model, "ST506",
1058 		    sizeof params->atap_model);
1059 		params->atap_config = ATA_CFG_FIXED;
1060 		params->atap_cylinders = 1024;
1061 		params->atap_heads = 8;
1062 		params->atap_sectors = 17;
1063 		params->atap_multi = 1;
1064 		params->atap_capabilities1 = params->atap_capabilities2 = 0;
1065 		wd->drvp->ata_vers = -1; /* Mark it as pre-ATA */
1066 		return 0;
1067 	case CMD_OK:
1068 		return 0;
1069 	default:
1070 		panic("wd_get_params: bad return code from ata_get_params");
1071 		/* NOTREACHED */
1072 	}
1073 }
1074 
1075 void
1076 wd_flushcache(struct wd_softc *wd, int flags)
1077 {
1078 	struct wdc_command wdc_c;
1079 
1080 	if (wd->drvp->ata_vers < 4) /* WDCC_FLUSHCACHE is here since ATA-4 */
1081 		return;
1082 	bzero(&wdc_c, sizeof(struct wdc_command));
1083 	wdc_c.r_command = (wd->sc_flags & WDF_LBA48 ? WDCC_FLUSHCACHE_EXT :
1084 	    WDCC_FLUSHCACHE);
1085 	wdc_c.r_st_bmask = WDCS_DRDY;
1086 	wdc_c.r_st_pmask = WDCS_DRDY;
1087 	if (flags != 0) {
1088 		wdc_c.flags = AT_POLL;
1089 	} else {
1090 		wdc_c.flags = AT_WAIT;
1091 	}
1092 	wdc_c.timeout = 30000; /* 30s timeout */
1093 	if (wdc_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) {
1094 		printf("%s: flush cache command didn't complete\n",
1095 		    wd->sc_dev.dv_xname);
1096 	}
1097 	if (wdc_c.flags & AT_TIMEOU) {
1098 		printf("%s: flush cache command timeout\n",
1099 		    wd->sc_dev.dv_xname);
1100 	}
1101 	if (wdc_c.flags & AT_DF) {
1102 		printf("%s: flush cache command: drive fault\n",
1103 		    wd->sc_dev.dv_xname);
1104 	}
1105 	/*
1106 	 * Ignore error register, it shouldn't report anything else
1107 	 * than COMMAND ABORTED, which means the device doesn't support
1108 	 * flush cache
1109 	 */
1110 }
1111 
1112 void
1113 wd_standby(struct wd_softc *wd, int flags)
1114 {
1115 	struct wdc_command wdc_c;
1116 
1117 	bzero(&wdc_c, sizeof(struct wdc_command));
1118 	wdc_c.r_command = WDCC_STANDBY_IMMED;
1119 	wdc_c.r_st_bmask = WDCS_DRDY;
1120 	wdc_c.r_st_pmask = WDCS_DRDY;
1121 	if (flags != 0) {
1122 		wdc_c.flags = AT_POLL;
1123 	} else {
1124 		wdc_c.flags = AT_WAIT;
1125 	}
1126 	wdc_c.timeout = 30000; /* 30s timeout */
1127 	if (wdc_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) {
1128 		printf("%s: standby command didn't complete\n",
1129 		    wd->sc_dev.dv_xname);
1130 	}
1131 	if (wdc_c.flags & AT_TIMEOU) {
1132 		printf("%s: standby command timeout\n",
1133 		    wd->sc_dev.dv_xname);
1134 	}
1135 	if (wdc_c.flags & AT_DF) {
1136 		printf("%s: standby command: drive fault\n",
1137 		    wd->sc_dev.dv_xname);
1138 	}
1139 	/*
1140 	 * Ignore error register, it shouldn't report anything else
1141 	 * than COMMAND ABORTED, which means the device doesn't support
1142 	 * standby
1143 	 */
1144 }
1145 
1146 void
1147 wd_shutdown(void *arg)
1148 {
1149 	struct wd_softc *wd = arg;
1150 
1151 	wd_flushcache(wd, AT_POLL);
1152 	if (boothowto & RB_POWERDOWN)
1153 		wd_standby(wd, AT_POLL);
1154 }
1155