wd.c revision 1.363.8.3 1 /* $NetBSD: wd.c,v 1.363.8.3 2010/01/10 23:59:30 snj 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.3 2010/01/10 23:59:30 snj 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
617 if (__predict_false(bp->b_error != 0)) {
618 /*
619 * Propagate the error. If this was the first half of
620 * the original transfer, make sure to account for that
621 * in the residual.
622 */
623 if (bp->b_data == obp->b_data)
624 bp->b_resid += bp->b_bcount;
625 goto done;
626 }
627
628 /*
629 * If this was the second half of the transfer, we're all done!
630 */
631 if (bp->b_data != obp->b_data)
632 goto done;
633
634 /*
635 * Advance the pointer to the second half and issue that command
636 * using the same opening.
637 */
638 bp->b_flags = obp->b_flags;
639 bp->b_oflags = obp->b_oflags;
640 bp->b_cflags = obp->b_cflags;
641 bp->b_data = (char *)bp->b_data + bp->b_bcount;
642 bp->b_blkno += (bp->b_bcount / 512);
643 bp->b_rawblkno += (bp->b_bcount / 512);
644 __wdstart(sc, bp);
645 return;
646
647 done:
648 obp->b_error = bp->b_error;
649 obp->b_resid = bp->b_resid;
650 putiobuf(bp);
651 biodone(obp);
652 sc->openings++;
653 /* wddone() will call wdstart() */
654 }
655
656 void
657 __wdstart(struct wd_softc *wd, struct buf *bp)
658 {
659
660 /*
661 * Deal with the "split mod15 write" quirk. We just divide the
662 * transfer in two, doing the first half and then then second half
663 * with the same command opening.
664 *
665 * Note we MUST do this here, because we can't let insertion
666 * into the bufq cause the transfers to be re-merged.
667 */
668 if (__predict_false((wd->sc_quirks & WD_QUIRK_SPLIT_MOD15_WRITE) != 0 &&
669 (bp->b_flags & B_READ) == 0 &&
670 bp->b_bcount > 512 &&
671 ((bp->b_bcount / 512) % 15) == 1)) {
672 struct buf *nbp;
673
674 /* already at splbio */
675 nbp = getiobuf(NULL, false);
676 if (__predict_false(nbp == NULL)) {
677 /* No memory -- fail the iop. */
678 bp->b_error = ENOMEM;
679 bp->b_resid = bp->b_bcount;
680 biodone(bp);
681 wd->openings++;
682 return;
683 }
684
685 nbp->b_error = 0;
686 nbp->b_proc = bp->b_proc;
687 nbp->b_dev = bp->b_dev;
688
689 nbp->b_bcount = bp->b_bcount / 2;
690 nbp->b_bufsize = bp->b_bcount / 2;
691 nbp->b_data = bp->b_data;
692
693 nbp->b_blkno = bp->b_blkno;
694 nbp->b_rawblkno = bp->b_rawblkno;
695
696 nbp->b_flags = bp->b_flags;
697 nbp->b_oflags = bp->b_oflags;
698 nbp->b_cflags = bp->b_cflags;
699 nbp->b_iodone = wd_split_mod15_write;
700
701 /* Put ptr to orig buf in b_private and use new buf */
702 nbp->b_private = bp;
703
704 BIO_COPYPRIO(nbp, bp);
705
706 bp = nbp;
707 }
708
709 wd->sc_wdc_bio.blkno = bp->b_rawblkno;
710 wd->sc_wdc_bio.bcount = bp->b_bcount;
711 wd->sc_wdc_bio.databuf = bp->b_data;
712 wd->sc_wdc_bio.blkdone =0;
713 wd->sc_bp = bp;
714 /*
715 * If we're retrying, retry in single-sector mode. This will give us
716 * the sector number of the problem, and will eventually allow the
717 * transfer to succeed.
718 */
719 if (wd->retries >= WDIORETRIES_SINGLE)
720 wd->sc_wdc_bio.flags = ATA_SINGLE;
721 else
722 wd->sc_wdc_bio.flags = 0;
723 if (wd->sc_flags & WDF_LBA48 &&
724 (wd->sc_wdc_bio.blkno +
725 wd->sc_wdc_bio.bcount / wd->sc_dk.dk_label->d_secsize) >
726 wd->sc_capacity28)
727 wd->sc_wdc_bio.flags |= ATA_LBA48;
728 if (wd->sc_flags & WDF_LBA)
729 wd->sc_wdc_bio.flags |= ATA_LBA;
730 if (bp->b_flags & B_READ)
731 wd->sc_wdc_bio.flags |= ATA_READ;
732 /* Instrumentation. */
733 disk_busy(&wd->sc_dk);
734 switch (wd->atabus->ata_bio(wd->drvp, &wd->sc_wdc_bio)) {
735 case ATACMD_TRY_AGAIN:
736 callout_reset(&wd->sc_restart_ch, hz, wdrestart, wd);
737 break;
738 case ATACMD_QUEUED:
739 case ATACMD_COMPLETE:
740 break;
741 default:
742 panic("__wdstart: bad return code from ata_bio()");
743 }
744 }
745
746 void
747 wddone(void *v)
748 {
749 struct wd_softc *wd = device_private(v);
750 struct buf *bp = wd->sc_bp;
751 const char *errmsg;
752 int do_perror = 0;
753
754 ATADEBUG_PRINT(("wddone %s\n", device_xname(wd->sc_dev)),
755 DEBUG_XFERS);
756 if (bp == NULL)
757 return;
758 bp->b_resid = wd->sc_wdc_bio.bcount;
759 switch (wd->sc_wdc_bio.error) {
760 case ERR_DMA:
761 errmsg = "DMA error";
762 goto retry;
763 case ERR_DF:
764 errmsg = "device fault";
765 goto retry;
766 case TIMEOUT:
767 errmsg = "device timeout";
768 goto retry;
769 case ERR_RESET:
770 errmsg = "channel reset";
771 goto retry2;
772 case ERROR:
773 /* Don't care about media change bits */
774 if (wd->sc_wdc_bio.r_error != 0 &&
775 (wd->sc_wdc_bio.r_error & ~(WDCE_MC | WDCE_MCR)) == 0)
776 goto noerror;
777 errmsg = "error";
778 do_perror = 1;
779 retry: /* Just reset and retry. Can we do more ? */
780 (*wd->atabus->ata_reset_drive)(wd->drvp, AT_RST_NOCMD);
781 retry2:
782 diskerr(bp, "wd", errmsg, LOG_PRINTF,
783 wd->sc_wdc_bio.blkdone, wd->sc_dk.dk_label);
784 if (wd->retries < WDIORETRIES)
785 printf(", retrying");
786 printf("\n");
787 if (do_perror)
788 wdperror(wd);
789 if (wd->retries < WDIORETRIES) {
790 wd->retries++;
791 callout_reset(&wd->sc_restart_ch, RECOVERYTIME,
792 wdrestart, wd);
793 return;
794 }
795
796 #ifdef WD_SOFTBADSECT
797 /*
798 * Not all errors indicate a failed block but those that do,
799 * put the block on the bad-block list for the device. Only
800 * do this for reads because the drive should do it for writes,
801 * itself, according to Manuel.
802 */
803 if ((bp->b_flags & B_READ) &&
804 ((wd->drvp->ata_vers >= 4 && wd->sc_wdc_bio.r_error & 64) ||
805 (wd->drvp->ata_vers < 4 && wd->sc_wdc_bio.r_error & 192))) {
806 struct disk_badsectors *dbs;
807
808 dbs = malloc(sizeof *dbs, M_TEMP, M_WAITOK);
809 dbs->dbs_min = bp->b_rawblkno;
810 dbs->dbs_max = dbs->dbs_min + (bp->b_bcount >> DEV_BSHIFT) - 1;
811 microtime(&dbs->dbs_failedat);
812 SLIST_INSERT_HEAD(&wd->sc_bslist, dbs, dbs_next);
813 wd->sc_bscount++;
814 }
815 #endif
816 bp->b_error = EIO;
817 break;
818 case NOERROR:
819 noerror: if ((wd->sc_wdc_bio.flags & ATA_CORR) || wd->retries > 0)
820 aprint_error_dev(wd->sc_dev,
821 "soft error (corrected)\n");
822 break;
823 case ERR_NODEV:
824 bp->b_error = EIO;
825 break;
826 }
827 disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid),
828 (bp->b_flags & B_READ));
829 #if NRND > 0
830 rnd_add_uint32(&wd->rnd_source, bp->b_blkno);
831 #endif
832 /* XXX Yuck, but we don't want to increment openings in this case */
833 if (__predict_false(bp->b_iodone == wd_split_mod15_write))
834 biodone(bp);
835 else {
836 biodone(bp);
837 wd->openings++;
838 }
839 wdstart(wd);
840 }
841
842 void
843 wdrestart(void *v)
844 {
845 struct wd_softc *wd = v;
846 struct buf *bp = wd->sc_bp;
847 int s;
848
849 ATADEBUG_PRINT(("wdrestart %s\n", device_xname(wd->sc_dev)),
850 DEBUG_XFERS);
851 s = splbio();
852 __wdstart(v, bp);
853 splx(s);
854 }
855
856 int
857 wdread(dev_t dev, struct uio *uio, int flags)
858 {
859
860 ATADEBUG_PRINT(("wdread\n"), DEBUG_XFERS);
861 return (physio(wdstrategy, NULL, dev, B_READ, minphys, uio));
862 }
863
864 int
865 wdwrite(dev_t dev, struct uio *uio, int flags)
866 {
867
868 ATADEBUG_PRINT(("wdwrite\n"), DEBUG_XFERS);
869 return (physio(wdstrategy, NULL, dev, B_WRITE, minphys, uio));
870 }
871
872 int
873 wdopen(dev_t dev, int flag, int fmt, struct lwp *l)
874 {
875 struct wd_softc *wd;
876 int part, error;
877
878 ATADEBUG_PRINT(("wdopen\n"), DEBUG_FUNCS);
879 wd = device_lookup_private(&wd_cd, WDUNIT(dev));
880 if (wd == NULL)
881 return (ENXIO);
882
883 if (! device_is_active(wd->sc_dev))
884 return (ENODEV);
885
886 part = WDPART(dev);
887
888 mutex_enter(&wd->sc_dk.dk_openlock);
889
890 /*
891 * If there are wedges, and this is not RAW_PART, then we
892 * need to fail.
893 */
894 if (wd->sc_dk.dk_nwedges != 0 && part != RAW_PART) {
895 error = EBUSY;
896 goto bad1;
897 }
898
899 /*
900 * If this is the first open of this device, add a reference
901 * to the adapter.
902 */
903 if (wd->sc_dk.dk_openmask == 0 &&
904 (error = wd->atabus->ata_addref(wd->drvp)) != 0)
905 goto bad1;
906
907 if (wd->sc_dk.dk_openmask != 0) {
908 /*
909 * If any partition is open, but the disk has been invalidated,
910 * disallow further opens.
911 */
912 if ((wd->sc_flags & WDF_LOADED) == 0) {
913 error = EIO;
914 goto bad2;
915 }
916 } else {
917 if ((wd->sc_flags & WDF_LOADED) == 0) {
918 wd->sc_flags |= WDF_LOADED;
919
920 /* Load the physical device parameters. */
921 wd_get_params(wd, AT_WAIT, &wd->sc_params);
922
923 /* Load the partition info if not already loaded. */
924 wdgetdisklabel(wd);
925 }
926 }
927
928 /* Check that the partition exists. */
929 if (part != RAW_PART &&
930 (part >= wd->sc_dk.dk_label->d_npartitions ||
931 wd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
932 error = ENXIO;
933 goto bad2;
934 }
935
936 /* Insure only one open at a time. */
937 switch (fmt) {
938 case S_IFCHR:
939 wd->sc_dk.dk_copenmask |= (1 << part);
940 break;
941 case S_IFBLK:
942 wd->sc_dk.dk_bopenmask |= (1 << part);
943 break;
944 }
945 wd->sc_dk.dk_openmask =
946 wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
947
948 mutex_exit(&wd->sc_dk.dk_openlock);
949 return 0;
950
951 bad2:
952 if (wd->sc_dk.dk_openmask == 0)
953 wd->atabus->ata_delref(wd->drvp);
954 bad1:
955 mutex_exit(&wd->sc_dk.dk_openlock);
956 return error;
957 }
958
959 int
960 wdclose(dev_t dev, int flag, int fmt, struct lwp *l)
961 {
962 struct wd_softc *wd =
963 device_lookup_private(&wd_cd, WDUNIT(dev));
964 int part = WDPART(dev);
965
966 ATADEBUG_PRINT(("wdclose\n"), DEBUG_FUNCS);
967
968 mutex_enter(&wd->sc_dk.dk_openlock);
969
970 switch (fmt) {
971 case S_IFCHR:
972 wd->sc_dk.dk_copenmask &= ~(1 << part);
973 break;
974 case S_IFBLK:
975 wd->sc_dk.dk_bopenmask &= ~(1 << part);
976 break;
977 }
978 wd->sc_dk.dk_openmask =
979 wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
980
981 if (wd->sc_dk.dk_openmask == 0) {
982 wd_flushcache(wd, AT_WAIT);
983
984 if (! (wd->sc_flags & WDF_KLABEL))
985 wd->sc_flags &= ~WDF_LOADED;
986
987 wd->atabus->ata_delref(wd->drvp);
988 }
989
990 mutex_exit(&wd->sc_dk.dk_openlock);
991 return 0;
992 }
993
994 void
995 wdgetdefaultlabel(struct wd_softc *wd, struct disklabel *lp)
996 {
997
998 ATADEBUG_PRINT(("wdgetdefaultlabel\n"), DEBUG_FUNCS);
999 memset(lp, 0, sizeof(struct disklabel));
1000
1001 lp->d_secsize = DEV_BSIZE;
1002 lp->d_ntracks = wd->sc_params.atap_heads;
1003 lp->d_nsectors = wd->sc_params.atap_sectors;
1004 lp->d_ncylinders = (wd->sc_flags & WDF_LBA) ? wd->sc_capacity /
1005 (wd->sc_params.atap_heads * wd->sc_params.atap_sectors) :
1006 wd->sc_params.atap_cylinders;
1007 lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
1008
1009 if (strcmp(wd->sc_params.atap_model, "ST506") == 0)
1010 lp->d_type = DTYPE_ST506;
1011 else
1012 lp->d_type = DTYPE_ESDI;
1013
1014 strncpy(lp->d_typename, wd->sc_params.atap_model, 16);
1015 strncpy(lp->d_packname, "fictitious", 16);
1016 if (wd->sc_capacity > UINT32_MAX)
1017 lp->d_secperunit = UINT32_MAX;
1018 else
1019 lp->d_secperunit = wd->sc_capacity;
1020 lp->d_rpm = 3600;
1021 lp->d_interleave = 1;
1022 lp->d_flags = 0;
1023
1024 lp->d_partitions[RAW_PART].p_offset = 0;
1025 lp->d_partitions[RAW_PART].p_size =
1026 lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
1027 lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
1028 lp->d_npartitions = RAW_PART + 1;
1029
1030 lp->d_magic = DISKMAGIC;
1031 lp->d_magic2 = DISKMAGIC;
1032 lp->d_checksum = dkcksum(lp);
1033 }
1034
1035 /*
1036 * Fabricate a default disk label, and try to read the correct one.
1037 */
1038 void
1039 wdgetdisklabel(struct wd_softc *wd)
1040 {
1041 struct disklabel *lp = wd->sc_dk.dk_label;
1042 const char *errstring;
1043 int s;
1044
1045 ATADEBUG_PRINT(("wdgetdisklabel\n"), DEBUG_FUNCS);
1046
1047 memset(wd->sc_dk.dk_cpulabel, 0, sizeof(struct cpu_disklabel));
1048
1049 wdgetdefaultlabel(wd, lp);
1050
1051 wd->sc_badsect[0] = -1;
1052
1053 if (wd->drvp->state > RESET) {
1054 s = splbio();
1055 wd->drvp->drive_flags |= DRIVE_RESET;
1056 splx(s);
1057 }
1058 errstring = readdisklabel(MAKEWDDEV(0, device_unit(wd->sc_dev),
1059 RAW_PART), wdstrategy, lp,
1060 wd->sc_dk.dk_cpulabel);
1061 if (errstring) {
1062 /*
1063 * This probably happened because the drive's default
1064 * geometry doesn't match the DOS geometry. We
1065 * assume the DOS geometry is now in the label and try
1066 * again. XXX This is a kluge.
1067 */
1068 if (wd->drvp->state > RESET) {
1069 s = splbio();
1070 wd->drvp->drive_flags |= DRIVE_RESET;
1071 splx(s);
1072 }
1073 errstring = readdisklabel(MAKEWDDEV(0, device_unit(wd->sc_dev),
1074 RAW_PART), wdstrategy, lp, wd->sc_dk.dk_cpulabel);
1075 }
1076 if (errstring) {
1077 aprint_error_dev(wd->sc_dev, "%s\n", errstring);
1078 return;
1079 }
1080
1081 if (wd->drvp->state > RESET) {
1082 s = splbio();
1083 wd->drvp->drive_flags |= DRIVE_RESET;
1084 splx(s);
1085 }
1086 #ifdef HAS_BAD144_HANDLING
1087 if ((lp->d_flags & D_BADSECT) != 0)
1088 bad144intern(wd);
1089 #endif
1090 }
1091
1092 void
1093 wdperror(const struct wd_softc *wd)
1094 {
1095 static const char *const errstr0_3[] = {"address mark not found",
1096 "track 0 not found", "aborted command", "media change requested",
1097 "id not found", "media changed", "uncorrectable data error",
1098 "bad block detected"};
1099 static const char *const errstr4_5[] = {
1100 "obsolete (address mark not found)",
1101 "no media/write protected", "aborted command",
1102 "media change requested", "id not found", "media changed",
1103 "uncorrectable data error", "interface CRC error"};
1104 const char *const *errstr;
1105 int i;
1106 const char *sep = "";
1107
1108 const char *devname = device_xname(wd->sc_dev);
1109 struct ata_drive_datas *drvp = wd->drvp;
1110 int errno = wd->sc_wdc_bio.r_error;
1111
1112 if (drvp->ata_vers >= 4)
1113 errstr = errstr4_5;
1114 else
1115 errstr = errstr0_3;
1116
1117 printf("%s: (", devname);
1118
1119 if (errno == 0)
1120 printf("error not notified");
1121
1122 for (i = 0; i < 8; i++) {
1123 if (errno & (1 << i)) {
1124 printf("%s%s", sep, errstr[i]);
1125 sep = ", ";
1126 }
1127 }
1128 printf(")\n");
1129 }
1130
1131 int
1132 wdioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l)
1133 {
1134 struct wd_softc *wd =
1135 device_lookup_private(&wd_cd, WDUNIT(dev));
1136 int error = 0, s;
1137 #ifdef __HAVE_OLD_DISKLABEL
1138 struct disklabel *newlabel = NULL;
1139 #endif
1140
1141 ATADEBUG_PRINT(("wdioctl\n"), DEBUG_FUNCS);
1142
1143 if ((wd->sc_flags & WDF_LOADED) == 0)
1144 return EIO;
1145
1146 error = disk_ioctl(&wd->sc_dk, xfer, addr, flag, l);
1147 if (error != EPASSTHROUGH)
1148 return (error);
1149
1150 switch (xfer) {
1151 #ifdef HAS_BAD144_HANDLING
1152 case DIOCSBAD:
1153 if ((flag & FWRITE) == 0)
1154 return EBADF;
1155 wd->sc_dk.dk_cpulabel->bad = *(struct dkbad *)addr;
1156 wd->sc_dk.dk_label->d_flags |= D_BADSECT;
1157 bad144intern(wd);
1158 return 0;
1159 #endif
1160 #ifdef WD_SOFTBADSECT
1161 case DIOCBSLIST :
1162 {
1163 u_int32_t count, missing, skip;
1164 struct disk_badsecinfo dbsi;
1165 struct disk_badsectors *dbs;
1166 size_t available;
1167 uint8_t *laddr;
1168
1169 dbsi = *(struct disk_badsecinfo *)addr;
1170 missing = wd->sc_bscount;
1171 count = 0;
1172 available = dbsi.dbsi_bufsize;
1173 skip = dbsi.dbsi_skip;
1174 laddr = (uint8_t *)dbsi.dbsi_buffer;
1175
1176 /*
1177 * We start this loop with the expectation that all of the
1178 * entries will be missed and decrement this counter each
1179 * time we either skip over one (already copied out) or
1180 * we actually copy it back to user space. The structs
1181 * holding the bad sector information are copied directly
1182 * back to user space whilst the summary is returned via
1183 * the struct passed in via the ioctl.
1184 */
1185 SLIST_FOREACH(dbs, &wd->sc_bslist, dbs_next) {
1186 if (skip > 0) {
1187 missing--;
1188 skip--;
1189 continue;
1190 }
1191 if (available < sizeof(*dbs))
1192 break;
1193 available -= sizeof(*dbs);
1194 copyout(dbs, laddr, sizeof(*dbs));
1195 laddr += sizeof(*dbs);
1196 missing--;
1197 count++;
1198 }
1199 dbsi.dbsi_left = missing;
1200 dbsi.dbsi_copied = count;
1201 *(struct disk_badsecinfo *)addr = dbsi;
1202 return 0;
1203 }
1204
1205 case DIOCBSFLUSH :
1206 /* Clean out the bad sector list */
1207 while (!SLIST_EMPTY(&wd->sc_bslist)) {
1208 void *head = SLIST_FIRST(&wd->sc_bslist);
1209 SLIST_REMOVE_HEAD(&wd->sc_bslist, dbs_next);
1210 free(head, M_TEMP);
1211 }
1212 wd->sc_bscount = 0;
1213 return 0;
1214 #endif
1215 case DIOCGDINFO:
1216 *(struct disklabel *)addr = *(wd->sc_dk.dk_label);
1217 return 0;
1218 #ifdef __HAVE_OLD_DISKLABEL
1219 case ODIOCGDINFO:
1220 newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK);
1221 if (newlabel == NULL)
1222 return EIO;
1223 *newlabel = *(wd->sc_dk.dk_label);
1224 if (newlabel->d_npartitions <= OLDMAXPARTITIONS)
1225 memcpy(addr, newlabel, sizeof (struct olddisklabel));
1226 else
1227 error = ENOTTY;
1228 free(newlabel, M_TEMP);
1229 return error;
1230 #endif
1231
1232 case DIOCGPART:
1233 ((struct partinfo *)addr)->disklab = wd->sc_dk.dk_label;
1234 ((struct partinfo *)addr)->part =
1235 &wd->sc_dk.dk_label->d_partitions[WDPART(dev)];
1236 return 0;
1237
1238 case DIOCWDINFO:
1239 case DIOCSDINFO:
1240 #ifdef __HAVE_OLD_DISKLABEL
1241 case ODIOCWDINFO:
1242 case ODIOCSDINFO:
1243 #endif
1244 {
1245 struct disklabel *lp;
1246
1247 if ((flag & FWRITE) == 0)
1248 return EBADF;
1249
1250 #ifdef __HAVE_OLD_DISKLABEL
1251 if (xfer == ODIOCSDINFO || xfer == ODIOCWDINFO) {
1252 newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK);
1253 if (newlabel == NULL)
1254 return EIO;
1255 memset(newlabel, 0, sizeof newlabel);
1256 memcpy(newlabel, addr, sizeof (struct olddisklabel));
1257 lp = newlabel;
1258 } else
1259 #endif
1260 lp = (struct disklabel *)addr;
1261
1262 mutex_enter(&wd->sc_dk.dk_openlock);
1263 wd->sc_flags |= WDF_LABELLING;
1264
1265 error = setdisklabel(wd->sc_dk.dk_label,
1266 lp, /*wd->sc_dk.dk_openmask : */0,
1267 wd->sc_dk.dk_cpulabel);
1268 if (error == 0) {
1269 if (wd->drvp->state > RESET) {
1270 s = splbio();
1271 wd->drvp->drive_flags |= DRIVE_RESET;
1272 splx(s);
1273 }
1274 if (xfer == DIOCWDINFO
1275 #ifdef __HAVE_OLD_DISKLABEL
1276 || xfer == ODIOCWDINFO
1277 #endif
1278 )
1279 error = writedisklabel(WDLABELDEV(dev),
1280 wdstrategy, wd->sc_dk.dk_label,
1281 wd->sc_dk.dk_cpulabel);
1282 }
1283
1284 wd->sc_flags &= ~WDF_LABELLING;
1285 mutex_exit(&wd->sc_dk.dk_openlock);
1286 #ifdef __HAVE_OLD_DISKLABEL
1287 if (newlabel != NULL)
1288 free(newlabel, M_TEMP);
1289 #endif
1290 return error;
1291 }
1292
1293 case DIOCKLABEL:
1294 if (*(int *)addr)
1295 wd->sc_flags |= WDF_KLABEL;
1296 else
1297 wd->sc_flags &= ~WDF_KLABEL;
1298 return 0;
1299
1300 case DIOCWLABEL:
1301 if ((flag & FWRITE) == 0)
1302 return EBADF;
1303 if (*(int *)addr)
1304 wd->sc_flags |= WDF_WLABEL;
1305 else
1306 wd->sc_flags &= ~WDF_WLABEL;
1307 return 0;
1308
1309 case DIOCGDEFLABEL:
1310 wdgetdefaultlabel(wd, (struct disklabel *)addr);
1311 return 0;
1312 #ifdef __HAVE_OLD_DISKLABEL
1313 case ODIOCGDEFLABEL:
1314 newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK);
1315 if (newlabel == NULL)
1316 return EIO;
1317 wdgetdefaultlabel(wd, newlabel);
1318 if (newlabel->d_npartitions <= OLDMAXPARTITIONS)
1319 memcpy(addr, &newlabel, sizeof (struct olddisklabel));
1320 else
1321 error = ENOTTY;
1322 free(newlabel, M_TEMP);
1323 return error;
1324 #endif
1325
1326 #ifdef notyet
1327 case DIOCWFORMAT:
1328 if ((flag & FWRITE) == 0)
1329 return EBADF;
1330 {
1331 register struct format_op *fop;
1332 struct iovec aiov;
1333 struct uio auio;
1334
1335 fop = (struct format_op *)addr;
1336 aiov.iov_base = fop->df_buf;
1337 aiov.iov_len = fop->df_count;
1338 auio.uio_iov = &aiov;
1339 auio.uio_iovcnt = 1;
1340 auio.uio_resid = fop->df_count;
1341 auio.uio_offset =
1342 fop->df_startblk * wd->sc_dk.dk_label->d_secsize;
1343 auio.uio_vmspace = l->l_proc->p_vmspace;
1344 error = physio(wdformat, NULL, dev, B_WRITE, minphys,
1345 &auio);
1346 fop->df_count -= auio.uio_resid;
1347 fop->df_reg[0] = wdc->sc_status;
1348 fop->df_reg[1] = wdc->sc_error;
1349 return error;
1350 }
1351 #endif
1352 case DIOCGCACHE:
1353 return wd_getcache(wd, (int *)addr);
1354
1355 case DIOCSCACHE:
1356 return wd_setcache(wd, *(int *)addr);
1357
1358 case DIOCCACHESYNC:
1359 return wd_flushcache(wd, AT_WAIT);
1360
1361 case ATAIOCCOMMAND:
1362 /*
1363 * Make sure this command is (relatively) safe first
1364 */
1365 if ((((atareq_t *) addr)->flags & ATACMD_READ) == 0 &&
1366 (flag & FWRITE) == 0)
1367 return (EBADF);
1368 {
1369 struct wd_ioctl *wi;
1370 atareq_t *atareq = (atareq_t *) addr;
1371 int error1;
1372
1373 wi = wi_get();
1374 wi->wi_softc = wd;
1375 wi->wi_atareq = *atareq;
1376
1377 if (atareq->datalen && atareq->flags &
1378 (ATACMD_READ | ATACMD_WRITE)) {
1379 void *tbuf;
1380 if (atareq->datalen < DEV_BSIZE
1381 && atareq->command == WDCC_IDENTIFY) {
1382 tbuf = malloc(DEV_BSIZE, M_TEMP, M_WAITOK);
1383 wi->wi_iov.iov_base = tbuf;
1384 wi->wi_iov.iov_len = DEV_BSIZE;
1385 UIO_SETUP_SYSSPACE(&wi->wi_uio);
1386 } else {
1387 tbuf = NULL;
1388 wi->wi_iov.iov_base = atareq->databuf;
1389 wi->wi_iov.iov_len = atareq->datalen;
1390 wi->wi_uio.uio_vmspace = l->l_proc->p_vmspace;
1391 }
1392 wi->wi_uio.uio_iov = &wi->wi_iov;
1393 wi->wi_uio.uio_iovcnt = 1;
1394 wi->wi_uio.uio_resid = atareq->datalen;
1395 wi->wi_uio.uio_offset = 0;
1396 wi->wi_uio.uio_rw =
1397 (atareq->flags & ATACMD_READ) ? B_READ : B_WRITE;
1398 error1 = physio(wdioctlstrategy, &wi->wi_bp, dev,
1399 (atareq->flags & ATACMD_READ) ? B_READ : B_WRITE,
1400 minphys, &wi->wi_uio);
1401 if (tbuf != NULL && error1 == 0) {
1402 error1 = copyout(tbuf, atareq->databuf,
1403 atareq->datalen);
1404 free(tbuf, M_TEMP);
1405 }
1406 } else {
1407 /* No need to call physio if we don't have any
1408 user data */
1409 wi->wi_bp.b_flags = 0;
1410 wi->wi_bp.b_data = 0;
1411 wi->wi_bp.b_bcount = 0;
1412 wi->wi_bp.b_dev = 0;
1413 wi->wi_bp.b_proc = l->l_proc;
1414 wdioctlstrategy(&wi->wi_bp);
1415 error1 = wi->wi_bp.b_error;
1416 }
1417 *atareq = wi->wi_atareq;
1418 wi_free(wi);
1419 return(error1);
1420 }
1421
1422 case DIOCAWEDGE:
1423 {
1424 struct dkwedge_info *dkw = (void *) addr;
1425
1426 if ((flag & FWRITE) == 0)
1427 return (EBADF);
1428
1429 /* If the ioctl happens here, the parent is us. */
1430 strcpy(dkw->dkw_parent, device_xname(wd->sc_dev));
1431 return (dkwedge_add(dkw));
1432 }
1433
1434 case DIOCDWEDGE:
1435 {
1436 struct dkwedge_info *dkw = (void *) addr;
1437
1438 if ((flag & FWRITE) == 0)
1439 return (EBADF);
1440
1441 /* If the ioctl happens here, the parent is us. */
1442 strcpy(dkw->dkw_parent, device_xname(wd->sc_dev));
1443 return (dkwedge_del(dkw));
1444 }
1445
1446 case DIOCLWEDGES:
1447 {
1448 struct dkwedge_list *dkwl = (void *) addr;
1449
1450 return (dkwedge_list(&wd->sc_dk, dkwl, l));
1451 }
1452
1453 case DIOCGSTRATEGY:
1454 {
1455 struct disk_strategy *dks = (void *)addr;
1456
1457 s = splbio();
1458 strlcpy(dks->dks_name, bufq_getstrategyname(wd->sc_q),
1459 sizeof(dks->dks_name));
1460 splx(s);
1461 dks->dks_paramlen = 0;
1462
1463 return 0;
1464 }
1465
1466 case DIOCSSTRATEGY:
1467 {
1468 struct disk_strategy *dks = (void *)addr;
1469 struct bufq_state *new;
1470 struct bufq_state *old;
1471
1472 if ((flag & FWRITE) == 0) {
1473 return EBADF;
1474 }
1475 if (dks->dks_param != NULL) {
1476 return EINVAL;
1477 }
1478 dks->dks_name[sizeof(dks->dks_name) - 1] = 0; /* ensure term */
1479 error = bufq_alloc(&new, dks->dks_name,
1480 BUFQ_EXACT|BUFQ_SORT_RAWBLOCK);
1481 if (error) {
1482 return error;
1483 }
1484 s = splbio();
1485 old = wd->sc_q;
1486 bufq_move(new, old);
1487 wd->sc_q = new;
1488 splx(s);
1489 bufq_free(old);
1490
1491 return 0;
1492 }
1493
1494 default:
1495 return ENOTTY;
1496 }
1497
1498 #ifdef DIAGNOSTIC
1499 panic("wdioctl: impossible");
1500 #endif
1501 }
1502
1503 #ifdef B_FORMAT
1504 int
1505 wdformat(struct buf *bp)
1506 {
1507
1508 bp->b_flags |= B_FORMAT;
1509 return wdstrategy(bp);
1510 }
1511 #endif
1512
1513 int
1514 wdsize(dev_t dev)
1515 {
1516 struct wd_softc *wd;
1517 int part, omask;
1518 int size;
1519
1520 ATADEBUG_PRINT(("wdsize\n"), DEBUG_FUNCS);
1521
1522 wd = device_lookup_private(&wd_cd, WDUNIT(dev));
1523 if (wd == NULL)
1524 return (-1);
1525
1526 part = WDPART(dev);
1527 omask = wd->sc_dk.dk_openmask & (1 << part);
1528
1529 if (omask == 0 && wdopen(dev, 0, S_IFBLK, NULL) != 0)
1530 return (-1);
1531 if (wd->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
1532 size = -1;
1533 else
1534 size = wd->sc_dk.dk_label->d_partitions[part].p_size *
1535 (wd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
1536 if (omask == 0 && wdclose(dev, 0, S_IFBLK, NULL) != 0)
1537 return (-1);
1538 return (size);
1539 }
1540
1541 /* #define WD_DUMP_NOT_TRUSTED if you just want to watch */
1542 static int wddoingadump = 0;
1543 static int wddumprecalibrated = 0;
1544
1545 /*
1546 * Dump core after a system crash.
1547 */
1548 int
1549 wddump(dev_t dev, daddr_t blkno, void *va, size_t size)
1550 {
1551 struct wd_softc *wd; /* disk unit to do the I/O */
1552 struct disklabel *lp; /* disk's disklabel */
1553 int part, err;
1554 int nblks; /* total number of sectors left to write */
1555
1556 /* Check if recursive dump; if so, punt. */
1557 if (wddoingadump)
1558 return EFAULT;
1559 wddoingadump = 1;
1560
1561 wd = device_lookup_private(&wd_cd, WDUNIT(dev));
1562 if (wd == NULL)
1563 return (ENXIO);
1564
1565 part = WDPART(dev);
1566
1567 /* Convert to disk sectors. Request must be a multiple of size. */
1568 lp = wd->sc_dk.dk_label;
1569 if ((size % lp->d_secsize) != 0)
1570 return EFAULT;
1571 nblks = size / lp->d_secsize;
1572 blkno = blkno / (lp->d_secsize / DEV_BSIZE);
1573
1574 /* Check transfer bounds against partition size. */
1575 if ((blkno < 0) || ((blkno + nblks) > lp->d_partitions[part].p_size))
1576 return EINVAL;
1577
1578 /* Offset block number to start of partition. */
1579 blkno += lp->d_partitions[part].p_offset;
1580
1581 /* Recalibrate, if first dump transfer. */
1582 if (wddumprecalibrated == 0) {
1583 wddumprecalibrated = 1;
1584 (*wd->atabus->ata_reset_drive)(wd->drvp,
1585 AT_POLL | AT_RST_EMERG);
1586 wd->drvp->state = RESET;
1587 }
1588
1589 wd->sc_bp = NULL;
1590 wd->sc_wdc_bio.blkno = blkno;
1591 wd->sc_wdc_bio.flags = ATA_POLL;
1592 if (wd->sc_flags & WDF_LBA48 &&
1593 (wd->sc_wdc_bio.blkno + nblks) > wd->sc_capacity28)
1594 wd->sc_wdc_bio.flags |= ATA_LBA48;
1595 if (wd->sc_flags & WDF_LBA)
1596 wd->sc_wdc_bio.flags |= ATA_LBA;
1597 wd->sc_wdc_bio.bcount = nblks * lp->d_secsize;
1598 wd->sc_wdc_bio.databuf = va;
1599 #ifndef WD_DUMP_NOT_TRUSTED
1600 switch (wd->atabus->ata_bio(wd->drvp, &wd->sc_wdc_bio)) {
1601 case ATACMD_TRY_AGAIN:
1602 panic("wddump: try again");
1603 break;
1604 case ATACMD_QUEUED:
1605 panic("wddump: polled command has been queued");
1606 break;
1607 case ATACMD_COMPLETE:
1608 break;
1609 }
1610 switch(wd->sc_wdc_bio.error) {
1611 case TIMEOUT:
1612 printf("wddump: device timed out");
1613 err = EIO;
1614 break;
1615 case ERR_DF:
1616 printf("wddump: drive fault");
1617 err = EIO;
1618 break;
1619 case ERR_DMA:
1620 printf("wddump: DMA error");
1621 err = EIO;
1622 break;
1623 case ERROR:
1624 printf("wddump: ");
1625 wdperror(wd);
1626 err = EIO;
1627 break;
1628 case NOERROR:
1629 err = 0;
1630 break;
1631 default:
1632 panic("wddump: unknown error type");
1633 }
1634 if (err != 0) {
1635 printf("\n");
1636 return err;
1637 }
1638 #else /* WD_DUMP_NOT_TRUSTED */
1639 /* Let's just talk about this first... */
1640 printf("wd%d: dump addr 0x%x, cylin %d, head %d, sector %d\n",
1641 unit, va, cylin, head, sector);
1642 delay(500 * 1000); /* half a second */
1643 #endif
1644
1645 wddoingadump = 0;
1646 return 0;
1647 }
1648
1649 #ifdef HAS_BAD144_HANDLING
1650 /*
1651 * Internalize the bad sector table.
1652 */
1653 void
1654 bad144intern(struct wd_softc *wd)
1655 {
1656 struct dkbad *bt = &wd->sc_dk.dk_cpulabel->bad;
1657 struct disklabel *lp = wd->sc_dk.dk_label;
1658 int i = 0;
1659
1660 ATADEBUG_PRINT(("bad144intern\n"), DEBUG_XFERS);
1661
1662 for (; i < NBT_BAD; i++) {
1663 if (bt->bt_bad[i].bt_cyl == 0xffff)
1664 break;
1665 wd->sc_badsect[i] =
1666 bt->bt_bad[i].bt_cyl * lp->d_secpercyl +
1667 (bt->bt_bad[i].bt_trksec >> 8) * lp->d_nsectors +
1668 (bt->bt_bad[i].bt_trksec & 0xff);
1669 }
1670 for (; i < NBT_BAD+1; i++)
1671 wd->sc_badsect[i] = -1;
1672 }
1673 #endif
1674
1675 static void
1676 wd_params_to_properties(struct wd_softc *wd, struct ataparams *params)
1677 {
1678 prop_dictionary_t disk_info, odisk_info, geom;
1679 const char *cp;
1680
1681 disk_info = prop_dictionary_create();
1682
1683 if (strcmp(wd->sc_params.atap_model, "ST506") == 0)
1684 cp = "ST506";
1685 else {
1686 /* XXX Should have a case for ATA here, too. */
1687 cp = "ESDI";
1688 }
1689 prop_dictionary_set_cstring_nocopy(disk_info, "type", cp);
1690
1691 geom = prop_dictionary_create();
1692
1693 prop_dictionary_set_uint64(geom, "sectors-per-unit", wd->sc_capacity);
1694
1695 prop_dictionary_set_uint32(geom, "sector-size",
1696 DEV_BSIZE /* XXX 512? */);
1697
1698 prop_dictionary_set_uint16(geom, "sectors-per-track",
1699 wd->sc_params.atap_sectors);
1700
1701 prop_dictionary_set_uint16(geom, "tracks-per-cylinder",
1702 wd->sc_params.atap_heads);
1703
1704 if (wd->sc_flags & WDF_LBA)
1705 prop_dictionary_set_uint64(geom, "cylinders-per-unit",
1706 wd->sc_capacity /
1707 (wd->sc_params.atap_heads *
1708 wd->sc_params.atap_sectors));
1709 else
1710 prop_dictionary_set_uint16(geom, "cylinders-per-unit",
1711 wd->sc_params.atap_cylinders);
1712
1713 prop_dictionary_set(disk_info, "geometry", geom);
1714 prop_object_release(geom);
1715
1716 prop_dictionary_set(device_properties(wd->sc_dev),
1717 "disk-info", disk_info);
1718
1719 /*
1720 * Don't release disk_info here; we keep a reference to it.
1721 * disk_detach() will release it when we go away.
1722 */
1723
1724 odisk_info = wd->sc_dk.dk_info;
1725 wd->sc_dk.dk_info = disk_info;
1726 if (odisk_info)
1727 prop_object_release(odisk_info);
1728 }
1729
1730 int
1731 wd_get_params(struct wd_softc *wd, u_int8_t flags, struct ataparams *params)
1732 {
1733
1734 switch (wd->atabus->ata_get_params(wd->drvp, flags, params)) {
1735 case CMD_AGAIN:
1736 return 1;
1737 case CMD_ERR:
1738 /*
1739 * We `know' there's a drive here; just assume it's old.
1740 * This geometry is only used to read the MBR and print a
1741 * (false) attach message.
1742 */
1743 strncpy(params->atap_model, "ST506",
1744 sizeof params->atap_model);
1745 params->atap_config = ATA_CFG_FIXED;
1746 params->atap_cylinders = 1024;
1747 params->atap_heads = 8;
1748 params->atap_sectors = 17;
1749 params->atap_multi = 1;
1750 params->atap_capabilities1 = params->atap_capabilities2 = 0;
1751 wd->drvp->ata_vers = -1; /* Mark it as pre-ATA */
1752 /* FALLTHROUGH */
1753 case CMD_OK:
1754 wd_params_to_properties(wd, params);
1755 return 0;
1756 default:
1757 panic("wd_get_params: bad return code from ata_get_params");
1758 /* NOTREACHED */
1759 }
1760 }
1761
1762 int
1763 wd_getcache(struct wd_softc *wd, int *bitsp)
1764 {
1765 struct ataparams params;
1766
1767 if (wd_get_params(wd, AT_WAIT, ¶ms) != 0)
1768 return EIO;
1769 if (params.atap_cmd_set1 == 0x0000 ||
1770 params.atap_cmd_set1 == 0xffff ||
1771 (params.atap_cmd_set1 & WDC_CMD1_CACHE) == 0) {
1772 *bitsp = 0;
1773 return 0;
1774 }
1775 *bitsp = DKCACHE_WCHANGE | DKCACHE_READ;
1776 if (params.atap_cmd1_en & WDC_CMD1_CACHE)
1777 *bitsp |= DKCACHE_WRITE;
1778
1779 return 0;
1780 }
1781
1782 const char at_errbits[] = "\20\10ERROR\11TIMEOU\12DF";
1783
1784 int
1785 wd_setcache(struct wd_softc *wd, int bits)
1786 {
1787 struct ataparams params;
1788 struct ata_command ata_c;
1789
1790 if (wd_get_params(wd, AT_WAIT, ¶ms) != 0)
1791 return EIO;
1792
1793 if (params.atap_cmd_set1 == 0x0000 ||
1794 params.atap_cmd_set1 == 0xffff ||
1795 (params.atap_cmd_set1 & WDC_CMD1_CACHE) == 0)
1796 return EOPNOTSUPP;
1797
1798 if ((bits & DKCACHE_READ) == 0 ||
1799 (bits & DKCACHE_SAVE) != 0)
1800 return EOPNOTSUPP;
1801
1802 memset(&ata_c, 0, sizeof(struct ata_command));
1803 ata_c.r_command = SET_FEATURES;
1804 ata_c.r_st_bmask = 0;
1805 ata_c.r_st_pmask = 0;
1806 ata_c.timeout = 30000; /* 30s timeout */
1807 ata_c.flags = AT_WAIT;
1808 if (bits & DKCACHE_WRITE)
1809 ata_c.r_features = WDSF_WRITE_CACHE_EN;
1810 else
1811 ata_c.r_features = WDSF_WRITE_CACHE_DS;
1812 if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
1813 aprint_error_dev(wd->sc_dev,
1814 "wd_setcache command not complete\n");
1815 return EIO;
1816 }
1817 if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
1818 char sbuf[sizeof(at_errbits) + 64];
1819 bitmask_snprintf(ata_c.flags, at_errbits, sbuf, sizeof(sbuf));
1820 aprint_error_dev(wd->sc_dev, "wd_setcache: status=%s\n", sbuf);
1821 return EIO;
1822 }
1823 return 0;
1824 }
1825
1826 static int
1827 wd_standby(struct wd_softc *wd, int flags)
1828 {
1829 struct ata_command ata_c;
1830
1831 memset(&ata_c, 0, sizeof(struct ata_command));
1832 ata_c.r_command = WDCC_STANDBY_IMMED;
1833 ata_c.r_st_bmask = WDCS_DRDY;
1834 ata_c.r_st_pmask = WDCS_DRDY;
1835 ata_c.flags = flags;
1836 ata_c.timeout = 30000; /* 30s timeout */
1837 if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
1838 aprint_error_dev(wd->sc_dev,
1839 "standby immediate command didn't complete\n");
1840 return EIO;
1841 }
1842 if (ata_c.flags & AT_ERROR) {
1843 if (ata_c.r_error == WDCE_ABRT) /* command not supported */
1844 return ENODEV;
1845 }
1846 if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
1847 char sbuf[sizeof(at_errbits) + 64];
1848 bitmask_snprintf(ata_c.flags, at_errbits, sbuf, sizeof(sbuf));
1849 aprint_error_dev(wd->sc_dev, "wd_standby: status=%s\n", sbuf);
1850 return EIO;
1851 }
1852 return 0;
1853 }
1854
1855 int
1856 wd_flushcache(struct wd_softc *wd, int flags)
1857 {
1858 struct ata_command ata_c;
1859
1860 /*
1861 * WDCC_FLUSHCACHE is here since ATA-4, but some drives report
1862 * only ATA-2 and still support it.
1863 */
1864 if (wd->drvp->ata_vers < 4 &&
1865 ((wd->sc_params.atap_cmd_set2 & WDC_CMD2_FC) == 0 ||
1866 wd->sc_params.atap_cmd_set2 == 0xffff))
1867 return ENODEV;
1868 memset(&ata_c, 0, sizeof(struct ata_command));
1869 if ((wd->sc_params.atap_cmd2_en & ATA_CMD2_LBA48) != 0 &&
1870 (wd->sc_params.atap_cmd2_en & ATA_CMD2_FCE) != 0)
1871 ata_c.r_command = WDCC_FLUSHCACHE_EXT;
1872 else
1873 ata_c.r_command = WDCC_FLUSHCACHE;
1874 ata_c.r_st_bmask = WDCS_DRDY;
1875 ata_c.r_st_pmask = WDCS_DRDY;
1876 ata_c.flags = flags;
1877 ata_c.timeout = 30000; /* 30s timeout */
1878 if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
1879 aprint_error_dev(wd->sc_dev,
1880 "flush cache command didn't complete\n");
1881 return EIO;
1882 }
1883 if (ata_c.flags & AT_ERROR) {
1884 if (ata_c.r_error == WDCE_ABRT) /* command not supported */
1885 return ENODEV;
1886 }
1887 if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
1888 char sbuf[sizeof(at_errbits) + 64];
1889 bitmask_snprintf(ata_c.flags, at_errbits, sbuf, sizeof(sbuf));
1890 aprint_error_dev(wd->sc_dev, "wd_flushcache: status=%s\n",
1891 sbuf);
1892 return EIO;
1893 }
1894 return 0;
1895 }
1896
1897 bool
1898 wd_shutdown(device_t dev, int how)
1899 {
1900 struct wd_softc *wd = device_private(dev);
1901
1902 /* the adapter needs to be enabled */
1903 if (wd->atabus->ata_addref(wd->drvp))
1904 return true; /* no need to complain */
1905
1906 wd_flushcache(wd, AT_POLL);
1907 if ((how & RB_POWERDOWN) == RB_POWERDOWN)
1908 wd_standby(wd, AT_POLL);
1909 return true;
1910 }
1911
1912 /*
1913 * Allocate space for a ioctl queue structure. Mostly taken from
1914 * scsipi_ioctl.c
1915 */
1916 struct wd_ioctl *
1917 wi_get(void)
1918 {
1919 struct wd_ioctl *wi;
1920 int s;
1921
1922 wi = malloc(sizeof(struct wd_ioctl), M_TEMP, M_WAITOK|M_ZERO);
1923 buf_init(&wi->wi_bp);
1924 s = splbio();
1925 LIST_INSERT_HEAD(&wi_head, wi, wi_list);
1926 splx(s);
1927 return (wi);
1928 }
1929
1930 /*
1931 * Free an ioctl structure and remove it from our list
1932 */
1933
1934 void
1935 wi_free(struct wd_ioctl *wi)
1936 {
1937 int s;
1938
1939 s = splbio();
1940 LIST_REMOVE(wi, wi_list);
1941 splx(s);
1942 buf_destroy(&wi->wi_bp);
1943 free(wi, M_TEMP);
1944 }
1945
1946 /*
1947 * Find a wd_ioctl structure based on the struct buf.
1948 */
1949
1950 struct wd_ioctl *
1951 wi_find(struct buf *bp)
1952 {
1953 struct wd_ioctl *wi;
1954 int s;
1955
1956 s = splbio();
1957 for (wi = wi_head.lh_first; wi != 0; wi = wi->wi_list.le_next)
1958 if (bp == &wi->wi_bp)
1959 break;
1960 splx(s);
1961 return (wi);
1962 }
1963
1964 /*
1965 * Ioctl pseudo strategy routine
1966 *
1967 * This is mostly stolen from scsipi_ioctl.c:scsistrategy(). What
1968 * happens here is:
1969 *
1970 * - wdioctl() queues a wd_ioctl structure.
1971 *
1972 * - wdioctl() calls physio/wdioctlstrategy based on whether or not
1973 * user space I/O is required. If physio() is called, physio() eventually
1974 * calls wdioctlstrategy().
1975 *
1976 * - In either case, wdioctlstrategy() calls wd->atabus->ata_exec_command()
1977 * to perform the actual command
1978 *
1979 * The reason for the use of the pseudo strategy routine is because
1980 * when doing I/O to/from user space, physio _really_ wants to be in
1981 * the loop. We could put the entire buffer into the ioctl request
1982 * structure, but that won't scale if we want to do things like download
1983 * microcode.
1984 */
1985
1986 void
1987 wdioctlstrategy(struct buf *bp)
1988 {
1989 struct wd_ioctl *wi;
1990 struct ata_command ata_c;
1991 int error = 0;
1992
1993 wi = wi_find(bp);
1994 if (wi == NULL) {
1995 printf("wdioctlstrategy: "
1996 "No matching ioctl request found in queue\n");
1997 error = EINVAL;
1998 goto bad;
1999 }
2000
2001 memset(&ata_c, 0, sizeof(ata_c));
2002
2003 /*
2004 * Abort if physio broke up the transfer
2005 */
2006
2007 if (bp->b_bcount != wi->wi_atareq.datalen) {
2008 printf("physio split wd ioctl request... cannot proceed\n");
2009 error = EIO;
2010 goto bad;
2011 }
2012
2013 /*
2014 * Abort if we didn't get a buffer size that was a multiple of
2015 * our sector size (or was larger than NBBY)
2016 */
2017
2018 if ((bp->b_bcount % wi->wi_softc->sc_dk.dk_label->d_secsize) != 0 ||
2019 (bp->b_bcount / wi->wi_softc->sc_dk.dk_label->d_secsize) >=
2020 (1 << NBBY)) {
2021 error = EINVAL;
2022 goto bad;
2023 }
2024
2025 /*
2026 * Make sure a timeout was supplied in the ioctl request
2027 */
2028
2029 if (wi->wi_atareq.timeout == 0) {
2030 error = EINVAL;
2031 goto bad;
2032 }
2033
2034 if (wi->wi_atareq.flags & ATACMD_READ)
2035 ata_c.flags |= AT_READ;
2036 else if (wi->wi_atareq.flags & ATACMD_WRITE)
2037 ata_c.flags |= AT_WRITE;
2038
2039 if (wi->wi_atareq.flags & ATACMD_READREG)
2040 ata_c.flags |= AT_READREG;
2041
2042 ata_c.flags |= AT_WAIT;
2043
2044 ata_c.timeout = wi->wi_atareq.timeout;
2045 ata_c.r_command = wi->wi_atareq.command;
2046 ata_c.r_head = wi->wi_atareq.head & 0x0f;
2047 ata_c.r_cyl = wi->wi_atareq.cylinder;
2048 ata_c.r_sector = wi->wi_atareq.sec_num;
2049 ata_c.r_count = wi->wi_atareq.sec_count;
2050 ata_c.r_features = wi->wi_atareq.features;
2051 ata_c.r_st_bmask = WDCS_DRDY;
2052 ata_c.r_st_pmask = WDCS_DRDY;
2053 ata_c.data = wi->wi_bp.b_data;
2054 ata_c.bcount = wi->wi_bp.b_bcount;
2055
2056 if (wi->wi_softc->atabus->ata_exec_command(wi->wi_softc->drvp, &ata_c)
2057 != ATACMD_COMPLETE) {
2058 wi->wi_atareq.retsts = ATACMD_ERROR;
2059 goto bad;
2060 }
2061
2062 if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
2063 if (ata_c.flags & AT_ERROR) {
2064 wi->wi_atareq.retsts = ATACMD_ERROR;
2065 wi->wi_atareq.error = ata_c.r_error;
2066 } else if (ata_c.flags & AT_DF)
2067 wi->wi_atareq.retsts = ATACMD_DF;
2068 else
2069 wi->wi_atareq.retsts = ATACMD_TIMEOUT;
2070 } else {
2071 wi->wi_atareq.retsts = ATACMD_OK;
2072 if (wi->wi_atareq.flags & ATACMD_READREG) {
2073 wi->wi_atareq.head = ata_c.r_head ;
2074 wi->wi_atareq.cylinder = ata_c.r_cyl;
2075 wi->wi_atareq.sec_num = ata_c.r_sector;
2076 wi->wi_atareq.sec_count = ata_c.r_count;
2077 wi->wi_atareq.features = ata_c.r_features;
2078 wi->wi_atareq.error = ata_c.r_error;
2079 }
2080 }
2081
2082 bp->b_error = 0;
2083 biodone(bp);
2084 return;
2085 bad:
2086 bp->b_error = error;
2087 biodone(bp);
2088 }
2089