xref: /netbsd-src/sys/dev/ata/wd.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
1 /*	$NetBSD: wd.c,v 1.353 2007/12/11 02:02:31 jmcneill 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, 2003, 2004 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.353 2007/12/11 02:02:31 jmcneill Exp $");
70 
71 #include "opt_ata.h"
72 
73 #include "rnd.h"
74 
75 #include <sys/param.h>
76 #include <sys/systm.h>
77 #include <sys/kernel.h>
78 #include <sys/conf.h>
79 #include <sys/file.h>
80 #include <sys/stat.h>
81 #include <sys/ioctl.h>
82 #include <sys/buf.h>
83 #include <sys/bufq.h>
84 #include <sys/uio.h>
85 #include <sys/malloc.h>
86 #include <sys/device.h>
87 #include <sys/disklabel.h>
88 #include <sys/disk.h>
89 #include <sys/syslog.h>
90 #include <sys/proc.h>
91 #include <sys/vnode.h>
92 #if NRND > 0
93 #include <sys/rnd.h>
94 #endif
95 
96 #include <sys/intr.h>
97 #include <sys/bus.h>
98 
99 #include <dev/ata/atareg.h>
100 #include <dev/ata/atavar.h>
101 #include <dev/ata/wdvar.h>
102 #include <dev/ic/wdcreg.h>
103 #include <sys/ataio.h>
104 #include "locators.h"
105 
106 #include <prop/proplib.h>
107 
108 #define	LBA48_THRESHOLD		(0xfffffff)	/* 128GB / DEV_BSIZE */
109 
110 #define	WDIORETRIES_SINGLE 4	/* number of retries before single-sector */
111 #define	WDIORETRIES	5	/* number of retries before giving up */
112 #define	RECOVERYTIME hz/2	/* time to wait before retrying a cmd */
113 
114 #define	WDUNIT(dev)		DISKUNIT(dev)
115 #define	WDPART(dev)		DISKPART(dev)
116 #define	WDMINOR(unit, part)	DISKMINOR(unit, part)
117 #define	MAKEWDDEV(maj, unit, part)	MAKEDISKDEV(maj, unit, part)
118 
119 #define	WDLABELDEV(dev)	(MAKEWDDEV(major(dev), WDUNIT(dev), RAW_PART))
120 
121 #define DEBUG_INTR   0x01
122 #define DEBUG_XFERS  0x02
123 #define DEBUG_STATUS 0x04
124 #define DEBUG_FUNCS  0x08
125 #define DEBUG_PROBE  0x10
126 #ifdef ATADEBUG
127 int wdcdebug_wd_mask = 0x0;
128 #define ATADEBUG_PRINT(args, level) \
129 	if (wdcdebug_wd_mask & (level)) \
130 		printf args
131 #else
132 #define ATADEBUG_PRINT(args, level)
133 #endif
134 
135 int	wdprobe(struct device *, struct cfdata *, void *);
136 void	wdattach(struct device *, struct device *, void *);
137 int	wddetach(struct device *, int);
138 int	wdactivate(struct device *, enum devact);
139 int	wdprint(void *, char *);
140 void	wdperror(const struct wd_softc *);
141 
142 #if notyet
143 static bool	wd_suspend(device_t);
144 static int	wd_standby(struct wd_softc *, int);
145 #endif
146 
147 CFATTACH_DECL(wd, sizeof(struct wd_softc),
148     wdprobe, wdattach, wddetach, wdactivate);
149 
150 extern struct cfdriver wd_cd;
151 
152 dev_type_open(wdopen);
153 dev_type_close(wdclose);
154 dev_type_read(wdread);
155 dev_type_write(wdwrite);
156 dev_type_ioctl(wdioctl);
157 dev_type_strategy(wdstrategy);
158 dev_type_dump(wddump);
159 dev_type_size(wdsize);
160 
161 const struct bdevsw wd_bdevsw = {
162 	wdopen, wdclose, wdstrategy, wdioctl, wddump, wdsize, D_DISK
163 };
164 
165 const struct cdevsw wd_cdevsw = {
166 	wdopen, wdclose, wdread, wdwrite, wdioctl,
167 	nostop, notty, nopoll, nommap, nokqfilter, D_DISK
168 };
169 
170 /*
171  * Glue necessary to hook WDCIOCCOMMAND into physio
172  */
173 
174 struct wd_ioctl {
175 	LIST_ENTRY(wd_ioctl) wi_list;
176 	struct buf wi_bp;
177 	struct uio wi_uio;
178 	struct iovec wi_iov;
179 	atareq_t wi_atareq;
180 	struct wd_softc *wi_softc;
181 };
182 
183 LIST_HEAD(, wd_ioctl) wi_head;
184 
185 struct	wd_ioctl *wi_find(struct buf *);
186 void	wi_free(struct wd_ioctl *);
187 struct	wd_ioctl *wi_get(void);
188 void	wdioctlstrategy(struct buf *);
189 
190 void  wdgetdefaultlabel(struct wd_softc *, struct disklabel *);
191 void  wdgetdisklabel(struct wd_softc *);
192 void  wdstart(void *);
193 void  __wdstart(struct wd_softc*, struct buf *);
194 void  wdrestart(void *);
195 void  wddone(void *);
196 int   wd_get_params(struct wd_softc *, u_int8_t, struct ataparams *);
197 int   wd_flushcache(struct wd_softc *, int);
198 
199 int   wd_getcache(struct wd_softc *, int *);
200 int   wd_setcache(struct wd_softc *, int);
201 
202 struct dkdriver wddkdriver = { wdstrategy, minphys };
203 
204 #ifdef HAS_BAD144_HANDLING
205 static void bad144intern(struct wd_softc *);
206 #endif
207 
208 #define	WD_QUIRK_SPLIT_MOD15_WRITE	0x0001	/* must split certain writes */
209 #define	WD_QUIRK_FORCE_LBA48		0x0002	/* must use LBA48 commands */
210 
211 #define	WD_QUIRK_FMT "\20\1SPLIT_MOD15_WRITE\2FORCE_LBA48"
212 
213 /*
214  * Quirk table for IDE drives.  Put more-specific matches first, since
215  * a simple globbing routine is used for matching.
216  */
217 static const struct wd_quirk {
218 	const char *wdq_match;		/* inquiry pattern to match */
219 	int wdq_quirks;			/* drive quirks */
220 } wd_quirk_table[] = {
221 	/*
222 	 * Some Seagate S-ATA drives have a PHY which can get confused
223 	 * with the way data is packetized by some S-ATA controllers.
224 	 *
225 	 * The work-around is to split in two any write transfer whose
226 	 * sector count % 15 == 1 (assuming 512 byte sectors).
227 	 *
228 	 * XXX This is an incomplete list.  There are at least a couple
229 	 * XXX more model numbers.  If you have trouble with such transfers
230 	 * XXX (8K is the most common) on Seagate S-ATA drives, please
231 	 * XXX notify thorpej@NetBSD.org.
232 	 */
233 	{ "ST3120023AS",
234 	  WD_QUIRK_SPLIT_MOD15_WRITE },
235 	{ "ST380023AS",
236 	  WD_QUIRK_SPLIT_MOD15_WRITE },
237 
238 	/*
239 	 * These seagate drives seems to have issue addressing sector 0xfffffff
240 	 * (aka LBA48_THRESHOLD) in LBA mode. The workaround is to force
241 	 * LBA48
242 	 * Note that we can't just change the code to always use LBA48 for
243 	 * sector 0xfffffff, because this would break valid and working
244 	 * setups using LBA48 drives on non-LBA48-capable controllers
245 	 * (and it's hard to get a list of such controllers)
246 	 */
247 	{ "ST3160021A*",
248 	  WD_QUIRK_FORCE_LBA48 },
249 	{ "ST3160811A*",
250 	  WD_QUIRK_FORCE_LBA48 },
251 	{ "ST3160812A*",
252 	  WD_QUIRK_FORCE_LBA48 },
253 	{ "ST3160023A*",
254 	  WD_QUIRK_FORCE_LBA48 },
255 	{ "ST3160827A*",
256 	  WD_QUIRK_FORCE_LBA48 },
257 	/* Attempt to catch all seagate drives larger than 200GB */
258 	{ "ST3[2-9][0-9][0-9][0-9][0-9][0-9][A-Z]*",
259 	  WD_QUIRK_FORCE_LBA48 },
260 	{ "ST3[1-9][0-9][0-9][0-9][0-9][0-9][0-9][A-Z]*",
261 	  WD_QUIRK_FORCE_LBA48 },
262 	{ NULL,
263 	  0 }
264 };
265 
266 static const struct wd_quirk *
267 wd_lookup_quirks(const char *name)
268 {
269 	const struct wd_quirk *wdq;
270 	const char *estr;
271 
272 	for (wdq = wd_quirk_table; wdq->wdq_match != NULL; wdq++) {
273 		/*
274 		 * We only want exact matches (which include matches
275 		 * against globbing characters).
276 		 */
277 		if (pmatch(name, wdq->wdq_match, &estr) == 2)
278 			return (wdq);
279 	}
280 	return (NULL);
281 }
282 
283 int
284 wdprobe(struct device *parent, struct cfdata *match, void *aux)
285 {
286 	struct ata_device *adev = aux;
287 
288 	if (adev == NULL)
289 		return 0;
290 	if (adev->adev_bustype->bustype_type != SCSIPI_BUSTYPE_ATA)
291 		return 0;
292 
293 	if (match->cf_loc[ATA_HLCF_DRIVE] != ATA_HLCF_DRIVE_DEFAULT &&
294 	    match->cf_loc[ATA_HLCF_DRIVE] != adev->adev_drv_data->drive)
295 		return 0;
296 	return 1;
297 }
298 
299 void
300 wdattach(struct device *parent, struct device *self, void *aux)
301 {
302 	struct wd_softc *wd = (void *)self;
303 	struct ata_device *adev= aux;
304 	int i, blank;
305 	char tbuf[41], pbuf[9], c, *p, *q;
306 	const struct wd_quirk *wdq;
307 
308 	ATADEBUG_PRINT(("wdattach\n"), DEBUG_FUNCS | DEBUG_PROBE);
309 	callout_init(&wd->sc_restart_ch, 0);
310 	bufq_alloc(&wd->sc_q, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK);
311 #ifdef WD_SOFTBADSECT
312 	SLIST_INIT(&wd->sc_bslist);
313 #endif
314 	wd->atabus = adev->adev_bustype;
315 	wd->openings = adev->adev_openings;
316 	wd->drvp = adev->adev_drv_data;
317 
318 	wd->drvp->drv_done = wddone;
319 	wd->drvp->drv_softc = &wd->sc_dev;
320 
321 	aprint_naive("\n");
322 
323 	/* read our drive info */
324 	if (wd_get_params(wd, AT_WAIT, &wd->sc_params) != 0) {
325 		aprint_error("\n%s: IDENTIFY failed\n", wd->sc_dev.dv_xname);
326 		return;
327 	}
328 
329 	for (blank = 0, p = wd->sc_params.atap_model, q = tbuf, i = 0;
330 	    i < sizeof(wd->sc_params.atap_model); i++) {
331 		c = *p++;
332 		if (c == '\0')
333 			break;
334 		if (c != ' ') {
335 			if (blank) {
336 				*q++ = ' ';
337 				blank = 0;
338 			}
339 			*q++ = c;
340 		} else
341 			blank = 1;
342 	}
343 	*q++ = '\0';
344 
345 	aprint_normal(": <%s>\n", tbuf);
346 
347 	wdq = wd_lookup_quirks(tbuf);
348 	if (wdq != NULL)
349 		wd->sc_quirks = wdq->wdq_quirks;
350 
351 	if (wd->sc_quirks != 0) {
352 		char sbuf[sizeof(WD_QUIRK_FMT) + 64];
353 		bitmask_snprintf(wd->sc_quirks, WD_QUIRK_FMT,
354 		    sbuf, sizeof(sbuf));
355 		aprint_normal("%s: quirks %s\n", wd->sc_dev.dv_xname, sbuf);
356 	}
357 
358 	if ((wd->sc_params.atap_multi & 0xff) > 1) {
359 		wd->sc_multi = wd->sc_params.atap_multi & 0xff;
360 	} else {
361 		wd->sc_multi = 1;
362 	}
363 
364 	aprint_verbose("%s: drive supports %d-sector PIO transfers,",
365 	    wd->sc_dev.dv_xname, wd->sc_multi);
366 
367 	/* 48-bit LBA addressing */
368 	if ((wd->sc_params.atap_cmd2_en & ATA_CMD2_LBA48) != 0)
369 		wd->sc_flags |= WDF_LBA48;
370 
371 	/* Prior to ATA-4, LBA was optional. */
372 	if ((wd->sc_params.atap_capabilities1 & WDC_CAP_LBA) != 0)
373 		wd->sc_flags |= WDF_LBA;
374 #if 0
375 	/* ATA-4 requires LBA. */
376 	if (wd->sc_params.atap_ataversion != 0xffff &&
377 	    wd->sc_params.atap_ataversion >= WDC_VER_ATA4)
378 		wd->sc_flags |= WDF_LBA;
379 #endif
380 
381 	if ((wd->sc_flags & WDF_LBA48) != 0) {
382 		aprint_verbose(" LBA48 addressing\n");
383 		wd->sc_capacity =
384 		    ((u_int64_t) wd->sc_params.__reserved6[11] << 48) |
385 		    ((u_int64_t) wd->sc_params.__reserved6[10] << 32) |
386 		    ((u_int64_t) wd->sc_params.__reserved6[9]  << 16) |
387 		    ((u_int64_t) wd->sc_params.__reserved6[8]  << 0);
388 	} else if ((wd->sc_flags & WDF_LBA) != 0) {
389 		aprint_verbose(" LBA addressing\n");
390 		wd->sc_capacity =
391 		    ((u_int64_t)wd->sc_params.atap_capacity[1] << 16) |
392 		    wd->sc_params.atap_capacity[0];
393 	} else {
394 		aprint_verbose(" chs addressing\n");
395 		wd->sc_capacity =
396 		    wd->sc_params.atap_cylinders *
397 		    wd->sc_params.atap_heads *
398 		    wd->sc_params.atap_sectors;
399 	}
400 	format_bytes(pbuf, sizeof(pbuf), wd->sc_capacity * DEV_BSIZE);
401 	aprint_normal("%s: %s, %d cyl, %d head, %d sec, "
402 	    "%d bytes/sect x %llu sectors\n",
403 	    self->dv_xname, pbuf,
404 	    (wd->sc_flags & WDF_LBA) ? (int)(wd->sc_capacity /
405 		(wd->sc_params.atap_heads * wd->sc_params.atap_sectors)) :
406 		wd->sc_params.atap_cylinders,
407 	    wd->sc_params.atap_heads, wd->sc_params.atap_sectors,
408 	    DEV_BSIZE, (unsigned long long)wd->sc_capacity);
409 
410 	ATADEBUG_PRINT(("%s: atap_dmatiming_mimi=%d, atap_dmatiming_recom=%d\n",
411 	    self->dv_xname, wd->sc_params.atap_dmatiming_mimi,
412 	    wd->sc_params.atap_dmatiming_recom), DEBUG_PROBE);
413 	/*
414 	 * Initialize and attach the disk structure.
415 	 */
416 	/* we fill in dk_info later */
417 	disk_init(&wd->sc_dk, wd->sc_dev.dv_xname, &wddkdriver);
418 	disk_attach(&wd->sc_dk);
419 	wd->sc_wdc_bio.lp = wd->sc_dk.dk_label;
420 #if NRND > 0
421 	rnd_attach_source(&wd->rnd_source, wd->sc_dev.dv_xname,
422 			  RND_TYPE_DISK, 0);
423 #endif
424 
425 	/* Discover wedges on this disk. */
426 	dkwedge_discover(&wd->sc_dk);
427 
428 	if (!pmf_device_register(self, NULL, NULL))
429 		aprint_error_dev(self, "couldn't establish power handler\n");
430 }
431 
432 #if notyet
433 static bool
434 wd_suspend(device_t dv)
435 {
436 	struct wd_softc *sc = device_private(dv);
437 
438 	wd_flushcache(sc, AT_WAIT | AT_POLL);
439 	wd_standby(sc, AT_WAIT | AT_POLL);
440 
441 	return true;
442 }
443 #endif
444 
445 int
446 wdactivate(struct device *self, enum devact act)
447 {
448 	int rv = 0;
449 
450 	switch (act) {
451 	case DVACT_ACTIVATE:
452 		rv = EOPNOTSUPP;
453 		break;
454 
455 	case DVACT_DEACTIVATE:
456 		/*
457 		 * Nothing to do; we key off the device's DVF_ACTIVATE.
458 		 */
459 		break;
460 	}
461 	return (rv);
462 }
463 
464 int
465 wddetach(struct device *self, int flags)
466 {
467 	struct wd_softc *sc = (struct wd_softc *)self;
468 	int s, bmaj, cmaj, i, mn;
469 
470 	/* locate the major number */
471 	bmaj = bdevsw_lookup_major(&wd_bdevsw);
472 	cmaj = cdevsw_lookup_major(&wd_cdevsw);
473 
474 	/* Nuke the vnodes for any open instances. */
475 	for (i = 0; i < MAXPARTITIONS; i++) {
476 		mn = WDMINOR(device_unit(self), i);
477 		vdevgone(bmaj, mn, mn, VBLK);
478 		vdevgone(cmaj, mn, mn, VCHR);
479 	}
480 
481 	/* Delete all of our wedges. */
482 	dkwedge_delall(&sc->sc_dk);
483 
484 	s = splbio();
485 
486 	/* Kill off any queued buffers. */
487 	bufq_drain(sc->sc_q);
488 
489 	bufq_free(sc->sc_q);
490 	sc->atabus->ata_killpending(sc->drvp);
491 
492 	splx(s);
493 
494 	/* Detach disk. */
495 	disk_detach(&sc->sc_dk);
496 
497 #ifdef WD_SOFTBADSECT
498 	/* Clean out the bad sector list */
499 	while (!SLIST_EMPTY(&sc->sc_bslist)) {
500 		void *head = SLIST_FIRST(&sc->sc_bslist);
501 		SLIST_REMOVE_HEAD(&sc->sc_bslist, dbs_next);
502 		free(head, M_TEMP);
503 	}
504 	sc->sc_bscount = 0;
505 #endif
506 
507 	pmf_device_deregister(self);
508 
509 #if NRND > 0
510 	/* Unhook the entropy source. */
511 	rnd_detach_source(&sc->rnd_source);
512 #endif
513 
514 	sc->drvp->drive_flags = 0; /* no drive any more here */
515 
516 	return (0);
517 }
518 
519 /*
520  * Read/write routine for a buffer.  Validates the arguments and schedules the
521  * transfer.  Does not wait for the transfer to complete.
522  */
523 void
524 wdstrategy(struct buf *bp)
525 {
526 	struct wd_softc *wd = device_lookup(&wd_cd, WDUNIT(bp->b_dev));
527 	struct disklabel *lp = wd->sc_dk.dk_label;
528 	daddr_t blkno;
529 	int s;
530 
531 	ATADEBUG_PRINT(("wdstrategy (%s)\n", wd->sc_dev.dv_xname),
532 	    DEBUG_XFERS);
533 
534 	/* Valid request?  */
535 	if (bp->b_blkno < 0 ||
536 	    (bp->b_bcount % lp->d_secsize) != 0 ||
537 	    (bp->b_bcount / lp->d_secsize) >= (1 << NBBY)) {
538 		bp->b_error = EINVAL;
539 		goto done;
540 	}
541 
542 	/* If device invalidated (e.g. media change, door open), error. */
543 	if ((wd->sc_flags & WDF_LOADED) == 0) {
544 		bp->b_error = EIO;
545 		goto done;
546 	}
547 
548 	/* If it's a null transfer, return immediately. */
549 	if (bp->b_bcount == 0)
550 		goto done;
551 
552 	/*
553 	 * Do bounds checking, adjust transfer. if error, process.
554 	 * If end of partition, just return.
555 	 */
556 	if (WDPART(bp->b_dev) == RAW_PART) {
557 		if (bounds_check_with_mediasize(bp, DEV_BSIZE,
558 		    wd->sc_capacity) <= 0)
559 			goto done;
560 	} else {
561 		if (bounds_check_with_label(&wd->sc_dk, bp,
562 		    (wd->sc_flags & (WDF_WLABEL|WDF_LABELLING)) != 0) <= 0)
563 			goto done;
564 	}
565 
566 	/*
567 	 * Now convert the block number to absolute and put it in
568 	 * terms of the device's logical block size.
569 	 */
570 	if (lp->d_secsize >= DEV_BSIZE)
571 		blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE);
572 	else
573 		blkno = bp->b_blkno * (DEV_BSIZE / lp->d_secsize);
574 
575 	if (WDPART(bp->b_dev) != RAW_PART)
576 		blkno += lp->d_partitions[WDPART(bp->b_dev)].p_offset;
577 
578 	bp->b_rawblkno = blkno;
579 
580 #ifdef WD_SOFTBADSECT
581 	/*
582 	 * If the transfer about to be attempted contains only a block that
583 	 * is known to be bad then return an error for the transfer without
584 	 * even attempting to start a transfer up under the premis that we
585 	 * will just end up doing more retries for a transfer that will end
586 	 * up failing again.
587 	 * XXX:SMP - mutex required to protect with DIOCBSFLUSH
588 	 */
589 	if (__predict_false(!SLIST_EMPTY(&wd->sc_bslist))) {
590 		struct disk_badsectors *dbs;
591 		daddr_t maxblk = blkno + (bp->b_bcount >> DEV_BSHIFT) - 1;
592 
593 		SLIST_FOREACH(dbs, &wd->sc_bslist, dbs_next)
594 			if ((dbs->dbs_min <= blkno && blkno <= dbs->dbs_max) ||
595 			    (dbs->dbs_min <= maxblk && maxblk <= dbs->dbs_max)){
596 				bp->b_error = EIO;
597 				goto done;
598 			}
599 	}
600 #endif
601 
602 	/* Queue transfer on drive, activate drive and controller if idle. */
603 	s = splbio();
604 	BUFQ_PUT(wd->sc_q, bp);
605 	wdstart(wd);
606 	splx(s);
607 	return;
608 done:
609 	/* Toss transfer; we're done early. */
610 	bp->b_resid = bp->b_bcount;
611 	biodone(bp);
612 }
613 
614 /*
615  * Queue a drive for I/O.
616  */
617 void
618 wdstart(void *arg)
619 {
620 	struct wd_softc *wd = arg;
621 	struct buf *bp = NULL;
622 
623 	ATADEBUG_PRINT(("wdstart %s\n", wd->sc_dev.dv_xname),
624 	    DEBUG_XFERS);
625 	while (wd->openings > 0) {
626 
627 		/* Is there a buf for us ? */
628 		if ((bp = BUFQ_GET(wd->sc_q)) == NULL)
629 			return;
630 
631 		/*
632 		 * Make the command. First lock the device
633 		 */
634 		wd->openings--;
635 
636 		wd->retries = 0;
637 		__wdstart(wd, bp);
638 	}
639 }
640 
641 static void
642 wd_split_mod15_write(struct buf *bp)
643 {
644 	struct buf *obp = bp->b_private;
645 	struct wd_softc *sc = wd_cd.cd_devs[DISKUNIT(obp->b_dev)];
646 
647 	if (__predict_false(bp->b_error != 0)) {
648 		/*
649 		 * Propagate the error.  If this was the first half of
650 		 * the original transfer, make sure to account for that
651 		 * in the residual.
652 		 */
653 		if (bp->b_data == obp->b_data)
654 			bp->b_resid += bp->b_bcount;
655 		goto done;
656 	}
657 
658 	/*
659 	 * If this was the second half of the transfer, we're all done!
660 	 */
661 	if (bp->b_data != obp->b_data)
662 		goto done;
663 
664 	/*
665 	 * Advance the pointer to the second half and issue that command
666 	 * using the same opening.
667 	 */
668 	bp->b_flags = obp->b_flags | B_CALL;
669 	bp->b_data = (char *)bp->b_data + bp->b_bcount;
670 	bp->b_blkno += (bp->b_bcount / 512);
671 	bp->b_rawblkno += (bp->b_bcount / 512);
672 	__wdstart(sc, bp);
673 	return;
674 
675  done:
676 	obp->b_error = bp->b_error;
677 	obp->b_resid = bp->b_resid;
678 	putiobuf(bp);
679 	biodone(obp);
680 	sc->openings++;
681 	/* wddone() will call wdstart() */
682 }
683 
684 void
685 __wdstart(struct wd_softc *wd, struct buf *bp)
686 {
687 
688 	/*
689 	 * Deal with the "split mod15 write" quirk.  We just divide the
690 	 * transfer in two, doing the first half and then then second half
691 	 * with the same command opening.
692 	 *
693 	 * Note we MUST do this here, because we can't let insertion
694 	 * into the bufq cause the transfers to be re-merged.
695 	 */
696 	if (__predict_false((wd->sc_quirks & WD_QUIRK_SPLIT_MOD15_WRITE) != 0 &&
697 			    (bp->b_flags & B_READ) == 0 &&
698 			    bp->b_bcount > 512 &&
699 			    ((bp->b_bcount / 512) % 15) == 1)) {
700 		struct buf *nbp;
701 
702 		/* already at splbio */
703 		nbp = getiobuf_nowait();
704 		if (__predict_false(nbp == NULL)) {
705 			/* No memory -- fail the iop. */
706 			bp->b_error = ENOMEM;
707 			bp->b_resid = bp->b_bcount;
708 			biodone(bp);
709 			wd->openings++;
710 			return;
711 		}
712 
713 		nbp->b_error = 0;
714 		nbp->b_proc = bp->b_proc;
715 		nbp->b_vp = NULLVP;
716 		nbp->b_dev = bp->b_dev;
717 
718 		nbp->b_bcount = bp->b_bcount / 2;
719 		nbp->b_bufsize = bp->b_bcount / 2;
720 		nbp->b_data = bp->b_data;
721 
722 		nbp->b_blkno = bp->b_blkno;
723 		nbp->b_rawblkno = bp->b_rawblkno;
724 
725 		nbp->b_flags = bp->b_flags | B_CALL;
726 		nbp->b_iodone = wd_split_mod15_write;
727 
728 		/* Put ptr to orig buf in b_private and use new buf */
729 		nbp->b_private = bp;
730 
731 		BIO_COPYPRIO(nbp, bp);
732 
733 		bp = nbp;
734 	}
735 
736 	wd->sc_wdc_bio.blkno = bp->b_rawblkno;
737 	wd->sc_wdc_bio.blkdone =0;
738 	wd->sc_bp = bp;
739 	/*
740 	 * If we're retrying, retry in single-sector mode. This will give us
741 	 * the sector number of the problem, and will eventually allow the
742 	 * transfer to succeed.
743 	 */
744 	if (wd->retries >= WDIORETRIES_SINGLE)
745 		wd->sc_wdc_bio.flags = ATA_SINGLE;
746 	else
747 		wd->sc_wdc_bio.flags = 0;
748 	if (wd->sc_flags & WDF_LBA48 &&
749 	    (wd->sc_wdc_bio.blkno > LBA48_THRESHOLD ||
750 	    (wd->sc_quirks & WD_QUIRK_FORCE_LBA48) != 0))
751 		wd->sc_wdc_bio.flags |= ATA_LBA48;
752 	if (wd->sc_flags & WDF_LBA)
753 		wd->sc_wdc_bio.flags |= ATA_LBA;
754 	if (bp->b_flags & B_READ)
755 		wd->sc_wdc_bio.flags |= ATA_READ;
756 	wd->sc_wdc_bio.bcount = bp->b_bcount;
757 	wd->sc_wdc_bio.databuf = bp->b_data;
758 	/* Instrumentation. */
759 	disk_busy(&wd->sc_dk);
760 	switch (wd->atabus->ata_bio(wd->drvp, &wd->sc_wdc_bio)) {
761 	case ATACMD_TRY_AGAIN:
762 		callout_reset(&wd->sc_restart_ch, hz, wdrestart, wd);
763 		break;
764 	case ATACMD_QUEUED:
765 	case ATACMD_COMPLETE:
766 		break;
767 	default:
768 		panic("__wdstart: bad return code from ata_bio()");
769 	}
770 }
771 
772 void
773 wddone(void *v)
774 {
775 	struct wd_softc *wd = v;
776 	struct buf *bp = wd->sc_bp;
777 	const char *errmsg;
778 	int do_perror = 0;
779 	int nblks;
780 
781 	ATADEBUG_PRINT(("wddone %s\n", wd->sc_dev.dv_xname),
782 	    DEBUG_XFERS);
783 	if (bp == NULL)
784 		return;
785 	bp->b_resid = wd->sc_wdc_bio.bcount;
786 	switch (wd->sc_wdc_bio.error) {
787 	case ERR_DMA:
788 		errmsg = "DMA error";
789 		goto retry;
790 	case ERR_DF:
791 		errmsg = "device fault";
792 		goto retry;
793 	case TIMEOUT:
794 		errmsg = "device timeout";
795 		goto retry;
796 	case ERR_RESET:
797 		errmsg = "channel reset";
798 		goto retry2;
799 	case ERROR:
800 		/* Don't care about media change bits */
801 		if (wd->sc_wdc_bio.r_error != 0 &&
802 		    (wd->sc_wdc_bio.r_error & ~(WDCE_MC | WDCE_MCR)) == 0)
803 			goto noerror;
804 		errmsg = "error";
805 		do_perror = 1;
806 		if (wd->sc_wdc_bio.r_error & WDCE_IDNF &&
807 		    (wd->sc_quirks & WD_QUIRK_FORCE_LBA48) == 0) {
808 			nblks = wd->sc_wdc_bio.bcount /
809 			    wd->sc_dk.dk_label->d_secsize;
810 			/*
811 			 * If we get a "id not found" when crossing the
812 			 * LBA48_THRESHOLD, and the drive is larger than
813 			 * 128GB, then we can assume the drive has the
814 			 * LBA48 bug and we switch to LBA48.
815 			 */
816 			if (wd->sc_wdc_bio.blkno <= LBA48_THRESHOLD &&
817 			    wd->sc_wdc_bio.blkno + nblks > LBA48_THRESHOLD &&
818 			    wd->sc_capacity > LBA48_THRESHOLD + 1) {
819 				errmsg = "LBA48 bug";
820 				wd->sc_quirks |= WD_QUIRK_FORCE_LBA48;
821 				do_perror = 0;
822 				goto retry2;
823 			}
824 		}
825 retry:		/* Just reset and retry. Can we do more ? */
826 		(*wd->atabus->ata_reset_drive)(wd->drvp, AT_RST_NOCMD);
827 retry2:
828 		diskerr(bp, "wd", errmsg, LOG_PRINTF,
829 		    wd->sc_wdc_bio.blkdone, wd->sc_dk.dk_label);
830 		if (wd->retries < WDIORETRIES)
831 			printf(", retrying");
832 		printf("\n");
833 		if (do_perror)
834 			wdperror(wd);
835 		if (wd->retries < WDIORETRIES) {
836 			wd->retries++;
837 			callout_reset(&wd->sc_restart_ch, RECOVERYTIME,
838 			    wdrestart, wd);
839 			return;
840 		}
841 
842 #ifdef WD_SOFTBADSECT
843 		/*
844 		 * Not all errors indicate a failed block but those that do,
845 		 * put the block on the bad-block list for the device.  Only
846 		 * do this for reads because the drive should do it for writes,
847 		 * itself, according to Manuel.
848 		 */
849 		if ((bp->b_flags & B_READ) &&
850 		    ((wd->drvp->ata_vers >= 4 && wd->sc_wdc_bio.r_error & 64) ||
851 	     	     (wd->drvp->ata_vers < 4 && wd->sc_wdc_bio.r_error & 192))) {
852 			struct disk_badsectors *dbs;
853 
854 			dbs = malloc(sizeof *dbs, M_TEMP, M_WAITOK);
855 			dbs->dbs_min = bp->b_rawblkno;
856 			dbs->dbs_max = dbs->dbs_min + (bp->b_bcount >> DEV_BSHIFT) - 1;
857 			microtime(&dbs->dbs_failedat);
858 			SLIST_INSERT_HEAD(&wd->sc_bslist, dbs, dbs_next);
859 			wd->sc_bscount++;
860 		}
861 #endif
862 		bp->b_error = EIO;
863 		break;
864 	case NOERROR:
865 noerror:	if ((wd->sc_wdc_bio.flags & ATA_CORR) || wd->retries > 0)
866 			printf("%s: soft error (corrected)\n",
867 			    wd->sc_dev.dv_xname);
868 		break;
869 	case ERR_NODEV:
870 		bp->b_error = EIO;
871 		break;
872 	}
873 	disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid),
874 	    (bp->b_flags & B_READ));
875 #if NRND > 0
876 	rnd_add_uint32(&wd->rnd_source, bp->b_blkno);
877 #endif
878 	/* XXX Yuck, but we don't want to increment openings in this case */
879 	if (__predict_false((bp->b_flags & B_CALL) != 0 &&
880 			    bp->b_iodone == wd_split_mod15_write))
881 		biodone(bp);
882 	else {
883 		biodone(bp);
884 		wd->openings++;
885 	}
886 	wdstart(wd);
887 }
888 
889 void
890 wdrestart(void *v)
891 {
892 	struct wd_softc *wd = v;
893 	struct buf *bp = wd->sc_bp;
894 	int s;
895 
896 	ATADEBUG_PRINT(("wdrestart %s\n", wd->sc_dev.dv_xname),
897 	    DEBUG_XFERS);
898 	s = splbio();
899 	__wdstart(v, bp);
900 	splx(s);
901 }
902 
903 int
904 wdread(dev_t dev, struct uio *uio, int flags)
905 {
906 
907 	ATADEBUG_PRINT(("wdread\n"), DEBUG_XFERS);
908 	return (physio(wdstrategy, NULL, dev, B_READ, minphys, uio));
909 }
910 
911 int
912 wdwrite(dev_t dev, struct uio *uio, int flags)
913 {
914 
915 	ATADEBUG_PRINT(("wdwrite\n"), DEBUG_XFERS);
916 	return (physio(wdstrategy, NULL, dev, B_WRITE, minphys, uio));
917 }
918 
919 int
920 wdopen(dev_t dev, int flag, int fmt, struct lwp *l)
921 {
922 	struct wd_softc *wd;
923 	int part, error;
924 
925 	ATADEBUG_PRINT(("wdopen\n"), DEBUG_FUNCS);
926 	wd = device_lookup(&wd_cd, WDUNIT(dev));
927 	if (wd == NULL)
928 		return (ENXIO);
929 
930 	if (! device_is_active(&wd->sc_dev))
931 		return (ENODEV);
932 
933 	part = WDPART(dev);
934 
935 	mutex_enter(&wd->sc_dk.dk_openlock);
936 
937 	/*
938 	 * If there are wedges, and this is not RAW_PART, then we
939 	 * need to fail.
940 	 */
941 	if (wd->sc_dk.dk_nwedges != 0 && part != RAW_PART) {
942 		error = EBUSY;
943 		goto bad1;
944 	}
945 
946 	/*
947 	 * If this is the first open of this device, add a reference
948 	 * to the adapter.
949 	 */
950 	if (wd->sc_dk.dk_openmask == 0 &&
951 	    (error = wd->atabus->ata_addref(wd->drvp)) != 0)
952 		goto bad1;
953 
954 	if (wd->sc_dk.dk_openmask != 0) {
955 		/*
956 		 * If any partition is open, but the disk has been invalidated,
957 		 * disallow further opens.
958 		 */
959 		if ((wd->sc_flags & WDF_LOADED) == 0) {
960 			error = EIO;
961 			goto bad2;
962 		}
963 	} else {
964 		if ((wd->sc_flags & WDF_LOADED) == 0) {
965 			wd->sc_flags |= WDF_LOADED;
966 
967 			/* Load the physical device parameters. */
968 			wd_get_params(wd, AT_WAIT, &wd->sc_params);
969 
970 			/* Load the partition info if not already loaded. */
971 			wdgetdisklabel(wd);
972 		}
973 	}
974 
975 	/* Check that the partition exists. */
976 	if (part != RAW_PART &&
977 	    (part >= wd->sc_dk.dk_label->d_npartitions ||
978 	     wd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
979 		error = ENXIO;
980 		goto bad2;
981 	}
982 
983 	/* Insure only one open at a time. */
984 	switch (fmt) {
985 	case S_IFCHR:
986 		wd->sc_dk.dk_copenmask |= (1 << part);
987 		break;
988 	case S_IFBLK:
989 		wd->sc_dk.dk_bopenmask |= (1 << part);
990 		break;
991 	}
992 	wd->sc_dk.dk_openmask =
993 	    wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
994 
995 	mutex_exit(&wd->sc_dk.dk_openlock);
996 	return 0;
997 
998  bad2:
999 	if (wd->sc_dk.dk_openmask == 0)
1000 		wd->atabus->ata_delref(wd->drvp);
1001  bad1:
1002 	mutex_exit(&wd->sc_dk.dk_openlock);
1003 	return error;
1004 }
1005 
1006 int
1007 wdclose(dev_t dev, int flag, int fmt, struct lwp *l)
1008 {
1009 	struct wd_softc *wd = device_lookup(&wd_cd, WDUNIT(dev));
1010 	int part = WDPART(dev);
1011 
1012 	ATADEBUG_PRINT(("wdclose\n"), DEBUG_FUNCS);
1013 
1014 	mutex_enter(&wd->sc_dk.dk_openlock);
1015 
1016 	switch (fmt) {
1017 	case S_IFCHR:
1018 		wd->sc_dk.dk_copenmask &= ~(1 << part);
1019 		break;
1020 	case S_IFBLK:
1021 		wd->sc_dk.dk_bopenmask &= ~(1 << part);
1022 		break;
1023 	}
1024 	wd->sc_dk.dk_openmask =
1025 	    wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
1026 
1027 	if (wd->sc_dk.dk_openmask == 0) {
1028 		wd_flushcache(wd, AT_WAIT);
1029 
1030 		if (! (wd->sc_flags & WDF_KLABEL))
1031 			wd->sc_flags &= ~WDF_LOADED;
1032 
1033 		wd->atabus->ata_delref(wd->drvp);
1034 	}
1035 
1036 	mutex_exit(&wd->sc_dk.dk_openlock);
1037 	return 0;
1038 }
1039 
1040 void
1041 wdgetdefaultlabel(struct wd_softc *wd, struct disklabel *lp)
1042 {
1043 
1044 	ATADEBUG_PRINT(("wdgetdefaultlabel\n"), DEBUG_FUNCS);
1045 	memset(lp, 0, sizeof(struct disklabel));
1046 
1047 	lp->d_secsize = DEV_BSIZE;
1048 	lp->d_ntracks = wd->sc_params.atap_heads;
1049 	lp->d_nsectors = wd->sc_params.atap_sectors;
1050 	lp->d_ncylinders = (wd->sc_flags & WDF_LBA) ? wd->sc_capacity /
1051 		(wd->sc_params.atap_heads * wd->sc_params.atap_sectors) :
1052 		wd->sc_params.atap_cylinders;
1053 	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
1054 
1055 	if (strcmp(wd->sc_params.atap_model, "ST506") == 0)
1056 		lp->d_type = DTYPE_ST506;
1057 	else
1058 		lp->d_type = DTYPE_ESDI;
1059 
1060 	strncpy(lp->d_typename, wd->sc_params.atap_model, 16);
1061 	strncpy(lp->d_packname, "fictitious", 16);
1062 	if (wd->sc_capacity > UINT32_MAX)
1063 		lp->d_secperunit = UINT32_MAX;
1064 	else
1065 		lp->d_secperunit = wd->sc_capacity;
1066 	lp->d_rpm = 3600;
1067 	lp->d_interleave = 1;
1068 	lp->d_flags = 0;
1069 
1070 	lp->d_partitions[RAW_PART].p_offset = 0;
1071 	lp->d_partitions[RAW_PART].p_size =
1072 	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
1073 	lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
1074 	lp->d_npartitions = RAW_PART + 1;
1075 
1076 	lp->d_magic = DISKMAGIC;
1077 	lp->d_magic2 = DISKMAGIC;
1078 	lp->d_checksum = dkcksum(lp);
1079 }
1080 
1081 /*
1082  * Fabricate a default disk label, and try to read the correct one.
1083  */
1084 void
1085 wdgetdisklabel(struct wd_softc *wd)
1086 {
1087 	struct disklabel *lp = wd->sc_dk.dk_label;
1088 	const char *errstring;
1089 	int s;
1090 
1091 	ATADEBUG_PRINT(("wdgetdisklabel\n"), DEBUG_FUNCS);
1092 
1093 	memset(wd->sc_dk.dk_cpulabel, 0, sizeof(struct cpu_disklabel));
1094 
1095 	wdgetdefaultlabel(wd, lp);
1096 
1097 	wd->sc_badsect[0] = -1;
1098 
1099 	if (wd->drvp->state > RESET) {
1100 		s = splbio();
1101 		wd->drvp->drive_flags |= DRIVE_RESET;
1102 		splx(s);
1103 	}
1104 	errstring = readdisklabel(MAKEWDDEV(0, device_unit(&wd->sc_dev),
1105 				  RAW_PART), wdstrategy, lp,
1106 				  wd->sc_dk.dk_cpulabel);
1107 	if (errstring) {
1108 		/*
1109 		 * This probably happened because the drive's default
1110 		 * geometry doesn't match the DOS geometry.  We
1111 		 * assume the DOS geometry is now in the label and try
1112 		 * again.  XXX This is a kluge.
1113 		 */
1114 		if (wd->drvp->state > RESET) {
1115 			s = splbio();
1116 			wd->drvp->drive_flags |= DRIVE_RESET;
1117 			splx(s);
1118 		}
1119 		errstring = readdisklabel(MAKEWDDEV(0, device_unit(&wd->sc_dev),
1120 		    RAW_PART), wdstrategy, lp, wd->sc_dk.dk_cpulabel);
1121 	}
1122 	if (errstring) {
1123 		printf("%s: %s\n", wd->sc_dev.dv_xname, errstring);
1124 		return;
1125 	}
1126 
1127 	if (wd->drvp->state > RESET) {
1128 		s = splbio();
1129 		wd->drvp->drive_flags |= DRIVE_RESET;
1130 		splx(s);
1131 	}
1132 #ifdef HAS_BAD144_HANDLING
1133 	if ((lp->d_flags & D_BADSECT) != 0)
1134 		bad144intern(wd);
1135 #endif
1136 }
1137 
1138 void
1139 wdperror(const struct wd_softc *wd)
1140 {
1141 	static const char *const errstr0_3[] = {"address mark not found",
1142 	    "track 0 not found", "aborted command", "media change requested",
1143 	    "id not found", "media changed", "uncorrectable data error",
1144 	    "bad block detected"};
1145 	static const char *const errstr4_5[] = {
1146 	    "obsolete (address mark not found)",
1147 	    "no media/write protected", "aborted command",
1148 	    "media change requested", "id not found", "media changed",
1149 	    "uncorrectable data error", "interface CRC error"};
1150 	const char *const *errstr;
1151 	int i;
1152 	const char *sep = "";
1153 
1154 	const char *devname = wd->sc_dev.dv_xname;
1155 	struct ata_drive_datas *drvp = wd->drvp;
1156 	int errno = wd->sc_wdc_bio.r_error;
1157 
1158 	if (drvp->ata_vers >= 4)
1159 		errstr = errstr4_5;
1160 	else
1161 		errstr = errstr0_3;
1162 
1163 	printf("%s: (", devname);
1164 
1165 	if (errno == 0)
1166 		printf("error not notified");
1167 
1168 	for (i = 0; i < 8; i++) {
1169 		if (errno & (1 << i)) {
1170 			printf("%s%s", sep, errstr[i]);
1171 			sep = ", ";
1172 		}
1173 	}
1174 	printf(")\n");
1175 }
1176 
1177 int
1178 wdioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l)
1179 {
1180 	struct wd_softc *wd = device_lookup(&wd_cd, WDUNIT(dev));
1181 	int error = 0, s;
1182 #ifdef __HAVE_OLD_DISKLABEL
1183 	struct disklabel *newlabel = NULL;
1184 #endif
1185 
1186 	ATADEBUG_PRINT(("wdioctl\n"), DEBUG_FUNCS);
1187 
1188 	if ((wd->sc_flags & WDF_LOADED) == 0)
1189 		return EIO;
1190 
1191 	error = disk_ioctl(&wd->sc_dk, xfer, addr, flag, l);
1192 	if (error != EPASSTHROUGH)
1193 		return (error);
1194 
1195 	switch (xfer) {
1196 #ifdef HAS_BAD144_HANDLING
1197 	case DIOCSBAD:
1198 		if ((flag & FWRITE) == 0)
1199 			return EBADF;
1200 		wd->sc_dk.dk_cpulabel->bad = *(struct dkbad *)addr;
1201 		wd->sc_dk.dk_label->d_flags |= D_BADSECT;
1202 		bad144intern(wd);
1203 		return 0;
1204 #endif
1205 #ifdef WD_SOFTBADSECT
1206 	case DIOCBSLIST :
1207 	{
1208 		u_int32_t count, missing, skip;
1209 		struct disk_badsecinfo dbsi;
1210 		struct disk_badsectors *dbs;
1211 		size_t available;
1212 		uint8_t *laddr;
1213 
1214 		dbsi = *(struct disk_badsecinfo *)addr;
1215 		missing = wd->sc_bscount;
1216 		count = 0;
1217 		available = dbsi.dbsi_bufsize;
1218 		skip = dbsi.dbsi_skip;
1219 		laddr = (uint8_t *)dbsi.dbsi_buffer;
1220 
1221 		/*
1222 		 * We start this loop with the expectation that all of the
1223 		 * entries will be missed and decrement this counter each
1224 		 * time we either skip over one (already copied out) or
1225 		 * we actually copy it back to user space.  The structs
1226 		 * holding the bad sector information are copied directly
1227 		 * back to user space whilst the summary is returned via
1228 		 * the struct passed in via the ioctl.
1229 		 */
1230 		SLIST_FOREACH(dbs, &wd->sc_bslist, dbs_next) {
1231 			if (skip > 0) {
1232 				missing--;
1233 				skip--;
1234 				continue;
1235 			}
1236 			if (available < sizeof(*dbs))
1237 				break;
1238 			available -= sizeof(*dbs);
1239 			copyout(dbs, laddr, sizeof(*dbs));
1240 			laddr += sizeof(*dbs);
1241 			missing--;
1242 			count++;
1243 		}
1244 		dbsi.dbsi_left = missing;
1245 		dbsi.dbsi_copied = count;
1246 		*(struct disk_badsecinfo *)addr = dbsi;
1247 		return 0;
1248 	}
1249 
1250 	case DIOCBSFLUSH :
1251 		/* Clean out the bad sector list */
1252 		while (!SLIST_EMPTY(&wd->sc_bslist)) {
1253 			void *head = SLIST_FIRST(&wd->sc_bslist);
1254 			SLIST_REMOVE_HEAD(&wd->sc_bslist, dbs_next);
1255 			free(head, M_TEMP);
1256 		}
1257 		wd->sc_bscount = 0;
1258 		return 0;
1259 #endif
1260 	case DIOCGDINFO:
1261 		*(struct disklabel *)addr = *(wd->sc_dk.dk_label);
1262 		return 0;
1263 #ifdef __HAVE_OLD_DISKLABEL
1264 	case ODIOCGDINFO:
1265 		newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK);
1266 		if (newlabel == NULL)
1267 			return EIO;
1268 		*newlabel = *(wd->sc_dk.dk_label);
1269 		if (newlabel->d_npartitions <= OLDMAXPARTITIONS)
1270 			memcpy(addr, newlabel, sizeof (struct olddisklabel));
1271 		else
1272 			error = ENOTTY;
1273 		free(newlabel, M_TEMP);
1274 		return error;
1275 #endif
1276 
1277 	case DIOCGPART:
1278 		((struct partinfo *)addr)->disklab = wd->sc_dk.dk_label;
1279 		((struct partinfo *)addr)->part =
1280 		    &wd->sc_dk.dk_label->d_partitions[WDPART(dev)];
1281 		return 0;
1282 
1283 	case DIOCWDINFO:
1284 	case DIOCSDINFO:
1285 #ifdef __HAVE_OLD_DISKLABEL
1286 	case ODIOCWDINFO:
1287 	case ODIOCSDINFO:
1288 #endif
1289 	{
1290 		struct disklabel *lp;
1291 
1292 		if ((flag & FWRITE) == 0)
1293 			return EBADF;
1294 
1295 #ifdef __HAVE_OLD_DISKLABEL
1296 		if (xfer == ODIOCSDINFO || xfer == ODIOCWDINFO) {
1297 			newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK);
1298 			if (newlabel == NULL)
1299 				return EIO;
1300 			memset(newlabel, 0, sizeof newlabel);
1301 			memcpy(newlabel, addr, sizeof (struct olddisklabel));
1302 			lp = newlabel;
1303 		} else
1304 #endif
1305 		lp = (struct disklabel *)addr;
1306 
1307 		mutex_enter(&wd->sc_dk.dk_openlock);
1308 		wd->sc_flags |= WDF_LABELLING;
1309 
1310 		error = setdisklabel(wd->sc_dk.dk_label,
1311 		    lp, /*wd->sc_dk.dk_openmask : */0,
1312 		    wd->sc_dk.dk_cpulabel);
1313 		if (error == 0) {
1314 			if (wd->drvp->state > RESET) {
1315 				s = splbio();
1316 				wd->drvp->drive_flags |= DRIVE_RESET;
1317 				splx(s);
1318 			}
1319 			if (xfer == DIOCWDINFO
1320 #ifdef __HAVE_OLD_DISKLABEL
1321 			    || xfer == ODIOCWDINFO
1322 #endif
1323 			    )
1324 				error = writedisklabel(WDLABELDEV(dev),
1325 				    wdstrategy, wd->sc_dk.dk_label,
1326 				    wd->sc_dk.dk_cpulabel);
1327 		}
1328 
1329 		wd->sc_flags &= ~WDF_LABELLING;
1330 		mutex_exit(&wd->sc_dk.dk_openlock);
1331 #ifdef __HAVE_OLD_DISKLABEL
1332 		if (newlabel != NULL)
1333 			free(newlabel, M_TEMP);
1334 #endif
1335 		return error;
1336 	}
1337 
1338 	case DIOCKLABEL:
1339 		if (*(int *)addr)
1340 			wd->sc_flags |= WDF_KLABEL;
1341 		else
1342 			wd->sc_flags &= ~WDF_KLABEL;
1343 		return 0;
1344 
1345 	case DIOCWLABEL:
1346 		if ((flag & FWRITE) == 0)
1347 			return EBADF;
1348 		if (*(int *)addr)
1349 			wd->sc_flags |= WDF_WLABEL;
1350 		else
1351 			wd->sc_flags &= ~WDF_WLABEL;
1352 		return 0;
1353 
1354 	case DIOCGDEFLABEL:
1355 		wdgetdefaultlabel(wd, (struct disklabel *)addr);
1356 		return 0;
1357 #ifdef __HAVE_OLD_DISKLABEL
1358 	case ODIOCGDEFLABEL:
1359 		newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK);
1360 		if (newlabel == NULL)
1361 			return EIO;
1362 		wdgetdefaultlabel(wd, newlabel);
1363 		if (newlabel->d_npartitions <= OLDMAXPARTITIONS)
1364 			memcpy(addr, &newlabel, sizeof (struct olddisklabel));
1365 		else
1366 			error = ENOTTY;
1367 		free(newlabel, M_TEMP);
1368 		return error;
1369 #endif
1370 
1371 #ifdef notyet
1372 	case DIOCWFORMAT:
1373 		if ((flag & FWRITE) == 0)
1374 			return EBADF;
1375 		{
1376 		register struct format_op *fop;
1377 		struct iovec aiov;
1378 		struct uio auio;
1379 
1380 		fop = (struct format_op *)addr;
1381 		aiov.iov_base = fop->df_buf;
1382 		aiov.iov_len = fop->df_count;
1383 		auio.uio_iov = &aiov;
1384 		auio.uio_iovcnt = 1;
1385 		auio.uio_resid = fop->df_count;
1386 		auio.uio_offset =
1387 			fop->df_startblk * wd->sc_dk.dk_label->d_secsize;
1388 		auio.uio_vmspace = l->l_proc->p_vmspace;
1389 		error = physio(wdformat, NULL, dev, B_WRITE, minphys,
1390 		    &auio);
1391 		fop->df_count -= auio.uio_resid;
1392 		fop->df_reg[0] = wdc->sc_status;
1393 		fop->df_reg[1] = wdc->sc_error;
1394 		return error;
1395 		}
1396 #endif
1397 	case DIOCGCACHE:
1398 		return wd_getcache(wd, (int *)addr);
1399 
1400 	case DIOCSCACHE:
1401 		return wd_setcache(wd, *(int *)addr);
1402 
1403 	case DIOCCACHESYNC:
1404 		return wd_flushcache(wd, AT_WAIT);
1405 
1406 	case ATAIOCCOMMAND:
1407 		/*
1408 		 * Make sure this command is (relatively) safe first
1409 		 */
1410 		if ((((atareq_t *) addr)->flags & ATACMD_READ) == 0 &&
1411 		    (flag & FWRITE) == 0)
1412 			return (EBADF);
1413 		{
1414 		struct wd_ioctl *wi;
1415 		atareq_t *atareq = (atareq_t *) addr;
1416 		int error1;
1417 
1418 		wi = wi_get();
1419 		wi->wi_softc = wd;
1420 		wi->wi_atareq = *atareq;
1421 
1422 		if (atareq->datalen && atareq->flags &
1423 		    (ATACMD_READ | ATACMD_WRITE)) {
1424 			void *tbuf;
1425 			if (atareq->datalen < DEV_BSIZE
1426 			    && atareq->command == WDCC_IDENTIFY) {
1427 				tbuf = malloc(DEV_BSIZE, M_TEMP, M_WAITOK);
1428 				wi->wi_iov.iov_base = tbuf;
1429 				wi->wi_iov.iov_len = DEV_BSIZE;
1430 				UIO_SETUP_SYSSPACE(&wi->wi_uio);
1431 			} else {
1432 				tbuf = NULL;
1433 				wi->wi_iov.iov_base = atareq->databuf;
1434 				wi->wi_iov.iov_len = atareq->datalen;
1435 				wi->wi_uio.uio_vmspace = l->l_proc->p_vmspace;
1436 			}
1437 			wi->wi_uio.uio_iov = &wi->wi_iov;
1438 			wi->wi_uio.uio_iovcnt = 1;
1439 			wi->wi_uio.uio_resid = atareq->datalen;
1440 			wi->wi_uio.uio_offset = 0;
1441 			wi->wi_uio.uio_rw =
1442 			    (atareq->flags & ATACMD_READ) ? B_READ : B_WRITE;
1443 			error1 = physio(wdioctlstrategy, &wi->wi_bp, dev,
1444 			    (atareq->flags & ATACMD_READ) ? B_READ : B_WRITE,
1445 			    minphys, &wi->wi_uio);
1446 			if (tbuf != NULL && error1 == 0) {
1447 				error1 = copyout(tbuf, atareq->databuf,
1448 				    atareq->datalen);
1449 				free(tbuf, M_TEMP);
1450 			}
1451 		} else {
1452 			/* No need to call physio if we don't have any
1453 			   user data */
1454 			wi->wi_bp.b_flags = 0;
1455 			wi->wi_bp.b_data = 0;
1456 			wi->wi_bp.b_bcount = 0;
1457 			wi->wi_bp.b_dev = 0;
1458 			wi->wi_bp.b_proc = l->l_proc;
1459 			wdioctlstrategy(&wi->wi_bp);
1460 			error1 = wi->wi_bp.b_error;
1461 		}
1462 		*atareq = wi->wi_atareq;
1463 		wi_free(wi);
1464 		return(error1);
1465 		}
1466 
1467 	case DIOCAWEDGE:
1468 	    {
1469 	    	struct dkwedge_info *dkw = (void *) addr;
1470 
1471 		if ((flag & FWRITE) == 0)
1472 			return (EBADF);
1473 
1474 		/* If the ioctl happens here, the parent is us. */
1475 		strcpy(dkw->dkw_parent, wd->sc_dev.dv_xname);
1476 		return (dkwedge_add(dkw));
1477 	    }
1478 
1479 	case DIOCDWEDGE:
1480 	    {
1481 	    	struct dkwedge_info *dkw = (void *) addr;
1482 
1483 		if ((flag & FWRITE) == 0)
1484 			return (EBADF);
1485 
1486 		/* If the ioctl happens here, the parent is us. */
1487 		strcpy(dkw->dkw_parent, wd->sc_dev.dv_xname);
1488 		return (dkwedge_del(dkw));
1489 	    }
1490 
1491 	case DIOCLWEDGES:
1492 	    {
1493 	    	struct dkwedge_list *dkwl = (void *) addr;
1494 
1495 		return (dkwedge_list(&wd->sc_dk, dkwl, l));
1496 	    }
1497 
1498 	case DIOCGSTRATEGY:
1499 	    {
1500 		struct disk_strategy *dks = (void *)addr;
1501 
1502 		s = splbio();
1503 		strlcpy(dks->dks_name, bufq_getstrategyname(wd->sc_q),
1504 		    sizeof(dks->dks_name));
1505 		splx(s);
1506 		dks->dks_paramlen = 0;
1507 
1508 		return 0;
1509 	    }
1510 
1511 	case DIOCSSTRATEGY:
1512 	    {
1513 		struct disk_strategy *dks = (void *)addr;
1514 		struct bufq_state *new;
1515 		struct bufq_state *old;
1516 
1517 		if ((flag & FWRITE) == 0) {
1518 			return EBADF;
1519 		}
1520 		if (dks->dks_param != NULL) {
1521 			return EINVAL;
1522 		}
1523 		dks->dks_name[sizeof(dks->dks_name) - 1] = 0; /* ensure term */
1524 		error = bufq_alloc(&new, dks->dks_name,
1525 		    BUFQ_EXACT|BUFQ_SORT_RAWBLOCK);
1526 		if (error) {
1527 			return error;
1528 		}
1529 		s = splbio();
1530 		old = wd->sc_q;
1531 		bufq_move(new, old);
1532 		wd->sc_q = new;
1533 		splx(s);
1534 		bufq_free(old);
1535 
1536 		return 0;
1537 	    }
1538 
1539 	default:
1540 		return ENOTTY;
1541 	}
1542 
1543 #ifdef DIAGNOSTIC
1544 	panic("wdioctl: impossible");
1545 #endif
1546 }
1547 
1548 #ifdef B_FORMAT
1549 int
1550 wdformat(struct buf *bp)
1551 {
1552 
1553 	bp->b_flags |= B_FORMAT;
1554 	return wdstrategy(bp);
1555 }
1556 #endif
1557 
1558 int
1559 wdsize(dev_t dev)
1560 {
1561 	struct wd_softc *wd;
1562 	int part, omask;
1563 	int size;
1564 
1565 	ATADEBUG_PRINT(("wdsize\n"), DEBUG_FUNCS);
1566 
1567 	wd = device_lookup(&wd_cd, WDUNIT(dev));
1568 	if (wd == NULL)
1569 		return (-1);
1570 
1571 	part = WDPART(dev);
1572 	omask = wd->sc_dk.dk_openmask & (1 << part);
1573 
1574 	if (omask == 0 && wdopen(dev, 0, S_IFBLK, NULL) != 0)
1575 		return (-1);
1576 	if (wd->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
1577 		size = -1;
1578 	else
1579 		size = wd->sc_dk.dk_label->d_partitions[part].p_size *
1580 		    (wd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
1581 	if (omask == 0 && wdclose(dev, 0, S_IFBLK, NULL) != 0)
1582 		return (-1);
1583 	return (size);
1584 }
1585 
1586 /* #define WD_DUMP_NOT_TRUSTED if you just want to watch */
1587 static int wddoingadump = 0;
1588 static int wddumprecalibrated = 0;
1589 
1590 /*
1591  * Dump core after a system crash.
1592  */
1593 int
1594 wddump(dev_t dev, daddr_t blkno, void *va, size_t size)
1595 {
1596 	struct wd_softc *wd;	/* disk unit to do the I/O */
1597 	struct disklabel *lp;   /* disk's disklabel */
1598 	int part, err;
1599 	int nblks;	/* total number of sectors left to write */
1600 
1601 	/* Check if recursive dump; if so, punt. */
1602 	if (wddoingadump)
1603 		return EFAULT;
1604 	wddoingadump = 1;
1605 
1606 	wd = device_lookup(&wd_cd, WDUNIT(dev));
1607 	if (wd == NULL)
1608 		return (ENXIO);
1609 
1610 	part = WDPART(dev);
1611 
1612 	/* Convert to disk sectors.  Request must be a multiple of size. */
1613 	lp = wd->sc_dk.dk_label;
1614 	if ((size % lp->d_secsize) != 0)
1615 		return EFAULT;
1616 	nblks = size / lp->d_secsize;
1617 	blkno = blkno / (lp->d_secsize / DEV_BSIZE);
1618 
1619 	/* Check transfer bounds against partition size. */
1620 	if ((blkno < 0) || ((blkno + nblks) > lp->d_partitions[part].p_size))
1621 		return EINVAL;
1622 
1623 	/* Offset block number to start of partition. */
1624 	blkno += lp->d_partitions[part].p_offset;
1625 
1626 	/* Recalibrate, if first dump transfer. */
1627 	if (wddumprecalibrated == 0) {
1628 		wddumprecalibrated = 1;
1629 		(*wd->atabus->ata_reset_drive)(wd->drvp,
1630 					       AT_POLL | AT_RST_EMERG);
1631 		wd->drvp->state = RESET;
1632 	}
1633 
1634 	wd->sc_bp = NULL;
1635 	wd->sc_wdc_bio.blkno = blkno;
1636 	wd->sc_wdc_bio.flags = ATA_POLL;
1637 	if (wd->sc_flags & WDF_LBA48 &&
1638 	    (blkno > LBA48_THRESHOLD ||
1639     	    (wd->sc_quirks & WD_QUIRK_FORCE_LBA48) != 0))
1640 		wd->sc_wdc_bio.flags |= ATA_LBA48;
1641 	if (wd->sc_flags & WDF_LBA)
1642 		wd->sc_wdc_bio.flags |= ATA_LBA;
1643 	wd->sc_wdc_bio.bcount = nblks * lp->d_secsize;
1644 	wd->sc_wdc_bio.databuf = va;
1645 #ifndef WD_DUMP_NOT_TRUSTED
1646 	switch (wd->atabus->ata_bio(wd->drvp, &wd->sc_wdc_bio)) {
1647 	case ATACMD_TRY_AGAIN:
1648 		panic("wddump: try again");
1649 		break;
1650 	case ATACMD_QUEUED:
1651 		panic("wddump: polled command has been queued");
1652 		break;
1653 	case ATACMD_COMPLETE:
1654 		break;
1655 	}
1656 	switch(wd->sc_wdc_bio.error) {
1657 	case TIMEOUT:
1658 		printf("wddump: device timed out");
1659 		err = EIO;
1660 		break;
1661 	case ERR_DF:
1662 		printf("wddump: drive fault");
1663 		err = EIO;
1664 		break;
1665 	case ERR_DMA:
1666 		printf("wddump: DMA error");
1667 		err = EIO;
1668 		break;
1669 	case ERROR:
1670 		printf("wddump: ");
1671 		wdperror(wd);
1672 		err = EIO;
1673 		break;
1674 	case NOERROR:
1675 		err = 0;
1676 		break;
1677 	default:
1678 		panic("wddump: unknown error type");
1679 	}
1680 	if (err != 0) {
1681 		printf("\n");
1682 		return err;
1683 	}
1684 #else	/* WD_DUMP_NOT_TRUSTED */
1685 	/* Let's just talk about this first... */
1686 	printf("wd%d: dump addr 0x%x, cylin %d, head %d, sector %d\n",
1687 	    unit, va, cylin, head, sector);
1688 	delay(500 * 1000);	/* half a second */
1689 #endif
1690 
1691 	wddoingadump = 0;
1692 	return 0;
1693 }
1694 
1695 #ifdef HAS_BAD144_HANDLING
1696 /*
1697  * Internalize the bad sector table.
1698  */
1699 void
1700 bad144intern(struct wd_softc *wd)
1701 {
1702 	struct dkbad *bt = &wd->sc_dk.dk_cpulabel->bad;
1703 	struct disklabel *lp = wd->sc_dk.dk_label;
1704 	int i = 0;
1705 
1706 	ATADEBUG_PRINT(("bad144intern\n"), DEBUG_XFERS);
1707 
1708 	for (; i < NBT_BAD; i++) {
1709 		if (bt->bt_bad[i].bt_cyl == 0xffff)
1710 			break;
1711 		wd->sc_badsect[i] =
1712 		    bt->bt_bad[i].bt_cyl * lp->d_secpercyl +
1713 		    (bt->bt_bad[i].bt_trksec >> 8) * lp->d_nsectors +
1714 		    (bt->bt_bad[i].bt_trksec & 0xff);
1715 	}
1716 	for (; i < NBT_BAD+1; i++)
1717 		wd->sc_badsect[i] = -1;
1718 }
1719 #endif
1720 
1721 static void
1722 wd_params_to_properties(struct wd_softc *wd, struct ataparams *params)
1723 {
1724 	prop_dictionary_t disk_info, odisk_info, geom;
1725 	const char *cp;
1726 
1727 	disk_info = prop_dictionary_create();
1728 
1729 	if (strcmp(wd->sc_params.atap_model, "ST506") == 0)
1730 		cp = "ST506";
1731 	else {
1732 		/* XXX Should have a case for ATA here, too. */
1733 		cp = "ESDI";
1734 	}
1735 	prop_dictionary_set_cstring_nocopy(disk_info, "type", cp);
1736 
1737 	geom = prop_dictionary_create();
1738 
1739 	prop_dictionary_set_uint64(geom, "sectors-per-unit", wd->sc_capacity);
1740 
1741 	prop_dictionary_set_uint32(geom, "sector-size",
1742 				   DEV_BSIZE /* XXX 512? */);
1743 
1744 	prop_dictionary_set_uint16(geom, "sectors-per-track",
1745 				   wd->sc_params.atap_sectors);
1746 
1747 	prop_dictionary_set_uint16(geom, "tracks-per-cylinder",
1748 				   wd->sc_params.atap_heads);
1749 
1750 	if (wd->sc_flags & WDF_LBA)
1751 		prop_dictionary_set_uint64(geom, "cylinders-per-unit",
1752 					   wd->sc_capacity /
1753 					       (wd->sc_params.atap_heads *
1754 					        wd->sc_params.atap_sectors));
1755 	else
1756 		prop_dictionary_set_uint16(geom, "cylinders-per-unit",
1757 					   wd->sc_params.atap_cylinders);
1758 
1759 	prop_dictionary_set(disk_info, "geometry", geom);
1760 	prop_object_release(geom);
1761 
1762 	prop_dictionary_set(device_properties(&wd->sc_dev),
1763 			    "disk-info", disk_info);
1764 
1765 	/*
1766 	 * Don't release disk_info here; we keep a reference to it.
1767 	 * disk_detach() will release it when we go away.
1768 	 */
1769 
1770 	odisk_info = wd->sc_dk.dk_info;
1771 	wd->sc_dk.dk_info = disk_info;
1772 	if (odisk_info)
1773 		prop_object_release(odisk_info);
1774 }
1775 
1776 int
1777 wd_get_params(struct wd_softc *wd, u_int8_t flags, struct ataparams *params)
1778 {
1779 
1780 	switch (wd->atabus->ata_get_params(wd->drvp, flags, params)) {
1781 	case CMD_AGAIN:
1782 		return 1;
1783 	case CMD_ERR:
1784 		/*
1785 		 * We `know' there's a drive here; just assume it's old.
1786 		 * This geometry is only used to read the MBR and print a
1787 		 * (false) attach message.
1788 		 */
1789 		strncpy(params->atap_model, "ST506",
1790 		    sizeof params->atap_model);
1791 		params->atap_config = ATA_CFG_FIXED;
1792 		params->atap_cylinders = 1024;
1793 		params->atap_heads = 8;
1794 		params->atap_sectors = 17;
1795 		params->atap_multi = 1;
1796 		params->atap_capabilities1 = params->atap_capabilities2 = 0;
1797 		wd->drvp->ata_vers = -1; /* Mark it as pre-ATA */
1798 		/* FALLTHROUGH */
1799 	case CMD_OK:
1800 		wd_params_to_properties(wd, params);
1801 		return 0;
1802 	default:
1803 		panic("wd_get_params: bad return code from ata_get_params");
1804 		/* NOTREACHED */
1805 	}
1806 }
1807 
1808 int
1809 wd_getcache(struct wd_softc *wd, int *bitsp)
1810 {
1811 	struct ataparams params;
1812 
1813 	if (wd_get_params(wd, AT_WAIT, &params) != 0)
1814 		return EIO;
1815 	if (params.atap_cmd_set1 == 0x0000 ||
1816 	    params.atap_cmd_set1 == 0xffff ||
1817 	    (params.atap_cmd_set1 & WDC_CMD1_CACHE) == 0) {
1818 		*bitsp = 0;
1819 		return 0;
1820 	}
1821 	*bitsp = DKCACHE_WCHANGE | DKCACHE_READ;
1822 	if (params.atap_cmd1_en & WDC_CMD1_CACHE)
1823 		*bitsp |= DKCACHE_WRITE;
1824 
1825 	return 0;
1826 }
1827 
1828 const char at_errbits[] = "\20\10ERROR\11TIMEOU\12DF";
1829 
1830 int
1831 wd_setcache(struct wd_softc *wd, int bits)
1832 {
1833 	struct ataparams params;
1834 	struct ata_command ata_c;
1835 
1836 	if (wd_get_params(wd, AT_WAIT, &params) != 0)
1837 		return EIO;
1838 
1839 	if (params.atap_cmd_set1 == 0x0000 ||
1840 	    params.atap_cmd_set1 == 0xffff ||
1841 	    (params.atap_cmd_set1 & WDC_CMD1_CACHE) == 0)
1842 		return EOPNOTSUPP;
1843 
1844 	if ((bits & DKCACHE_READ) == 0 ||
1845 	    (bits & DKCACHE_SAVE) != 0)
1846 		return EOPNOTSUPP;
1847 
1848 	memset(&ata_c, 0, sizeof(struct ata_command));
1849 	ata_c.r_command = SET_FEATURES;
1850 	ata_c.r_st_bmask = 0;
1851 	ata_c.r_st_pmask = 0;
1852 	ata_c.timeout = 30000; /* 30s timeout */
1853 	ata_c.flags = AT_WAIT;
1854 	if (bits & DKCACHE_WRITE)
1855 		ata_c.r_features = WDSF_WRITE_CACHE_EN;
1856 	else
1857 		ata_c.r_features = WDSF_WRITE_CACHE_DS;
1858 	if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
1859 		printf("%s: wd_setcache command not complete\n",
1860 		    wd->sc_dev.dv_xname);
1861 		return EIO;
1862 	}
1863 	if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
1864 		char sbuf[sizeof(at_errbits) + 64];
1865 		bitmask_snprintf(ata_c.flags, at_errbits, sbuf, sizeof(sbuf));
1866 		printf("%s: wd_setcache: status=%s\n", wd->sc_dev.dv_xname,
1867 		    sbuf);
1868 		return EIO;
1869 	}
1870 	return 0;
1871 }
1872 
1873 #if notyet
1874 static int
1875 wd_standby(struct wd_softc *wd, int flags)
1876 {
1877 	struct ata_command ata_c;
1878 
1879 	memset(&ata_c, 0, sizeof(struct ata_command));
1880 	ata_c.r_command = WDCC_STANDBY_IMMED;
1881 	ata_c.r_st_bmask = WDCS_DRDY;
1882 	ata_c.r_st_pmask = WDCS_DRDY;
1883 	ata_c.flags = flags;
1884 	ata_c.timeout = 30000; /* 30s timeout */
1885 	if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
1886 		aprint_error_dev(&wd->sc_dev,
1887 		    "standby immediate command didn't complete\n");
1888 		return EIO;
1889 	}
1890 	if (ata_c.flags & AT_ERROR) {
1891 		if (ata_c.r_error == WDCE_ABRT) /* command not supported */
1892 			return ENODEV;
1893 	}
1894 	if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
1895 		char sbuf[sizeof(at_errbits) + 64];
1896 		bitmask_snprintf(ata_c.flags, at_errbits, sbuf, sizeof(sbuf));
1897 		aprint_error_dev(&wd->sc_dev, "wd_standby: status=%s\n", sbuf);
1898 		return EIO;
1899 	}
1900 	return 0;
1901 }
1902 #endif
1903 
1904 int
1905 wd_flushcache(struct wd_softc *wd, int flags)
1906 {
1907 	struct ata_command ata_c;
1908 
1909 	/*
1910 	 * WDCC_FLUSHCACHE is here since ATA-4, but some drives report
1911 	 * only ATA-2 and still support it.
1912 	 */
1913 	if (wd->drvp->ata_vers < 4 &&
1914 	    ((wd->sc_params.atap_cmd_set2 & WDC_CMD2_FC) == 0 ||
1915 	    wd->sc_params.atap_cmd_set2 == 0xffff))
1916 		return ENODEV;
1917 	memset(&ata_c, 0, sizeof(struct ata_command));
1918 	if ((wd->sc_params.atap_cmd2_en & ATA_CMD2_LBA48) != 0 &&
1919 	    (wd->sc_params.atap_cmd2_en & ATA_CMD2_FCE) != 0)
1920 		ata_c.r_command = WDCC_FLUSHCACHE_EXT;
1921 	else
1922 		ata_c.r_command = WDCC_FLUSHCACHE;
1923 	ata_c.r_st_bmask = WDCS_DRDY;
1924 	ata_c.r_st_pmask = WDCS_DRDY;
1925 	ata_c.flags = flags;
1926 	ata_c.timeout = 30000; /* 30s timeout */
1927 	if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
1928 		printf("%s: flush cache command didn't complete\n",
1929 		    wd->sc_dev.dv_xname);
1930 		return EIO;
1931 	}
1932 	if (ata_c.flags & AT_ERROR) {
1933 		if (ata_c.r_error == WDCE_ABRT) /* command not supported */
1934 			return ENODEV;
1935 	}
1936 	if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
1937 		char sbuf[sizeof(at_errbits) + 64];
1938 		bitmask_snprintf(ata_c.flags, at_errbits, sbuf, sizeof(sbuf));
1939 		printf("%s: wd_flushcache: status=%s\n", wd->sc_dev.dv_xname,
1940 		    sbuf);
1941 		return EIO;
1942 	}
1943 	return 0;
1944 }
1945 
1946 /*
1947  * Allocate space for a ioctl queue structure.  Mostly taken from
1948  * scsipi_ioctl.c
1949  */
1950 struct wd_ioctl *
1951 wi_get(void)
1952 {
1953 	struct wd_ioctl *wi;
1954 	int s;
1955 
1956 	wi = malloc(sizeof(struct wd_ioctl), M_TEMP, M_WAITOK|M_ZERO);
1957 	simple_lock_init(&wi->wi_bp.b_interlock);
1958 	s = splbio();
1959 	LIST_INSERT_HEAD(&wi_head, wi, wi_list);
1960 	splx(s);
1961 	return (wi);
1962 }
1963 
1964 /*
1965  * Free an ioctl structure and remove it from our list
1966  */
1967 
1968 void
1969 wi_free(struct wd_ioctl *wi)
1970 {
1971 	int s;
1972 
1973 	s = splbio();
1974 	LIST_REMOVE(wi, wi_list);
1975 	splx(s);
1976 	free(wi, M_TEMP);
1977 }
1978 
1979 /*
1980  * Find a wd_ioctl structure based on the struct buf.
1981  */
1982 
1983 struct wd_ioctl *
1984 wi_find(struct buf *bp)
1985 {
1986 	struct wd_ioctl *wi;
1987 	int s;
1988 
1989 	s = splbio();
1990 	for (wi = wi_head.lh_first; wi != 0; wi = wi->wi_list.le_next)
1991 		if (bp == &wi->wi_bp)
1992 			break;
1993 	splx(s);
1994 	return (wi);
1995 }
1996 
1997 /*
1998  * Ioctl pseudo strategy routine
1999  *
2000  * This is mostly stolen from scsipi_ioctl.c:scsistrategy().  What
2001  * happens here is:
2002  *
2003  * - wdioctl() queues a wd_ioctl structure.
2004  *
2005  * - wdioctl() calls physio/wdioctlstrategy based on whether or not
2006  *   user space I/O is required.  If physio() is called, physio() eventually
2007  *   calls wdioctlstrategy().
2008  *
2009  * - In either case, wdioctlstrategy() calls wd->atabus->ata_exec_command()
2010  *   to perform the actual command
2011  *
2012  * The reason for the use of the pseudo strategy routine is because
2013  * when doing I/O to/from user space, physio _really_ wants to be in
2014  * the loop.  We could put the entire buffer into the ioctl request
2015  * structure, but that won't scale if we want to do things like download
2016  * microcode.
2017  */
2018 
2019 void
2020 wdioctlstrategy(struct buf *bp)
2021 {
2022 	struct wd_ioctl *wi;
2023 	struct ata_command ata_c;
2024 	int error = 0;
2025 
2026 	wi = wi_find(bp);
2027 	if (wi == NULL) {
2028 		printf("wdioctlstrategy: "
2029 		    "No matching ioctl request found in queue\n");
2030 		error = EINVAL;
2031 		goto done;
2032 	}
2033 
2034 	memset(&ata_c, 0, sizeof(ata_c));
2035 
2036 	/*
2037 	 * Abort if physio broke up the transfer
2038 	 */
2039 
2040 	if (bp->b_bcount != wi->wi_atareq.datalen) {
2041 		printf("physio split wd ioctl request... cannot proceed\n");
2042 		error = EIO;
2043 		goto done;
2044 	}
2045 
2046 	/*
2047 	 * Abort if we didn't get a buffer size that was a multiple of
2048 	 * our sector size (or was larger than NBBY)
2049 	 */
2050 
2051 	if ((bp->b_bcount % wi->wi_softc->sc_dk.dk_label->d_secsize) != 0 ||
2052 	    (bp->b_bcount / wi->wi_softc->sc_dk.dk_label->d_secsize) >=
2053 	     (1 << NBBY)) {
2054 		error = EINVAL;
2055 		goto done;
2056 	}
2057 
2058 	/*
2059 	 * Make sure a timeout was supplied in the ioctl request
2060 	 */
2061 
2062 	if (wi->wi_atareq.timeout == 0) {
2063 		error = EINVAL;
2064 		goto done;
2065 	}
2066 
2067 	if (wi->wi_atareq.flags & ATACMD_READ)
2068 		ata_c.flags |= AT_READ;
2069 	else if (wi->wi_atareq.flags & ATACMD_WRITE)
2070 		ata_c.flags |= AT_WRITE;
2071 
2072 	if (wi->wi_atareq.flags & ATACMD_READREG)
2073 		ata_c.flags |= AT_READREG;
2074 
2075 	ata_c.flags |= AT_WAIT;
2076 
2077 	ata_c.timeout = wi->wi_atareq.timeout;
2078 	ata_c.r_command = wi->wi_atareq.command;
2079 	ata_c.r_head = wi->wi_atareq.head & 0x0f;
2080 	ata_c.r_cyl = wi->wi_atareq.cylinder;
2081 	ata_c.r_sector = wi->wi_atareq.sec_num;
2082 	ata_c.r_count = wi->wi_atareq.sec_count;
2083 	ata_c.r_features = wi->wi_atareq.features;
2084 	ata_c.r_st_bmask = WDCS_DRDY;
2085 	ata_c.r_st_pmask = WDCS_DRDY;
2086 	ata_c.data = wi->wi_bp.b_data;
2087 	ata_c.bcount = wi->wi_bp.b_bcount;
2088 
2089 	if (wi->wi_softc->atabus->ata_exec_command(wi->wi_softc->drvp, &ata_c)
2090 	    != ATACMD_COMPLETE) {
2091 		wi->wi_atareq.retsts = ATACMD_ERROR;
2092 		error = EIO;
2093 		goto done;
2094 	}
2095 
2096 	if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
2097 		if (ata_c.flags & AT_ERROR) {
2098 			wi->wi_atareq.retsts = ATACMD_ERROR;
2099 			wi->wi_atareq.error = ata_c.r_error;
2100 		} else if (ata_c.flags & AT_DF)
2101 			wi->wi_atareq.retsts = ATACMD_DF;
2102 		else
2103 			wi->wi_atareq.retsts = ATACMD_TIMEOUT;
2104 	} else {
2105 		wi->wi_atareq.retsts = ATACMD_OK;
2106 		if (wi->wi_atareq.flags & ATACMD_READREG) {
2107 			wi->wi_atareq.head = ata_c.r_head ;
2108 			wi->wi_atareq.cylinder = ata_c.r_cyl;
2109 			wi->wi_atareq.sec_num = ata_c.r_sector;
2110 			wi->wi_atareq.sec_count = ata_c.r_count;
2111 			wi->wi_atareq.features = ata_c.r_features;
2112 			wi->wi_atareq.error = ata_c.r_error;
2113 		}
2114 	}
2115 
2116 done:
2117 	bp->b_error = error;
2118 	biodone(bp);
2119 }
2120