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