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