xref: /netbsd-src/sys/dev/ata/wd.c (revision 5e4c038a45edbc7d63b7c2daa76e29f88b64a4e3)
1 /*	$NetBSD: wd.c,v 1.220 2002/01/13 17:24:30 christos Exp $ */
2 
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  * 3. All advertising materials mentioning features or use of this software
15  *	must display the following acknowledgement:
16  *  This product includes software developed by Manuel Bouyer.
17  * 4. The name of the author may not be used to endorse or promote products
18  *	derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*-
33  * Copyright (c) 1998 The NetBSD Foundation, Inc.
34  * All rights reserved.
35  *
36  * This code is derived from software contributed to The NetBSD Foundation
37  * by Charles M. Hannum and by Onno van der Linden.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions
41  * are met:
42  * 1. Redistributions of source code must retain the above copyright
43  *    notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  *    notice, this list of conditions and the following disclaimer in the
46  *    documentation and/or other materials provided with the distribution.
47  * 3. All advertising materials mentioning features or use of this software
48  *    must display the following acknowledgement:
49  *        This product includes software developed by the NetBSD
50  *        Foundation, Inc. and its contributors.
51  * 4. Neither the name of The NetBSD Foundation nor the names of its
52  *    contributors may be used to endorse or promote products derived
53  *    from this software without specific prior written permission.
54  *
55  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
56  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
57  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
58  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
59  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
60  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
61  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
62  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
63  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
64  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
65  * POSSIBILITY OF SUCH DAMAGE.
66  */
67 
68 #include <sys/cdefs.h>
69 __KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.220 2002/01/13 17:24:30 christos Exp $");
70 
71 #ifndef WDCDEBUG
72 #define WDCDEBUG
73 #endif /* WDCDEBUG */
74 
75 #include "rnd.h"
76 
77 #include <sys/param.h>
78 #include <sys/systm.h>
79 #include <sys/kernel.h>
80 #include <sys/conf.h>
81 #include <sys/file.h>
82 #include <sys/stat.h>
83 #include <sys/ioctl.h>
84 #include <sys/buf.h>
85 #include <sys/uio.h>
86 #include <sys/malloc.h>
87 #include <sys/device.h>
88 #include <sys/disklabel.h>
89 #include <sys/disk.h>
90 #include <sys/syslog.h>
91 #include <sys/proc.h>
92 #include <sys/vnode.h>
93 #if NRND > 0
94 #include <sys/rnd.h>
95 #endif
96 
97 #include <machine/intr.h>
98 #include <machine/bus.h>
99 
100 #include <dev/ata/atareg.h>
101 #include <dev/ata/atavar.h>
102 #include <dev/ata/wdvar.h>
103 #include <dev/ic/wdcreg.h>
104 #include <sys/ataio.h>
105 #include "locators.h"
106 
107 #define	WAITTIME	(4 * hz)	/* time to wait for a completion */
108 #define	WDIORETRIES_SINGLE 4	/* number of retries before single-sector */
109 #define	WDIORETRIES	5	/* number of retries before giving up */
110 #define	RECOVERYTIME hz/2	/* time to wait before retrying a cmd */
111 
112 #define	WDUNIT(dev)		DISKUNIT(dev)
113 #define	WDPART(dev)		DISKPART(dev)
114 #define	WDMINOR(unit, part)	DISKMINOR(unit, part)
115 #define	MAKEWDDEV(maj, unit, part)	MAKEDISKDEV(maj, unit, part)
116 
117 #define	WDLABELDEV(dev)	(MAKEWDDEV(major(dev), WDUNIT(dev), RAW_PART))
118 
119 #define DEBUG_INTR   0x01
120 #define DEBUG_XFERS  0x02
121 #define DEBUG_STATUS 0x04
122 #define DEBUG_FUNCS  0x08
123 #define DEBUG_PROBE  0x10
124 #ifdef WDCDEBUG
125 extern int wdcdebug_wd_mask; /* init'ed in ata_wdc.c */
126 #define WDCDEBUG_PRINT(args, level) \
127 	if (wdcdebug_wd_mask & (level)) \
128 		printf args
129 #else
130 #define WDCDEBUG_PRINT(args, level)
131 #endif
132 
133 struct wd_softc {
134 	/* General disk infos */
135 	struct device sc_dev;
136 	struct disk sc_dk;
137 	struct buf_queue sc_q;
138 	struct callout sc_restart_ch;
139 	/* IDE disk soft states */
140 	struct ata_bio sc_wdc_bio; /* current transfer */
141 	struct buf *sc_bp; /* buf being transfered */
142 	void *wdc_softc;   /* pointer to our parent */
143 	struct ata_drive_datas *drvp; /* Our controller's infos */
144 	const struct ata_bustype *atabus;
145 	int openings;
146 	struct ataparams sc_params;/* drive characteistics found */
147 	int sc_flags;
148 #define	WDF_LOCKED	0x001
149 #define	WDF_WANTED	0x002
150 #define	WDF_WLABEL	0x004 /* label is writable */
151 #define	WDF_LABELLING	0x008 /* writing label */
152 /*
153  * XXX Nothing resets this yet, but disk change sensing will when ATA-4 is
154  * more fully implemented.
155  */
156 #define WDF_LOADED	0x010 /* parameters loaded */
157 #define WDF_WAIT	0x020 /* waiting for resources */
158 #define WDF_LBA		0x040 /* using LBA mode */
159 #define WDF_KLABEL	0x080 /* retain label after 'full' close */
160 #define WDF_LBA48	0x100 /* using 48-bit LBA mode */
161 	int sc_capacity;
162 	int cyl; /* actual drive parameters */
163 	int heads;
164 	int sectors;
165 	int retries; /* number of xfer retry */
166 
167 	void *sc_sdhook;		/* our shutdown hook */
168 
169 #if NRND > 0
170 	rndsource_element_t	rnd_source;
171 #endif
172 };
173 
174 #define sc_drive sc_wdc_bio.drive
175 #define sc_mode sc_wdc_bio.mode
176 #define sc_multi sc_wdc_bio.multi
177 #define sc_badsect sc_wdc_bio.badsect
178 
179 int	wdprobe		__P((struct device *, struct cfdata *, void *));
180 void	wdattach	__P((struct device *, struct device *, void *));
181 int	wddetach __P((struct device *, int));
182 int	wdactivate __P((struct device *, enum devact));
183 int	wdprint	__P((void *, char *));
184 void    wdperror __P((struct ata_drive_datas *, int, char *));
185 
186 struct cfattach wd_ca = {
187 	sizeof(struct wd_softc), wdprobe, wdattach, wddetach, wdactivate
188 };
189 
190 extern struct cfdriver wd_cd;
191 
192 /*
193  * Glue necessary to hook WDCIOCCOMMAND into physio
194  */
195 
196 struct wd_ioctl {
197 	LIST_ENTRY(wd_ioctl) wi_list;
198 	struct buf wi_bp;
199 	struct uio wi_uio;
200 	struct iovec wi_iov;
201 	atareq_t wi_atareq;
202 	struct wd_softc *wi_softc;
203 };
204 
205 LIST_HEAD(, wd_ioctl) wi_head;
206 
207 struct	wd_ioctl *wi_find __P((struct buf *));
208 void	wi_free __P((struct wd_ioctl *));
209 struct	wd_ioctl *wi_get __P((void));
210 void	wdioctlstrategy __P((struct buf *));
211 
212 void  wdgetdefaultlabel __P((struct wd_softc *, struct disklabel *));
213 void  wdgetdisklabel	__P((struct wd_softc *));
214 void  wdstrategy	__P((struct buf *));
215 void  wdstart	__P((void *));
216 void  __wdstart	__P((struct wd_softc*, struct buf *));
217 void  wdrestart __P((void*));
218 int   wd_get_params __P((struct wd_softc *, u_int8_t, struct ataparams *));
219 void  wd_flushcache __P((struct wd_softc *, int));
220 void  wd_shutdown __P((void*));
221 
222 struct dkdriver wddkdriver = { wdstrategy };
223 
224 /* XXX: these should go elsewhere */
225 cdev_decl(wd);
226 bdev_decl(wd);
227 
228 #ifdef HAS_BAD144_HANDLING
229 static void bad144intern __P((struct wd_softc *));
230 #endif
231 int	wdlock	__P((struct wd_softc *));
232 void	wdunlock	__P((struct wd_softc *));
233 
234 int
235 wdprobe(parent, match, aux)
236 	struct device *parent;
237 	struct cfdata *match;
238 
239 	void *aux;
240 {
241 	struct ata_device *adev = aux;
242 
243 	if (adev == NULL)
244 		return 0;
245 	if (adev->adev_bustype->bustype_type != SCSIPI_BUSTYPE_ATA)
246 		return 0;
247 
248 	if (match->cf_loc[ATACF_CHANNEL] != ATACF_CHANNEL_DEFAULT &&
249 	    match->cf_loc[ATACF_CHANNEL] != adev->adev_channel)
250 		return 0;
251 
252 	if (match->cf_loc[ATACF_DRIVE] != ATACF_DRIVE_DEFAULT &&
253 	    match->cf_loc[ATACF_DRIVE] != adev->adev_drv_data->drive)
254 		return 0;
255 	return 1;
256 }
257 
258 void
259 wdattach(parent, self, aux)
260 	struct device *parent, *self;
261 	void *aux;
262 {
263 	struct wd_softc *wd = (void *)self;
264 	struct ata_device *adev= aux;
265 	int i, blank;
266 	char buf[41], pbuf[9], c, *p, *q;
267 	WDCDEBUG_PRINT(("wdattach\n"), DEBUG_FUNCS | DEBUG_PROBE);
268 
269 	callout_init(&wd->sc_restart_ch);
270 	BUFQ_INIT(&wd->sc_q);
271 
272 	wd->atabus = adev->adev_bustype;
273 	wd->openings = adev->adev_openings;
274 	wd->drvp = adev->adev_drv_data;;
275 	wd->wdc_softc = parent;
276 	/* give back our softc to our caller */
277 	wd->drvp->drv_softc = &wd->sc_dev;
278 
279 	/* read our drive info */
280 	if (wd_get_params(wd, AT_POLL, &wd->sc_params) != 0) {
281 		printf("%s: IDENTIFY failed\n", wd->sc_dev.dv_xname);
282 		return;
283 	}
284 
285 	for (blank = 0, p = wd->sc_params.atap_model, q = buf, i = 0;
286 	    i < sizeof(wd->sc_params.atap_model); i++) {
287 		c = *p++;
288 		if (c == '\0')
289 			break;
290 		if (c != ' ') {
291 			if (blank) {
292 				*q++ = ' ';
293 				blank = 0;
294 			}
295 			*q++ = c;
296 		} else
297 			blank = 1;
298 	}
299 	*q++ = '\0';
300 
301 	printf(": <%s>\n", buf);
302 
303 	if ((wd->sc_params.atap_multi & 0xff) > 1) {
304 		wd->sc_multi = wd->sc_params.atap_multi & 0xff;
305 	} else {
306 		wd->sc_multi = 1;
307 	}
308 
309 	printf("%s: drive supports %d-sector PIO transfers,",
310 	    wd->sc_dev.dv_xname, wd->sc_multi);
311 
312 	/* 48-bit LBA addressing */
313 	if ((wd->sc_params.atap_cmd2_en & WDC_CAP_LBA48) != 0)
314 		wd->sc_flags |= WDF_LBA48;
315 
316 	/* Prior to ATA-4, LBA was optional. */
317 	if ((wd->sc_params.atap_capabilities1 & WDC_CAP_LBA) != 0)
318 		wd->sc_flags |= WDF_LBA;
319 #if 0
320 	/* ATA-4 requires LBA. */
321 	if (wd->sc_params.atap_ataversion != 0xffff &&
322 	    wd->sc_params.atap_ataversion >= WDC_VER_ATA4)
323 		wd->sc_flags |= WDF_LBA;
324 #endif
325 
326 	if ((wd->sc_flags & WDF_LBA48) != 0) {
327 		printf(" LBA48 addressing\n");
328 		wd->sc_capacity =
329 		    ((u_int64_t) wd->sc_params.__reserved6[11] << 48) |
330 		    ((u_int64_t) wd->sc_params.__reserved6[10] << 32) |
331 		    ((u_int64_t) wd->sc_params.__reserved6[9]  << 16) |
332 		    ((u_int64_t) wd->sc_params.__reserved6[8]  << 0);
333 	} else if ((wd->sc_flags & WDF_LBA) != 0) {
334 		printf(" LBA addressing\n");
335 		wd->sc_capacity =
336 		    (wd->sc_params.atap_capacity[1] << 16) |
337 		    wd->sc_params.atap_capacity[0];
338 	} else {
339 		printf(" chs addressing\n");
340 		wd->sc_capacity =
341 		    wd->sc_params.atap_cylinders *
342 		    wd->sc_params.atap_heads *
343 		    wd->sc_params.atap_sectors;
344 	}
345 	format_bytes(pbuf, sizeof(pbuf),
346 	    (u_int64_t)wd->sc_capacity * DEV_BSIZE);
347 	printf("%s: %s, %d cyl, %d head, %d sec, "
348 	    "%d bytes/sect x %d sectors\n",
349 	    self->dv_xname, pbuf, wd->sc_params.atap_cylinders,
350 	    wd->sc_params.atap_heads, wd->sc_params.atap_sectors,
351 	    DEV_BSIZE, wd->sc_capacity);
352 
353 	WDCDEBUG_PRINT(("%s: atap_dmatiming_mimi=%d, atap_dmatiming_recom=%d\n",
354 	    self->dv_xname, wd->sc_params.atap_dmatiming_mimi,
355 	    wd->sc_params.atap_dmatiming_recom), DEBUG_PROBE);
356 	/*
357 	 * Initialize and attach the disk structure.
358 	 */
359 	wd->sc_dk.dk_driver = &wddkdriver;
360 	wd->sc_dk.dk_name = wd->sc_dev.dv_xname;
361 	disk_attach(&wd->sc_dk);
362 	wd->sc_wdc_bio.lp = wd->sc_dk.dk_label;
363 	wd->sc_sdhook = shutdownhook_establish(wd_shutdown, wd);
364 	if (wd->sc_sdhook == NULL)
365 		printf("%s: WARNING: unable to establish shutdown hook\n",
366 		    wd->sc_dev.dv_xname);
367 #if NRND > 0
368 	rnd_attach_source(&wd->rnd_source, wd->sc_dev.dv_xname,
369 			  RND_TYPE_DISK, 0);
370 #endif
371 }
372 
373 int
374 wdactivate(self, act)
375 	struct device *self;
376 	enum devact act;
377 {
378 	int rv = 0;
379 
380 	switch (act) {
381 	case DVACT_ACTIVATE:
382 		rv = EOPNOTSUPP;
383 		break;
384 
385 	case DVACT_DEACTIVATE:
386 		/*
387 		 * Nothing to do; we key off the device's DVF_ACTIVATE.
388 		 */
389 		break;
390 	}
391 	return (rv);
392 }
393 
394 int
395 wddetach(self, flags)
396 	struct device *self;
397 	int flags;
398 {
399 	struct wd_softc *sc = (struct wd_softc *)self;
400 	struct buf *bp;
401 	int s, bmaj, cmaj, i, mn;
402 
403 	/* locate the major number */
404 	for (bmaj = 0; bmaj < nblkdev; bmaj++)
405 		if (bdevsw[bmaj].d_open == wdopen)
406 			break;
407 	for (cmaj = 0; cmaj < nchrdev; cmaj++)
408 		if (cdevsw[cmaj].d_open == wdopen)
409 			break;
410 
411 	s = splbio();
412 
413 	/* Kill off any queued buffers. */
414 	while ((bp = BUFQ_FIRST(&sc->sc_q)) != NULL) {
415 		BUFQ_REMOVE(&sc->sc_q, bp);
416 		bp->b_error = EIO;
417 		bp->b_flags |= B_ERROR;
418 		bp->b_resid = bp->b_bcount;
419 		biodone(bp);
420 	}
421 
422 	splx(s);
423 
424 	/* Nuke the vnodes for any open instances. */
425 	for (i = 0; i < MAXPARTITIONS; i++) {
426 		mn = WDMINOR(self->dv_unit, i);
427 		vdevgone(bmaj, mn, mn, VBLK);
428 		vdevgone(cmaj, mn, mn, VCHR);
429 	}
430 
431 	/* Detach disk. */
432 	disk_detach(&sc->sc_dk);
433 
434 	/* Get rid of the shutdown hook. */
435 	if (sc->sc_sdhook != NULL)
436 		shutdownhook_disestablish(sc->sc_sdhook);
437 
438 #if NRND > 0
439 	/* Unhook the entropy source. */
440 	rnd_detach_source(&sc->rnd_source);
441 #endif
442 
443 	return (0);
444 }
445 
446 /*
447  * Read/write routine for a buffer.  Validates the arguments and schedules the
448  * transfer.  Does not wait for the transfer to complete.
449  */
450 void
451 wdstrategy(bp)
452 	struct buf *bp;
453 {
454 	struct wd_softc *wd = device_lookup(&wd_cd, WDUNIT(bp->b_dev));
455 	struct disklabel *lp = wd->sc_dk.dk_label;
456 	daddr_t blkno;
457 	int s;
458 
459 	WDCDEBUG_PRINT(("wdstrategy (%s)\n", wd->sc_dev.dv_xname),
460 	    DEBUG_XFERS);
461 
462 	/* Valid request?  */
463 	if (bp->b_blkno < 0 ||
464 	    (bp->b_bcount % lp->d_secsize) != 0 ||
465 	    (bp->b_bcount / lp->d_secsize) >= (1 << NBBY)) {
466 		bp->b_error = EINVAL;
467 		goto bad;
468 	}
469 
470 	/* If device invalidated (e.g. media change, door open), error. */
471 	if ((wd->sc_flags & WDF_LOADED) == 0) {
472 		bp->b_error = EIO;
473 		goto bad;
474 	}
475 
476 	/* If it's a null transfer, return immediately. */
477 	if (bp->b_bcount == 0)
478 		goto done;
479 
480 	/*
481 	 * Do bounds checking, adjust transfer. if error, process.
482 	 * If end of partition, just return.
483 	 */
484 	if (WDPART(bp->b_dev) != RAW_PART &&
485 	    bounds_check_with_label(bp, wd->sc_dk.dk_label,
486 	    (wd->sc_flags & (WDF_WLABEL|WDF_LABELLING)) != 0) <= 0)
487 		goto done;
488 
489 	/*
490 	 * Now convert the block number to absolute and put it in
491 	 * terms of the device's logical block size.
492 	 */
493 	if (lp->d_secsize >= DEV_BSIZE)
494 		blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE);
495 	else
496 		blkno = bp->b_blkno * (DEV_BSIZE / lp->d_secsize);
497 
498 	if (WDPART(bp->b_dev) != RAW_PART)
499 		blkno += lp->d_partitions[WDPART(bp->b_dev)].p_offset;
500 
501 	bp->b_rawblkno = blkno;
502 
503 	/* Queue transfer on drive, activate drive and controller if idle. */
504 	s = splbio();
505 	disksort_blkno(&wd->sc_q, bp);
506 	wdstart(wd);
507 	splx(s);
508 	return;
509 bad:
510 	bp->b_flags |= B_ERROR;
511 done:
512 	/* Toss transfer; we're done early. */
513 	bp->b_resid = bp->b_bcount;
514 	biodone(bp);
515 }
516 
517 /*
518  * Queue a drive for I/O.
519  */
520 void
521 wdstart(arg)
522 	void *arg;
523 {
524 	struct wd_softc *wd = arg;
525 	struct buf *bp = NULL;
526 
527 	WDCDEBUG_PRINT(("wdstart %s\n", wd->sc_dev.dv_xname),
528 	    DEBUG_XFERS);
529 	while (wd->openings > 0) {
530 
531 		/* Is there a buf for us ? */
532 		if ((bp = BUFQ_FIRST(&wd->sc_q)) == NULL)
533 			return;
534 		BUFQ_REMOVE(&wd->sc_q, bp);
535 
536 		/*
537 		 * Make the command. First lock the device
538 		 */
539 		wd->openings--;
540 
541 		wd->retries = 0;
542 		__wdstart(wd, bp);
543 	}
544 }
545 
546 void
547 __wdstart(wd, bp)
548 	struct wd_softc *wd;
549 	struct buf *bp;
550 {
551 
552 	wd->sc_wdc_bio.blkno = bp->b_rawblkno;
553 	wd->sc_wdc_bio.blkdone =0;
554 	wd->sc_bp = bp;
555 	/*
556 	 * If we're retrying, retry in single-sector mode. This will give us
557 	 * the sector number of the problem, and will eventually allow the
558 	 * transfer to succeed.
559 	 */
560 	if (wd->sc_multi == 1 || wd->retries >= WDIORETRIES_SINGLE)
561 		wd->sc_wdc_bio.flags = ATA_SINGLE;
562 	else
563 		wd->sc_wdc_bio.flags = 0;
564 	if (wd->sc_flags & WDF_LBA48)
565 		wd->sc_wdc_bio.flags |= ATA_LBA48;
566 	if (wd->sc_flags & WDF_LBA)
567 		wd->sc_wdc_bio.flags |= ATA_LBA;
568 	if (bp->b_flags & B_READ)
569 		wd->sc_wdc_bio.flags |= ATA_READ;
570 	wd->sc_wdc_bio.bcount = bp->b_bcount;
571 	wd->sc_wdc_bio.databuf = bp->b_data;
572 	/* Instrumentation. */
573 	disk_busy(&wd->sc_dk);
574 	switch (wd->atabus->ata_bio(wd->drvp, &wd->sc_wdc_bio)) {
575 	case WDC_TRY_AGAIN:
576 		callout_reset(&wd->sc_restart_ch, hz, wdrestart, wd);
577 		break;
578 	case WDC_QUEUED:
579 	case WDC_COMPLETE:
580 		break;
581 	default:
582 		panic("__wdstart: bad return code from ata_bio()");
583 	}
584 }
585 
586 void
587 wddone(v)
588 	void *v;
589 {
590 	struct wd_softc *wd = v;
591 	struct buf *bp = wd->sc_bp;
592 	char buf[256], *errbuf = buf;
593 	WDCDEBUG_PRINT(("wddone %s\n", wd->sc_dev.dv_xname),
594 	    DEBUG_XFERS);
595 
596 	if (bp == NULL)
597 		return;
598 	bp->b_resid = wd->sc_wdc_bio.bcount;
599 	errbuf[0] = '\0';
600 	switch (wd->sc_wdc_bio.error) {
601 	case ERR_DMA:
602 		errbuf = "DMA error";
603 		goto retry;
604 	case ERR_DF:
605 		errbuf = "device fault";
606 		goto retry;
607 	case TIMEOUT:
608 		errbuf = "device timeout";
609 		goto retry;
610 	case ERROR:
611 		/* Don't care about media change bits */
612 		if (wd->sc_wdc_bio.r_error != 0 &&
613 		    (wd->sc_wdc_bio.r_error & ~(WDCE_MC | WDCE_MCR)) == 0)
614 			goto noerror;
615 		wdperror(wd->drvp, wd->sc_wdc_bio.r_error, errbuf);
616 retry:		/* Just reset and retry. Can we do more ? */
617 		wd->atabus->ata_reset_channel(wd->drvp);
618 		diskerr(bp, "wd", errbuf, LOG_PRINTF,
619 		    wd->sc_wdc_bio.blkdone, wd->sc_dk.dk_label);
620 		if (wd->retries++ < WDIORETRIES) {
621 			printf(", retrying\n");
622 			callout_reset(&wd->sc_restart_ch, RECOVERYTIME,
623 			    wdrestart, wd);
624 			return;
625 		}
626 		printf("\n");
627 		bp->b_flags |= B_ERROR;
628 		bp->b_error = EIO;
629 		break;
630 	case NOERROR:
631 noerror:	if ((wd->sc_wdc_bio.flags & ATA_CORR) || wd->retries > 0)
632 			printf("%s: soft error (corrected)\n",
633 			    wd->sc_dev.dv_xname);
634 		break;
635 	case ERR_NODEV:
636 		bp->b_flags |= B_ERROR;
637 		bp->b_error = EIO;
638 		break;
639 	}
640 	disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid));
641 #if NRND > 0
642 	rnd_add_uint32(&wd->rnd_source, bp->b_blkno);
643 #endif
644 	biodone(bp);
645 	wd->openings++;
646 	wdstart(wd);
647 }
648 
649 void
650 wdrestart(v)
651 	void *v;
652 {
653 	struct wd_softc *wd = v;
654 	struct buf *bp = wd->sc_bp;
655 	int s;
656 	WDCDEBUG_PRINT(("wdrestart %s\n", wd->sc_dev.dv_xname),
657 	    DEBUG_XFERS);
658 
659 	s = splbio();
660 	__wdstart(v, bp);
661 	splx(s);
662 }
663 
664 int
665 wdread(dev, uio, flags)
666 	dev_t dev;
667 	struct uio *uio;
668 	int flags;
669 {
670 
671 	WDCDEBUG_PRINT(("wdread\n"), DEBUG_XFERS);
672 	return (physio(wdstrategy, NULL, dev, B_READ, minphys, uio));
673 }
674 
675 int
676 wdwrite(dev, uio, flags)
677 	dev_t dev;
678 	struct uio *uio;
679 	int flags;
680 {
681 
682 	WDCDEBUG_PRINT(("wdwrite\n"), DEBUG_XFERS);
683 	return (physio(wdstrategy, NULL, dev, B_WRITE, minphys, uio));
684 }
685 
686 /*
687  * Wait interruptibly for an exclusive lock.
688  *
689  * XXX
690  * Several drivers do this; it should be abstracted and made MP-safe.
691  */
692 int
693 wdlock(wd)
694 	struct wd_softc *wd;
695 {
696 	int error;
697 	int s;
698 
699 	WDCDEBUG_PRINT(("wdlock\n"), DEBUG_FUNCS);
700 
701 	s = splbio();
702 
703 	while ((wd->sc_flags & WDF_LOCKED) != 0) {
704 		wd->sc_flags |= WDF_WANTED;
705 		if ((error = tsleep(wd, PRIBIO | PCATCH,
706 		    "wdlck", 0)) != 0) {
707 			splx(s);
708 			return error;
709 		}
710 	}
711 	wd->sc_flags |= WDF_LOCKED;
712 	splx(s);
713 	return 0;
714 }
715 
716 /*
717  * Unlock and wake up any waiters.
718  */
719 void
720 wdunlock(wd)
721 	struct wd_softc *wd;
722 {
723 
724 	WDCDEBUG_PRINT(("wdunlock\n"), DEBUG_FUNCS);
725 
726 	wd->sc_flags &= ~WDF_LOCKED;
727 	if ((wd->sc_flags & WDF_WANTED) != 0) {
728 		wd->sc_flags &= ~WDF_WANTED;
729 		wakeup(wd);
730 	}
731 }
732 
733 int
734 wdopen(dev, flag, fmt, p)
735 	dev_t dev;
736 	int flag, fmt;
737 	struct proc *p;
738 {
739 	struct wd_softc *wd;
740 	int part, error;
741 
742 	WDCDEBUG_PRINT(("wdopen\n"), DEBUG_FUNCS);
743 	wd = device_lookup(&wd_cd, WDUNIT(dev));
744 	if (wd == NULL)
745 		return (ENXIO);
746 
747 	/*
748 	 * If this is the first open of this device, add a reference
749 	 * to the adapter.
750 	 */
751 	if (wd->sc_dk.dk_openmask == 0 &&
752 	    (error = wd->atabus->ata_addref(wd->drvp)) != 0)
753 		return (error);
754 
755 	if ((error = wdlock(wd)) != 0)
756 		goto bad4;
757 
758 	if (wd->sc_dk.dk_openmask != 0) {
759 		/*
760 		 * If any partition is open, but the disk has been invalidated,
761 		 * disallow further opens.
762 		 */
763 		if ((wd->sc_flags & WDF_LOADED) == 0) {
764 			error = EIO;
765 			goto bad3;
766 		}
767 	} else {
768 		if ((wd->sc_flags & WDF_LOADED) == 0) {
769 			wd->sc_flags |= WDF_LOADED;
770 
771 			/* Load the physical device parameters. */
772 			wd_get_params(wd, AT_WAIT, &wd->sc_params);
773 
774 			/* Load the partition info if not already loaded. */
775 			wdgetdisklabel(wd);
776 		}
777 	}
778 
779 	part = WDPART(dev);
780 
781 	/* Check that the partition exists. */
782 	if (part != RAW_PART &&
783 	    (part >= wd->sc_dk.dk_label->d_npartitions ||
784 	     wd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
785 		error = ENXIO;
786 		goto bad;
787 	}
788 
789 	/* Insure only one open at a time. */
790 	switch (fmt) {
791 	case S_IFCHR:
792 		wd->sc_dk.dk_copenmask |= (1 << part);
793 		break;
794 	case S_IFBLK:
795 		wd->sc_dk.dk_bopenmask |= (1 << part);
796 		break;
797 	}
798 	wd->sc_dk.dk_openmask =
799 	    wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
800 
801 	wdunlock(wd);
802 	return 0;
803 
804 bad:
805 	if (wd->sc_dk.dk_openmask == 0) {
806 	}
807 
808 bad3:
809 	wdunlock(wd);
810 bad4:
811 	if (wd->sc_dk.dk_openmask == 0)
812 		wd->atabus->ata_delref(wd->drvp);
813 	return error;
814 }
815 
816 int
817 wdclose(dev, flag, fmt, p)
818 	dev_t dev;
819 	int flag, fmt;
820 	struct proc *p;
821 {
822 	struct wd_softc *wd = device_lookup(&wd_cd, WDUNIT(dev));
823 	int part = WDPART(dev);
824 	int error;
825 
826 	WDCDEBUG_PRINT(("wdclose\n"), DEBUG_FUNCS);
827 	if ((error = wdlock(wd)) != 0)
828 		return error;
829 
830 	switch (fmt) {
831 	case S_IFCHR:
832 		wd->sc_dk.dk_copenmask &= ~(1 << part);
833 		break;
834 	case S_IFBLK:
835 		wd->sc_dk.dk_bopenmask &= ~(1 << part);
836 		break;
837 	}
838 	wd->sc_dk.dk_openmask =
839 	    wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
840 
841 	if (wd->sc_dk.dk_openmask == 0) {
842 		wd_flushcache(wd, AT_WAIT);
843 		/* XXXX Must wait for I/O to complete! */
844 
845 		if (! (wd->sc_flags & WDF_KLABEL))
846 			wd->sc_flags &= ~WDF_LOADED;
847 
848 		wd->atabus->ata_delref(wd->drvp);
849 	}
850 
851 	wdunlock(wd);
852 	return 0;
853 }
854 
855 void
856 wdgetdefaultlabel(wd, lp)
857 	struct wd_softc *wd;
858 	struct disklabel *lp;
859 {
860 
861 	WDCDEBUG_PRINT(("wdgetdefaultlabel\n"), DEBUG_FUNCS);
862 	memset(lp, 0, sizeof(struct disklabel));
863 
864 	lp->d_secsize = DEV_BSIZE;
865 	lp->d_ntracks = wd->sc_params.atap_heads;
866 	lp->d_nsectors = wd->sc_params.atap_sectors;
867 	lp->d_ncylinders = wd->sc_params.atap_cylinders;
868 	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
869 
870 	if (strcmp(wd->sc_params.atap_model, "ST506") == 0)
871 		lp->d_type = DTYPE_ST506;
872 	else
873 		lp->d_type = DTYPE_ESDI;
874 
875 	strncpy(lp->d_typename, wd->sc_params.atap_model, 16);
876 	strncpy(lp->d_packname, "fictitious", 16);
877 	lp->d_secperunit = wd->sc_capacity;
878 	lp->d_rpm = 3600;
879 	lp->d_interleave = 1;
880 	lp->d_flags = 0;
881 
882 	lp->d_partitions[RAW_PART].p_offset = 0;
883 	lp->d_partitions[RAW_PART].p_size =
884 	lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
885 	lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
886 	lp->d_npartitions = RAW_PART + 1;
887 
888 	lp->d_magic = DISKMAGIC;
889 	lp->d_magic2 = DISKMAGIC;
890 	lp->d_checksum = dkcksum(lp);
891 }
892 
893 /*
894  * Fabricate a default disk label, and try to read the correct one.
895  */
896 void
897 wdgetdisklabel(wd)
898 	struct wd_softc *wd;
899 {
900 	struct disklabel *lp = wd->sc_dk.dk_label;
901 	char *errstring;
902 
903 	WDCDEBUG_PRINT(("wdgetdisklabel\n"), DEBUG_FUNCS);
904 
905 	memset(wd->sc_dk.dk_cpulabel, 0, sizeof(struct cpu_disklabel));
906 
907 	wdgetdefaultlabel(wd, lp);
908 
909 	wd->sc_badsect[0] = -1;
910 
911 	if (wd->drvp->state > RECAL)
912 		wd->drvp->drive_flags |= DRIVE_RESET;
913 	errstring = readdisklabel(MAKEWDDEV(0, wd->sc_dev.dv_unit, RAW_PART),
914 	    wdstrategy, lp, wd->sc_dk.dk_cpulabel);
915 	if (errstring) {
916 		/*
917 		 * This probably happened because the drive's default
918 		 * geometry doesn't match the DOS geometry.  We
919 		 * assume the DOS geometry is now in the label and try
920 		 * again.  XXX This is a kluge.
921 		 */
922 		if (wd->drvp->state > RECAL)
923 			wd->drvp->drive_flags |= DRIVE_RESET;
924 		errstring = readdisklabel(MAKEWDDEV(0, wd->sc_dev.dv_unit,
925 		    RAW_PART), wdstrategy, lp, wd->sc_dk.dk_cpulabel);
926 	}
927 	if (errstring) {
928 		printf("%s: %s\n", wd->sc_dev.dv_xname, errstring);
929 		return;
930 	}
931 
932 	if (wd->drvp->state > RECAL)
933 		wd->drvp->drive_flags |= DRIVE_RESET;
934 #ifdef HAS_BAD144_HANDLING
935 	if ((lp->d_flags & D_BADSECT) != 0)
936 		bad144intern(wd);
937 #endif
938 }
939 
940 void
941 wdperror(drvp, errno, buf)
942 	struct ata_drive_datas *drvp;
943 	int errno;
944 	char *buf;
945 {
946 	static char *errstr0_3[] = {"address mark not found",
947 	    "track 0 not found", "aborted command", "media change requested",
948 	    "id not found", "media changed", "uncorrectable data error",
949 	    "bad block detected"};
950 	static char *errstr4_5[] = {"obsolete (address mark not found)",
951 	    "no media/write protected", "aborted command",
952 	    "media change requested", "id not found", "media changed",
953 	    "uncorrectable data error", "interface CRC error"};
954 	char **errstr;
955 	int i;
956 	char *sep = "";
957 
958 	if (drvp->ata_vers >= 4)
959 		errstr = errstr4_5;
960 	else
961 		errstr = errstr0_3;
962 
963 	if (errno == 0)
964 		sprintf(buf, "error not notified");
965 
966 	for (i = 0; i < 8; i++) {
967 		if (errno & (1 << i)) {
968 			buf += sprintf(buf, "%s%s", sep, errstr[i]);
969 			sep = ", ";
970 		}
971 	}
972 }
973 
974 int
975 wdioctl(dev, xfer, addr, flag, p)
976 	dev_t dev;
977 	u_long xfer;
978 	caddr_t addr;
979 	int flag;
980 	struct proc *p;
981 {
982 	struct wd_softc *wd = device_lookup(&wd_cd, WDUNIT(dev));
983 	int error;
984 #ifdef __HAVE_OLD_DISKLABEL
985 	struct disklabel newlabel;
986 #endif
987 
988 	WDCDEBUG_PRINT(("wdioctl\n"), DEBUG_FUNCS);
989 
990 	if ((wd->sc_flags & WDF_LOADED) == 0)
991 		return EIO;
992 
993 	switch (xfer) {
994 #ifdef HAS_BAD144_HANDLING
995 	case DIOCSBAD:
996 		if ((flag & FWRITE) == 0)
997 			return EBADF;
998 		wd->sc_dk.dk_cpulabel->bad = *(struct dkbad *)addr;
999 		wd->sc_dk.dk_label->d_flags |= D_BADSECT;
1000 		bad144intern(wd);
1001 		return 0;
1002 #endif
1003 
1004 	case DIOCGDINFO:
1005 		*(struct disklabel *)addr = *(wd->sc_dk.dk_label);
1006 		return 0;
1007 #ifdef __HAVE_OLD_DISKLABEL
1008 	case ODIOCGDINFO:
1009 		newlabel = *(wd->sc_dk.dk_label);
1010 		if (newlabel.d_npartitions > OLDMAXPARTITIONS)
1011 			return ENOTTY;
1012 		memcpy(addr, &newlabel, sizeof (struct olddisklabel));
1013 		return 0;
1014 #endif
1015 
1016 	case DIOCGPART:
1017 		((struct partinfo *)addr)->disklab = wd->sc_dk.dk_label;
1018 		((struct partinfo *)addr)->part =
1019 		    &wd->sc_dk.dk_label->d_partitions[WDPART(dev)];
1020 		return 0;
1021 
1022 	case DIOCWDINFO:
1023 	case DIOCSDINFO:
1024 #ifdef __HAVE_OLD_DISKLABEL
1025 	case ODIOCWDINFO:
1026 	case ODIOCSDINFO:
1027 #endif
1028 	{
1029 		struct disklabel *lp;
1030 
1031 #ifdef __HAVE_OLD_DISKLABEL
1032 		if (xfer == ODIOCSDINFO || xfer == ODIOCWDINFO) {
1033 			memset(&newlabel, 0, sizeof newlabel);
1034 			memcpy(&newlabel, addr, sizeof (struct olddisklabel));
1035 			lp = &newlabel;
1036 		} else
1037 #endif
1038 		lp = (struct disklabel *)addr;
1039 
1040 		if ((flag & FWRITE) == 0)
1041 			return EBADF;
1042 
1043 		if ((error = wdlock(wd)) != 0)
1044 			return error;
1045 		wd->sc_flags |= WDF_LABELLING;
1046 
1047 		error = setdisklabel(wd->sc_dk.dk_label,
1048 		    lp, /*wd->sc_dk.dk_openmask : */0,
1049 		    wd->sc_dk.dk_cpulabel);
1050 		if (error == 0) {
1051 			if (wd->drvp->state > RECAL)
1052 				wd->drvp->drive_flags |= DRIVE_RESET;
1053 			if (xfer == DIOCWDINFO
1054 #ifdef __HAVE_OLD_DISKLABEL
1055 			    || xfer == ODIOCWDINFO
1056 #endif
1057 			    )
1058 				error = writedisklabel(WDLABELDEV(dev),
1059 				    wdstrategy, wd->sc_dk.dk_label,
1060 				    wd->sc_dk.dk_cpulabel);
1061 		}
1062 
1063 		wd->sc_flags &= ~WDF_LABELLING;
1064 		wdunlock(wd);
1065 		return error;
1066 	}
1067 
1068 	case DIOCKLABEL:
1069 		if (*(int *)addr)
1070 			wd->sc_flags |= WDF_KLABEL;
1071 		else
1072 			wd->sc_flags &= ~WDF_KLABEL;
1073 		return 0;
1074 
1075 	case DIOCWLABEL:
1076 		if ((flag & FWRITE) == 0)
1077 			return EBADF;
1078 		if (*(int *)addr)
1079 			wd->sc_flags |= WDF_WLABEL;
1080 		else
1081 			wd->sc_flags &= ~WDF_WLABEL;
1082 		return 0;
1083 
1084 	case DIOCGDEFLABEL:
1085 		wdgetdefaultlabel(wd, (struct disklabel *)addr);
1086 		return 0;
1087 #ifdef __HAVE_OLD_DISKLABEL
1088 	case ODIOCGDEFLABEL:
1089 		wdgetdefaultlabel(wd, &newlabel);
1090 		if (newlabel.d_npartitions > OLDMAXPARTITIONS)
1091 			return ENOTTY;
1092 		memcpy(addr, &newlabel, sizeof (struct olddisklabel));
1093 		return 0;
1094 #endif
1095 
1096 #ifdef notyet
1097 	case DIOCWFORMAT:
1098 		if ((flag & FWRITE) == 0)
1099 			return EBADF;
1100 		{
1101 		register struct format_op *fop;
1102 		struct iovec aiov;
1103 		struct uio auio;
1104 
1105 		fop = (struct format_op *)addr;
1106 		aiov.iov_base = fop->df_buf;
1107 		aiov.iov_len = fop->df_count;
1108 		auio.uio_iov = &aiov;
1109 		auio.uio_iovcnt = 1;
1110 		auio.uio_resid = fop->df_count;
1111 		auio.uio_segflg = 0;
1112 		auio.uio_offset =
1113 			fop->df_startblk * wd->sc_dk.dk_label->d_secsize;
1114 		auio.uio_procp = p;
1115 		error = physio(wdformat, NULL, dev, B_WRITE, minphys,
1116 		    &auio);
1117 		fop->df_count -= auio.uio_resid;
1118 		fop->df_reg[0] = wdc->sc_status;
1119 		fop->df_reg[1] = wdc->sc_error;
1120 		return error;
1121 		}
1122 #endif
1123 
1124 	case ATAIOCCOMMAND:
1125 		/*
1126 		 * Make sure this command is (relatively) safe first
1127 		 */
1128 		if ((((atareq_t *) addr)->flags & ATACMD_READ) == 0 &&
1129 		    (flag & FWRITE) == 0)
1130 			return (EBADF);
1131 		{
1132 		struct wd_ioctl *wi;
1133 		atareq_t *atareq = (atareq_t *) addr;
1134 		int error;
1135 
1136 		wi = wi_get();
1137 		wi->wi_softc = wd;
1138 		wi->wi_atareq = *atareq;
1139 
1140 		if (atareq->datalen && atareq->flags &
1141 		    (ATACMD_READ | ATACMD_WRITE)) {
1142 			wi->wi_iov.iov_base = atareq->databuf;
1143 			wi->wi_iov.iov_len = atareq->datalen;
1144 			wi->wi_uio.uio_iov = &wi->wi_iov;
1145 			wi->wi_uio.uio_iovcnt = 1;
1146 			wi->wi_uio.uio_resid = atareq->datalen;
1147 			wi->wi_uio.uio_offset = 0;
1148 			wi->wi_uio.uio_segflg = UIO_USERSPACE;
1149 			wi->wi_uio.uio_rw =
1150 			    (atareq->flags & ATACMD_READ) ? B_READ : B_WRITE;
1151 			wi->wi_uio.uio_procp = p;
1152 			error = physio(wdioctlstrategy, &wi->wi_bp, dev,
1153 			    (atareq->flags & ATACMD_READ) ? B_READ : B_WRITE,
1154 			    minphys, &wi->wi_uio);
1155 		} else {
1156 			/* No need to call physio if we don't have any
1157 			   user data */
1158 			wi->wi_bp.b_flags = 0;
1159 			wi->wi_bp.b_data = 0;
1160 			wi->wi_bp.b_bcount = 0;
1161 			wi->wi_bp.b_dev = 0;
1162 			wi->wi_bp.b_proc = p;
1163 			wdioctlstrategy(&wi->wi_bp);
1164 			error = wi->wi_bp.b_error;
1165 		}
1166 		*atareq = wi->wi_atareq;
1167 		wi_free(wi);
1168 		return(error);
1169 		}
1170 
1171 	default:
1172 		return ENOTTY;
1173 	}
1174 
1175 #ifdef DIAGNOSTIC
1176 	panic("wdioctl: impossible");
1177 #endif
1178 }
1179 
1180 #ifdef B_FORMAT
1181 int
1182 wdformat(struct buf *bp)
1183 {
1184 
1185 	bp->b_flags |= B_FORMAT;
1186 	return wdstrategy(bp);
1187 }
1188 #endif
1189 
1190 int
1191 wdsize(dev)
1192 	dev_t dev;
1193 {
1194 	struct wd_softc *wd;
1195 	int part, omask;
1196 	int size;
1197 
1198 	WDCDEBUG_PRINT(("wdsize\n"), DEBUG_FUNCS);
1199 
1200 	wd = device_lookup(&wd_cd, WDUNIT(dev));
1201 	if (wd == NULL)
1202 		return (-1);
1203 
1204 	part = WDPART(dev);
1205 	omask = wd->sc_dk.dk_openmask & (1 << part);
1206 
1207 	if (omask == 0 && wdopen(dev, 0, S_IFBLK, NULL) != 0)
1208 		return (-1);
1209 	if (wd->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
1210 		size = -1;
1211 	else
1212 		size = wd->sc_dk.dk_label->d_partitions[part].p_size *
1213 		    (wd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
1214 	if (omask == 0 && wdclose(dev, 0, S_IFBLK, NULL) != 0)
1215 		return (-1);
1216 	return (size);
1217 }
1218 
1219 /* #define WD_DUMP_NOT_TRUSTED if you just want to watch */
1220 static int wddoingadump = 0;
1221 static int wddumprecalibrated = 0;
1222 static int wddumpmulti = 1;
1223 
1224 /*
1225  * Dump core after a system crash.
1226  */
1227 int
1228 wddump(dev, blkno, va, size)
1229 	dev_t dev;
1230 	daddr_t blkno;
1231 	caddr_t va;
1232 	size_t size;
1233 {
1234 	struct wd_softc *wd;	/* disk unit to do the I/O */
1235 	struct disklabel *lp;   /* disk's disklabel */
1236 	int part, err;
1237 	int nblks;	/* total number of sectors left to write */
1238 	char errbuf[256];
1239 
1240 	/* Check if recursive dump; if so, punt. */
1241 	if (wddoingadump)
1242 		return EFAULT;
1243 	wddoingadump = 1;
1244 
1245 	wd = device_lookup(&wd_cd, WDUNIT(dev));
1246 	if (wd == NULL)
1247 		return (ENXIO);
1248 
1249 	part = WDPART(dev);
1250 
1251 	/* Make sure it was initialized. */
1252 	if (wd->drvp->state < READY)
1253 		return ENXIO;
1254 
1255 	/* Convert to disk sectors.  Request must be a multiple of size. */
1256 	lp = wd->sc_dk.dk_label;
1257 	if ((size % lp->d_secsize) != 0)
1258 		return EFAULT;
1259 	nblks = size / lp->d_secsize;
1260 	blkno = blkno / (lp->d_secsize / DEV_BSIZE);
1261 
1262 	/* Check transfer bounds against partition size. */
1263 	if ((blkno < 0) || ((blkno + nblks) > lp->d_partitions[part].p_size))
1264 		return EINVAL;
1265 
1266 	/* Offset block number to start of partition. */
1267 	blkno += lp->d_partitions[part].p_offset;
1268 
1269 	/* Recalibrate, if first dump transfer. */
1270 	if (wddumprecalibrated == 0) {
1271 		wddumpmulti = wd->sc_multi;
1272 		wddumprecalibrated = 1;
1273 		wd->drvp->state = RESET;
1274 	}
1275 
1276 	while (nblks > 0) {
1277 again:
1278 		wd->sc_bp = NULL;
1279 		wd->sc_wdc_bio.blkno = blkno;
1280 		wd->sc_wdc_bio.flags = ATA_POLL;
1281 		if (wddumpmulti == 1)
1282 			wd->sc_wdc_bio.flags |= ATA_SINGLE;
1283 		if (wd->sc_flags & WDF_LBA48)
1284 			wd->sc_wdc_bio.flags |= ATA_LBA48;
1285 		if (wd->sc_flags & WDF_LBA)
1286 			wd->sc_wdc_bio.flags |= ATA_LBA;
1287 		wd->sc_wdc_bio.bcount =
1288 			min(nblks, wddumpmulti) * lp->d_secsize;
1289 		wd->sc_wdc_bio.databuf = va;
1290 #ifndef WD_DUMP_NOT_TRUSTED
1291 		switch (wd->atabus->ata_bio(wd->drvp, &wd->sc_wdc_bio)) {
1292 		case WDC_TRY_AGAIN:
1293 			panic("wddump: try again");
1294 			break;
1295 		case WDC_QUEUED:
1296 			panic("wddump: polled command has been queued");
1297 			break;
1298 		case WDC_COMPLETE:
1299 			break;
1300 		}
1301 		switch(wd->sc_wdc_bio.error) {
1302 		case TIMEOUT:
1303 			printf("wddump: device timed out");
1304 			err = EIO;
1305 			break;
1306 		case ERR_DF:
1307 			printf("wddump: drive fault");
1308 			err = EIO;
1309 			break;
1310 		case ERR_DMA:
1311 			printf("wddump: DMA error");
1312 			err = EIO;
1313 			break;
1314 		case ERROR:
1315 			errbuf[0] = '\0';
1316 			wdperror(wd->drvp, wd->sc_wdc_bio.r_error, errbuf);
1317 			printf("wddump: %s", errbuf);
1318 			err = EIO;
1319 			break;
1320 		case NOERROR:
1321 			err = 0;
1322 			break;
1323 		default:
1324 			panic("wddump: unknown error type");
1325 		}
1326 		if (err != 0) {
1327 			if (wddumpmulti != 1) {
1328 				wddumpmulti = 1; /* retry in single-sector */
1329 				printf(", retrying\n");
1330 				goto again;
1331 			}
1332 			printf("\n");
1333 			return err;
1334 		}
1335 #else	/* WD_DUMP_NOT_TRUSTED */
1336 		/* Let's just talk about this first... */
1337 		printf("wd%d: dump addr 0x%x, cylin %d, head %d, sector %d\n",
1338 		    unit, va, cylin, head, sector);
1339 		delay(500 * 1000);	/* half a second */
1340 #endif
1341 
1342 		/* update block count */
1343 		nblks -= min(nblks, wddumpmulti);
1344 		blkno += min(nblks, wddumpmulti);
1345 		va += min(nblks, wddumpmulti) * lp->d_secsize;
1346 	}
1347 
1348 	wddoingadump = 0;
1349 	return 0;
1350 }
1351 
1352 #ifdef HAS_BAD144_HANDLING
1353 /*
1354  * Internalize the bad sector table.
1355  */
1356 void
1357 bad144intern(wd)
1358 	struct wd_softc *wd;
1359 {
1360 	struct dkbad *bt = &wd->sc_dk.dk_cpulabel->bad;
1361 	struct disklabel *lp = wd->sc_dk.dk_label;
1362 	int i = 0;
1363 
1364 	WDCDEBUG_PRINT(("bad144intern\n"), DEBUG_XFERS);
1365 
1366 	for (; i < NBT_BAD; i++) {
1367 		if (bt->bt_bad[i].bt_cyl == 0xffff)
1368 			break;
1369 		wd->sc_badsect[i] =
1370 		    bt->bt_bad[i].bt_cyl * lp->d_secpercyl +
1371 		    (bt->bt_bad[i].bt_trksec >> 8) * lp->d_nsectors +
1372 		    (bt->bt_bad[i].bt_trksec & 0xff);
1373 	}
1374 	for (; i < NBT_BAD+1; i++)
1375 		wd->sc_badsect[i] = -1;
1376 }
1377 #endif
1378 
1379 int
1380 wd_get_params(wd, flags, params)
1381 	struct wd_softc *wd;
1382 	u_int8_t flags;
1383 	struct ataparams *params;
1384 {
1385 	switch (wd->atabus->ata_get_params(wd->drvp, flags, params)) {
1386 	case CMD_AGAIN:
1387 		return 1;
1388 	case CMD_ERR:
1389 		/*
1390 		 * We `know' there's a drive here; just assume it's old.
1391 		 * This geometry is only used to read the MBR and print a
1392 		 * (false) attach message.
1393 		 */
1394 		strncpy(params->atap_model, "ST506",
1395 		    sizeof params->atap_model);
1396 		params->atap_config = ATA_CFG_FIXED;
1397 		params->atap_cylinders = 1024;
1398 		params->atap_heads = 8;
1399 		params->atap_sectors = 17;
1400 		params->atap_multi = 1;
1401 		params->atap_capabilities1 = params->atap_capabilities2 = 0;
1402 		wd->drvp->ata_vers = -1; /* Mark it as pre-ATA */
1403 		return 0;
1404 	case CMD_OK:
1405 		return 0;
1406 	default:
1407 		panic("wd_get_params: bad return code from ata_get_params");
1408 		/* NOTREACHED */
1409 	}
1410 }
1411 
1412 void
1413 wd_flushcache(wd, flags)
1414 	struct wd_softc *wd;
1415 	int flags;
1416 {
1417 	struct wdc_command wdc_c;
1418 
1419 	if (wd->drvp->ata_vers < 4) /* WDCC_FLUSHCACHE is here since ATA-4 */
1420 		return;
1421 	memset(&wdc_c, 0, sizeof(struct wdc_command));
1422 	wdc_c.r_command = WDCC_FLUSHCACHE;
1423 	wdc_c.r_st_bmask = WDCS_DRDY;
1424 	wdc_c.r_st_pmask = WDCS_DRDY;
1425 	wdc_c.flags = flags;
1426 	wdc_c.timeout = 30000; /* 30s timeout */
1427 	if (wd->atabus->ata_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) {
1428 		printf("%s: flush cache command didn't complete\n",
1429 		    wd->sc_dev.dv_xname);
1430 	}
1431 	if (wdc_c.flags & AT_TIMEOU) {
1432 		printf("%s: flush cache command timeout\n",
1433 		    wd->sc_dev.dv_xname);
1434 	}
1435 	if (wdc_c.flags & AT_DF) {
1436 		printf("%s: flush cache command: drive fault\n",
1437 		    wd->sc_dev.dv_xname);
1438 	}
1439 	/*
1440 	 * Ignore error register, it shouldn't report anything else
1441 	 * than COMMAND ABORTED, which means the device doesn't support
1442 	 * flush cache
1443 	 */
1444 }
1445 
1446 void
1447 wd_shutdown(arg)
1448 	void *arg;
1449 {
1450 	struct wd_softc *wd = arg;
1451 	wd_flushcache(wd, AT_POLL);
1452 }
1453 
1454 /*
1455  * Allocate space for a ioctl queue structure.  Mostly taken from
1456  * scsipi_ioctl.c
1457  */
1458 struct wd_ioctl *
1459 wi_get()
1460 {
1461 	struct wd_ioctl *wi;
1462 	int s;
1463 
1464 	wi = malloc(sizeof(struct wd_ioctl), M_TEMP, M_WAITOK|M_ZERO);
1465 	s = splbio();
1466 	LIST_INSERT_HEAD(&wi_head, wi, wi_list);
1467 	splx(s);
1468 	return (wi);
1469 }
1470 
1471 /*
1472  * Free an ioctl structure and remove it from our list
1473  */
1474 
1475 void
1476 wi_free(wi)
1477 	struct wd_ioctl *wi;
1478 {
1479 	int s;
1480 
1481 	s = splbio();
1482 	LIST_REMOVE(wi, wi_list);
1483 	splx(s);
1484 	free(wi, M_TEMP);
1485 }
1486 
1487 /*
1488  * Find a wd_ioctl structure based on the struct buf.
1489  */
1490 
1491 struct wd_ioctl *
1492 wi_find(bp)
1493 	struct buf *bp;
1494 {
1495 	struct wd_ioctl *wi;
1496 	int s;
1497 
1498 	s = splbio();
1499 	for (wi = wi_head.lh_first; wi != 0; wi = wi->wi_list.le_next)
1500 		if (bp == &wi->wi_bp)
1501 			break;
1502 	splx(s);
1503 	return (wi);
1504 }
1505 
1506 /*
1507  * Ioctl pseudo strategy routine
1508  *
1509  * This is mostly stolen from scsipi_ioctl.c:scsistrategy().  What
1510  * happens here is:
1511  *
1512  * - wdioctl() queues a wd_ioctl structure.
1513  *
1514  * - wdioctl() calls physio/wdioctlstrategy based on whether or not
1515  *   user space I/O is required.  If physio() is called, physio() eventually
1516  *   calls wdioctlstrategy().
1517  *
1518  * - In either case, wdioctlstrategy() calls wd->atabus->ata_exec_command()
1519  *   to perform the actual command
1520  *
1521  * The reason for the use of the pseudo strategy routine is because
1522  * when doing I/O to/from user space, physio _really_ wants to be in
1523  * the loop.  We could put the entire buffer into the ioctl request
1524  * structure, but that won't scale if we want to do things like download
1525  * microcode.
1526  */
1527 
1528 void
1529 wdioctlstrategy(bp)
1530 	struct buf *bp;
1531 {
1532 	struct wd_ioctl *wi;
1533 	struct wdc_command wdc_c;
1534 	int error = 0;
1535 
1536 	wi = wi_find(bp);
1537 	if (wi == NULL) {
1538 		printf("user_strat: No ioctl\n");
1539 		error = EINVAL;
1540 		goto bad;
1541 	}
1542 
1543 	memset(&wdc_c, 0, sizeof(wdc_c));
1544 
1545 	/*
1546 	 * Abort if physio broke up the transfer
1547 	 */
1548 
1549 	if (bp->b_bcount != wi->wi_atareq.datalen) {
1550 		printf("physio split wd ioctl request... cannot proceed\n");
1551 		error = EIO;
1552 		goto bad;
1553 	}
1554 
1555 	/*
1556 	 * Abort if we didn't get a buffer size that was a multiple of
1557 	 * our sector size (or was larger than NBBY)
1558 	 */
1559 
1560 	if ((bp->b_bcount % wi->wi_softc->sc_dk.dk_label->d_secsize) != 0 ||
1561 	    (bp->b_bcount / wi->wi_softc->sc_dk.dk_label->d_secsize) >=
1562 	     (1 << NBBY)) {
1563 		error = EINVAL;
1564 		goto bad;
1565 	}
1566 
1567 	/*
1568 	 * Make sure a timeout was supplied in the ioctl request
1569 	 */
1570 
1571 	if (wi->wi_atareq.timeout == 0) {
1572 		error = EINVAL;
1573 		goto bad;
1574 	}
1575 
1576 	if (wi->wi_atareq.flags & ATACMD_READ)
1577 		wdc_c.flags |= AT_READ;
1578 	else if (wi->wi_atareq.flags & ATACMD_WRITE)
1579 		wdc_c.flags |= AT_WRITE;
1580 
1581 	if (wi->wi_atareq.flags & ATACMD_READREG)
1582 		wdc_c.flags |= AT_READREG;
1583 
1584 	wdc_c.flags |= AT_WAIT;
1585 
1586 	wdc_c.timeout = wi->wi_atareq.timeout;
1587 	wdc_c.r_command = wi->wi_atareq.command;
1588 	wdc_c.r_head = wi->wi_atareq.head & 0x0f;
1589 	wdc_c.r_cyl = wi->wi_atareq.cylinder;
1590 	wdc_c.r_sector = wi->wi_atareq.sec_num;
1591 	wdc_c.r_count = wi->wi_atareq.sec_count;
1592 	wdc_c.r_precomp = wi->wi_atareq.features;
1593 	wdc_c.r_st_bmask = WDCS_DRDY;
1594 	wdc_c.r_st_pmask = WDCS_DRDY;
1595 	wdc_c.data = wi->wi_bp.b_data;
1596 	wdc_c.bcount = wi->wi_bp.b_bcount;
1597 
1598 	if (wi->wi_softc->atabus->ata_exec_command(wi->wi_softc->drvp, &wdc_c)
1599 	    != WDC_COMPLETE) {
1600 		wi->wi_atareq.retsts = ATACMD_ERROR;
1601 		goto bad;
1602 	}
1603 
1604 	if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
1605 		if (wdc_c.flags & AT_ERROR) {
1606 			wi->wi_atareq.retsts = ATACMD_ERROR;
1607 			wi->wi_atareq.error = wdc_c.r_error;
1608 		} else if (wdc_c.flags & AT_DF)
1609 			wi->wi_atareq.retsts = ATACMD_DF;
1610 		else
1611 			wi->wi_atareq.retsts = ATACMD_TIMEOUT;
1612 	} else {
1613 		wi->wi_atareq.retsts = ATACMD_OK;
1614 		if (wi->wi_atareq.flags & ATACMD_READREG) {
1615 			wi->wi_atareq.head = wdc_c.r_head ;
1616 			wi->wi_atareq.cylinder = wdc_c.r_cyl;
1617 			wi->wi_atareq.sec_num = wdc_c.r_sector;
1618 			wi->wi_atareq.sec_count = wdc_c.r_count;
1619 			wi->wi_atareq.features = wdc_c.r_precomp;
1620 			wi->wi_atareq.error = wdc_c.r_error;
1621 		}
1622 	}
1623 
1624 	bp->b_error = 0;
1625 	biodone(bp);
1626 	return;
1627 bad:
1628 	bp->b_flags |= B_ERROR;
1629 	bp->b_error = error;
1630 	biodone(bp);
1631 }
1632