1 /* $OpenBSD: wd.c,v 1.73 2008/11/08 01:32:06 chl Exp $ */ 2 /* $NetBSD: wd.c,v 1.193 1999/02/28 17:15:27 explorer Exp $ */ 3 4 /* 5 * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Manuel Bouyer. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /*- 34 * Copyright (c) 1998 The NetBSD Foundation, Inc. 35 * All rights reserved. 36 * 37 * This code is derived from software contributed to The NetBSD Foundation 38 * by Charles M. Hannum and by Onno van der Linden. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 50 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 51 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 52 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 53 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 54 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 55 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 56 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 57 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 59 * POSSIBILITY OF SUCH DAMAGE. 60 */ 61 62 #if 0 63 #include "rnd.h" 64 #endif 65 66 #include <sys/param.h> 67 #include <sys/systm.h> 68 #include <sys/kernel.h> 69 #include <sys/conf.h> 70 #include <sys/file.h> 71 #include <sys/stat.h> 72 #include <sys/ioctl.h> 73 #include <sys/buf.h> 74 #include <sys/uio.h> 75 #include <sys/malloc.h> 76 #include <sys/device.h> 77 #include <sys/disklabel.h> 78 #include <sys/disk.h> 79 #include <sys/syslog.h> 80 #include <sys/proc.h> 81 #include <sys/vnode.h> 82 83 #include <uvm/uvm_extern.h> 84 85 #include <machine/intr.h> 86 #include <machine/bus.h> 87 88 #include <dev/ata/atareg.h> 89 #include <dev/ata/atavar.h> 90 #include <dev/ata/wdvar.h> 91 #include <dev/ic/wdcreg.h> 92 #include <dev/ic/wdcvar.h> 93 #if 0 94 #include "locators.h" 95 #endif 96 97 #define LBA48_THRESHOLD (0xfffffff) /* 128GB / DEV_BSIZE */ 98 99 #define WDIORETRIES_SINGLE 4 /* number of retries before single-sector */ 100 #define WDIORETRIES 5 /* number of retries before giving up */ 101 #define RECOVERYTIME hz/2 /* time to wait before retrying a cmd */ 102 103 #define DEBUG_INTR 0x01 104 #define DEBUG_XFERS 0x02 105 #define DEBUG_STATUS 0x04 106 #define DEBUG_FUNCS 0x08 107 #define DEBUG_PROBE 0x10 108 #ifdef WDCDEBUG 109 extern int wdcdebug_wd_mask; /* init'ed in ata_wdc.c */ 110 #define WDCDEBUG_PRINT(args, level) do { \ 111 if ((wdcdebug_wd_mask & (level)) != 0) \ 112 printf args; \ 113 } while (0) 114 #else 115 #define WDCDEBUG_PRINT(args, level) 116 #endif 117 118 struct wd_softc { 119 /* General disk infos */ 120 struct device sc_dev; 121 struct disk sc_dk; 122 struct buf sc_q; 123 /* IDE disk soft states */ 124 struct ata_bio sc_wdc_bio; /* current transfer */ 125 struct buf *sc_bp; /* buf being transferred */ 126 struct ata_drive_datas *drvp; /* Our controller's infos */ 127 int openings; 128 struct ataparams sc_params;/* drive characteristics found */ 129 int sc_flags; 130 #define WDF_LOCKED 0x01 131 #define WDF_WANTED 0x02 132 #define WDF_WLABEL 0x04 /* label is writable */ 133 #define WDF_LABELLING 0x08 /* writing label */ 134 /* 135 * XXX Nothing resets this yet, but disk change sensing will when ATA-4 is 136 * more fully implemented. 137 */ 138 #define WDF_LOADED 0x10 /* parameters loaded */ 139 #define WDF_WAIT 0x20 /* waiting for resources */ 140 #define WDF_LBA 0x40 /* using LBA mode */ 141 #define WDF_LBA48 0x80 /* using 48-bit LBA mode */ 142 143 u_int64_t sc_capacity; 144 int cyl; /* actual drive parameters */ 145 int heads; 146 int sectors; 147 int retries; /* number of xfer retry */ 148 struct timeout sc_restart_timeout; 149 void *sc_sdhook; 150 }; 151 152 #define sc_drive sc_wdc_bio.drive 153 #define sc_mode sc_wdc_bio.mode 154 #define sc_multi sc_wdc_bio.multi 155 156 int wdprobe(struct device *, void *, void *); 157 void wdattach(struct device *, struct device *, void *); 158 int wddetach(struct device *, int); 159 int wdactivate(struct device *, enum devact); 160 int wdprint(void *, char *); 161 162 struct cfattach wd_ca = { 163 sizeof(struct wd_softc), wdprobe, wdattach, 164 wddetach, wdactivate 165 }; 166 167 struct cfdriver wd_cd = { 168 NULL, "wd", DV_DISK 169 }; 170 171 void wdgetdefaultlabel(struct wd_softc *, struct disklabel *); 172 void wdgetdisklabel(dev_t dev, struct wd_softc *, struct disklabel *, int); 173 void wdstrategy(struct buf *); 174 void wdstart(void *); 175 void __wdstart(struct wd_softc*, struct buf *); 176 void wdrestart(void *); 177 int wd_get_params(struct wd_softc *, u_int8_t, struct ataparams *); 178 void wd_flushcache(struct wd_softc *, int); 179 void wd_shutdown(void *); 180 181 struct dkdriver wddkdriver = { wdstrategy }; 182 183 /* XXX: these should go elsewhere */ 184 cdev_decl(wd); 185 bdev_decl(wd); 186 187 #define wdlock(wd) disk_lock(&(wd)->sc_dk) 188 #define wdunlock(wd) disk_unlock(&(wd)->sc_dk) 189 #define wdlookup(unit) (struct wd_softc *)device_lookup(&wd_cd, (unit)) 190 191 192 int 193 wdprobe(struct device *parent, void *match_, void *aux) 194 { 195 struct ata_atapi_attach *aa_link = aux; 196 struct cfdata *match = match_; 197 198 if (aa_link == NULL) 199 return 0; 200 if (aa_link->aa_type != T_ATA) 201 return 0; 202 203 if (match->cf_loc[0] != -1 && 204 match->cf_loc[0] != aa_link->aa_channel) 205 return 0; 206 207 if (match->cf_loc[1] != -1 && 208 match->cf_loc[1] != aa_link->aa_drv_data->drive) 209 return 0; 210 211 return 1; 212 } 213 214 void 215 wdattach(struct device *parent, struct device *self, void *aux) 216 { 217 struct wd_softc *wd = (void *)self; 218 struct ata_atapi_attach *aa_link= aux; 219 struct wdc_command wdc_c; 220 int i, blank; 221 char buf[41], c, *p, *q; 222 WDCDEBUG_PRINT(("wdattach\n"), DEBUG_FUNCS | DEBUG_PROBE); 223 224 wd->openings = aa_link->aa_openings; 225 wd->drvp = aa_link->aa_drv_data; 226 227 strlcpy(wd->drvp->drive_name, wd->sc_dev.dv_xname, 228 sizeof(wd->drvp->drive_name)); 229 wd->drvp->cf_flags = wd->sc_dev.dv_cfdata->cf_flags; 230 231 if ((NERRS_MAX - 2) > 0) 232 wd->drvp->n_dmaerrs = NERRS_MAX - 2; 233 else 234 wd->drvp->n_dmaerrs = 0; 235 236 /* read our drive info */ 237 if (wd_get_params(wd, at_poll, &wd->sc_params) != 0) { 238 printf("%s: IDENTIFY failed\n", wd->sc_dev.dv_xname); 239 return; 240 } 241 242 for (blank = 0, p = wd->sc_params.atap_model, q = buf, i = 0; 243 i < sizeof(wd->sc_params.atap_model); i++) { 244 c = *p++; 245 if (c == '\0') 246 break; 247 if (c != ' ') { 248 if (blank) { 249 *q++ = ' '; 250 blank = 0; 251 } 252 *q++ = c; 253 } else 254 blank = 1; 255 } 256 *q++ = '\0'; 257 258 printf(": <%s>\n", buf); 259 260 wdc_probe_caps(wd->drvp, &wd->sc_params); 261 wdc_print_caps(wd->drvp); 262 263 if ((wd->sc_params.atap_multi & 0xff) > 1) { 264 wd->sc_multi = wd->sc_params.atap_multi & 0xff; 265 } else { 266 wd->sc_multi = 1; 267 } 268 269 printf("%s: %d-sector PIO,", wd->sc_dev.dv_xname, wd->sc_multi); 270 271 /* use 48-bit LBA if enabled */ 272 /* XXX: shall we use it if drive capacity < 137Gb? */ 273 if ((wd->sc_params.atap_cmd2_en & ATAPI_CMD2_48AD) != 0) 274 wd->sc_flags |= WDF_LBA48; 275 276 /* Prior to ATA-4, LBA was optional. */ 277 if ((wd->sc_params.atap_capabilities1 & WDC_CAP_LBA) != 0) 278 wd->sc_flags |= WDF_LBA; 279 #if 0 280 /* ATA-4 requires LBA. */ 281 if (wd->sc_params.atap_ataversion != 0xffff && 282 wd->sc_params.atap_ataversion >= WDC_VER_ATA4) 283 wd->sc_flags |= WDF_LBA; 284 #endif 285 286 if ((wd->sc_flags & WDF_LBA48) != 0) { 287 wd->sc_capacity = 288 (((u_int64_t)wd->sc_params.atap_max_lba[3] << 48) | 289 ((u_int64_t)wd->sc_params.atap_max_lba[2] << 32) | 290 ((u_int64_t)wd->sc_params.atap_max_lba[1] << 16) | 291 (u_int64_t)wd->sc_params.atap_max_lba[0]); 292 printf(" LBA48, %lluMB, %llu sectors\n", 293 wd->sc_capacity / (1048576 / DEV_BSIZE), 294 wd->sc_capacity); 295 } else if ((wd->sc_flags & WDF_LBA) != 0) { 296 wd->sc_capacity = 297 (wd->sc_params.atap_capacity[1] << 16) | 298 wd->sc_params.atap_capacity[0]; 299 printf(" LBA, %lluMB, %llu sectors\n", 300 wd->sc_capacity / (1048576 / DEV_BSIZE), 301 wd->sc_capacity); 302 } else { 303 wd->sc_capacity = 304 wd->sc_params.atap_cylinders * 305 wd->sc_params.atap_heads * 306 wd->sc_params.atap_sectors; 307 printf(" CHS, %lluMB, %d cyl, %d head, %d sec, %llu sectors\n", 308 wd->sc_capacity / (1048576 / DEV_BSIZE), 309 wd->sc_params.atap_cylinders, 310 wd->sc_params.atap_heads, 311 wd->sc_params.atap_sectors, 312 wd->sc_capacity); 313 } 314 WDCDEBUG_PRINT(("%s: atap_dmatiming_mimi=%d, atap_dmatiming_recom=%d\n", 315 self->dv_xname, wd->sc_params.atap_dmatiming_mimi, 316 wd->sc_params.atap_dmatiming_recom), DEBUG_PROBE); 317 318 /* use read look ahead if supported */ 319 if (wd->sc_params.atap_cmd_set1 & WDC_CMD1_AHEAD) { 320 bzero(&wdc_c, sizeof(struct wdc_command)); 321 wdc_c.r_command = SET_FEATURES; 322 wdc_c.r_precomp = WDSF_READAHEAD_EN; 323 wdc_c.timeout = 1000; 324 wdc_c.flags = at_poll; 325 326 if (wdc_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) { 327 printf("%s: enable look ahead command didn't " 328 "complete\n", wd->sc_dev.dv_xname); 329 } 330 } 331 332 /* use write cache if supported */ 333 if (wd->sc_params.atap_cmd_set1 & WDC_CMD1_CACHE) { 334 bzero(&wdc_c, sizeof(struct wdc_command)); 335 wdc_c.r_command = SET_FEATURES; 336 wdc_c.r_precomp = WDSF_EN_WR_CACHE; 337 wdc_c.timeout = 1000; 338 wdc_c.flags = at_poll; 339 340 if (wdc_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) { 341 printf("%s: enable write cache command didn't " 342 "complete\n", wd->sc_dev.dv_xname); 343 } 344 } 345 346 /* 347 * FREEZE LOCK the drive so malicous users can't lock it on us. 348 * As there is no harm in issuing this to drives that don't 349 * support the security feature set we just send it, and don't 350 * bother checking if the drive sends a command abort to tell us it 351 * doesn't support it. 352 */ 353 bzero(&wdc_c, sizeof(struct wdc_command)); 354 355 wdc_c.r_command = WDCC_SEC_FREEZE_LOCK; 356 wdc_c.timeout = 1000; 357 wdc_c.flags = at_poll; 358 if (wdc_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) { 359 printf("%s: freeze lock command didn't complete\n", 360 wd->sc_dev.dv_xname); 361 } 362 363 /* 364 * Initialize and attach the disk structure. 365 */ 366 wd->sc_dk.dk_driver = &wddkdriver; 367 wd->sc_dk.dk_name = wd->sc_dev.dv_xname; 368 disk_attach(&wd->sc_dk); 369 wd->sc_wdc_bio.lp = wd->sc_dk.dk_label; 370 wd->sc_sdhook = shutdownhook_establish(wd_shutdown, wd); 371 if (wd->sc_sdhook == NULL) 372 printf("%s: WARNING: unable to establish shutdown hook\n", 373 wd->sc_dev.dv_xname); 374 timeout_set(&wd->sc_restart_timeout, wdrestart, wd); 375 } 376 377 int 378 wdactivate(struct device *self, enum devact act) 379 { 380 int rv = 0; 381 382 switch (act) { 383 case DVACT_ACTIVATE: 384 break; 385 386 case DVACT_DEACTIVATE: 387 /* 388 * Nothing to do; we key off the device's DVF_ACTIVATE. 389 */ 390 break; 391 } 392 return (rv); 393 } 394 395 int 396 wddetach(struct device *self, int flags) 397 { 398 struct wd_softc *sc = (struct wd_softc *)self; 399 struct buf *dp, *bp; 400 int s, bmaj, cmaj, mn; 401 402 /* Remove unprocessed buffers from queue */ 403 s = splbio(); 404 for (dp = &sc->sc_q; (bp = dp->b_actf) != NULL; ) { 405 dp->b_actf = bp->b_actf; 406 bp->b_error = ENXIO; 407 bp->b_flags |= B_ERROR; 408 biodone(bp); 409 } 410 splx(s); 411 412 /* Locate the lowest minor number to be detached. */ 413 mn = DISKMINOR(self->dv_unit, 0); 414 415 for (bmaj = 0; bmaj < nblkdev; bmaj++) 416 if (bdevsw[bmaj].d_open == wdopen) 417 vdevgone(bmaj, mn, mn + MAXPARTITIONS - 1, VBLK); 418 for (cmaj = 0; cmaj < nchrdev; cmaj++) 419 if (cdevsw[cmaj].d_open == wdopen) 420 vdevgone(cmaj, mn, mn + MAXPARTITIONS - 1, VCHR); 421 422 /* Get rid of the shutdown hook. */ 423 if (sc->sc_sdhook != NULL) 424 shutdownhook_disestablish(sc->sc_sdhook); 425 426 /* Detach disk. */ 427 disk_detach(&sc->sc_dk); 428 429 return (0); 430 } 431 432 /* 433 * Read/write routine for a buffer. Validates the arguments and schedules the 434 * transfer. Does not wait for the transfer to complete. 435 */ 436 void 437 wdstrategy(struct buf *bp) 438 { 439 struct wd_softc *wd; 440 int s; 441 442 wd = wdlookup(DISKUNIT(bp->b_dev)); 443 if (wd == NULL) { 444 bp->b_error = ENXIO; 445 goto bad; 446 } 447 448 WDCDEBUG_PRINT(("wdstrategy (%s)\n", wd->sc_dev.dv_xname), 449 DEBUG_XFERS); 450 451 /* Valid request? */ 452 if (bp->b_blkno < 0 || 453 (bp->b_bcount % wd->sc_dk.dk_label->d_secsize) != 0 || 454 (bp->b_bcount / wd->sc_dk.dk_label->d_secsize) >= (1 << NBBY)) { 455 bp->b_error = EINVAL; 456 goto bad; 457 } 458 459 /* If device invalidated (e.g. media change, door open), error. */ 460 if ((wd->sc_flags & WDF_LOADED) == 0) { 461 bp->b_error = EIO; 462 goto bad; 463 } 464 465 /* If it's a null transfer, return immediately. */ 466 if (bp->b_bcount == 0) 467 goto done; 468 469 /* 470 * Do bounds checking, adjust transfer. if error, process. 471 * If end of partition, just return. 472 */ 473 if (bounds_check_with_label(bp, wd->sc_dk.dk_label, 474 (wd->sc_flags & (WDF_WLABEL|WDF_LABELLING)) != 0) <= 0) 475 goto done; 476 /* Queue transfer on drive, activate drive and controller if idle. */ 477 s = splbio(); 478 disksort(&wd->sc_q, bp); 479 wdstart(wd); 480 splx(s); 481 device_unref(&wd->sc_dev); 482 return; 483 bad: 484 bp->b_flags |= B_ERROR; 485 done: 486 /* Toss transfer; we're done early. */ 487 bp->b_resid = bp->b_bcount; 488 s = splbio(); 489 biodone(bp); 490 splx(s); 491 if (wd != NULL) 492 device_unref(&wd->sc_dev); 493 } 494 495 /* 496 * Queue a drive for I/O. 497 */ 498 void 499 wdstart(void *arg) 500 { 501 struct wd_softc *wd = arg; 502 struct buf *dp, *bp = NULL; 503 504 WDCDEBUG_PRINT(("wdstart %s\n", wd->sc_dev.dv_xname), 505 DEBUG_XFERS); 506 while (wd->openings > 0) { 507 508 /* Is there a buf for us ? */ 509 dp = &wd->sc_q; 510 if ((bp = dp->b_actf) == NULL) /* yes, an assign */ 511 return; 512 dp->b_actf = bp->b_actf; 513 514 /* 515 * Make the command. First lock the device 516 */ 517 wd->openings--; 518 519 wd->retries = 0; 520 __wdstart(wd, bp); 521 } 522 } 523 524 void 525 __wdstart(struct wd_softc *wd, struct buf *bp) 526 { 527 daddr64_t nblks; 528 529 wd->sc_wdc_bio.blkno = bp->b_blkno + 530 DL_GETPOFFSET(&wd->sc_dk.dk_label->d_partitions[DISKPART(bp->b_dev)]); 531 wd->sc_wdc_bio.blkno /= (wd->sc_dk.dk_label->d_secsize / DEV_BSIZE); 532 wd->sc_wdc_bio.blkdone =0; 533 wd->sc_bp = bp; 534 /* 535 * If we're retrying, retry in single-sector mode. This will give us 536 * the sector number of the problem, and will eventually allow the 537 * transfer to succeed. 538 */ 539 if (wd->retries >= WDIORETRIES_SINGLE) 540 wd->sc_wdc_bio.flags = ATA_SINGLE; 541 else 542 wd->sc_wdc_bio.flags = 0; 543 nblks = bp->b_bcount / wd->sc_dk.dk_label->d_secsize; 544 if ((wd->sc_flags & WDF_LBA48) && 545 /* use LBA48 only if really need */ 546 ((wd->sc_wdc_bio.blkno + nblks - 1 > LBA48_THRESHOLD) || 547 (nblks > 0xff))) 548 wd->sc_wdc_bio.flags |= ATA_LBA48; 549 if (wd->sc_flags & WDF_LBA) 550 wd->sc_wdc_bio.flags |= ATA_LBA; 551 if (bp->b_flags & B_READ) 552 wd->sc_wdc_bio.flags |= ATA_READ; 553 wd->sc_wdc_bio.bcount = bp->b_bcount; 554 wd->sc_wdc_bio.databuf = bp->b_data; 555 wd->sc_wdc_bio.wd = wd; 556 /* Instrumentation. */ 557 disk_busy(&wd->sc_dk); 558 switch (wdc_ata_bio(wd->drvp, &wd->sc_wdc_bio)) { 559 case WDC_TRY_AGAIN: 560 timeout_add_sec(&wd->sc_restart_timeout, 1); 561 break; 562 case WDC_QUEUED: 563 break; 564 case WDC_COMPLETE: 565 /* 566 * This code is never executed because we never set 567 * the ATA_POLL flag above 568 */ 569 #if 0 570 if (wd->sc_wdc_bio.flags & ATA_POLL) 571 wddone(wd); 572 #endif 573 break; 574 default: 575 panic("__wdstart: bad return code from wdc_ata_bio()"); 576 } 577 } 578 579 void 580 wddone(void *v) 581 { 582 struct wd_softc *wd = v; 583 struct buf *bp = wd->sc_bp; 584 char buf[256], *errbuf = buf; 585 WDCDEBUG_PRINT(("wddone %s\n", wd->sc_dev.dv_xname), 586 DEBUG_XFERS); 587 588 bp->b_resid = wd->sc_wdc_bio.bcount; 589 errbuf[0] = '\0'; 590 switch (wd->sc_wdc_bio.error) { 591 case ERR_NODEV: 592 bp->b_flags |= B_ERROR; 593 bp->b_error = ENXIO; 594 break; 595 case ERR_DMA: 596 errbuf = "DMA error"; 597 goto retry; 598 case ERR_DF: 599 errbuf = "device fault"; 600 goto retry; 601 case TIMEOUT: 602 errbuf = "device timeout"; 603 goto retry; 604 case ERROR: 605 /* Don't care about media change bits */ 606 if (wd->sc_wdc_bio.r_error != 0 && 607 (wd->sc_wdc_bio.r_error & ~(WDCE_MC | WDCE_MCR)) == 0) 608 goto noerror; 609 ata_perror(wd->drvp, wd->sc_wdc_bio.r_error, errbuf, 610 sizeof buf); 611 retry: 612 /* Just reset and retry. Can we do more ? */ 613 wdc_reset_channel(wd->drvp); 614 diskerr(bp, "wd", errbuf, LOG_PRINTF, 615 wd->sc_wdc_bio.blkdone, wd->sc_dk.dk_label); 616 if (wd->retries++ < WDIORETRIES) { 617 printf(", retrying\n"); 618 timeout_add(&wd->sc_restart_timeout, RECOVERYTIME); 619 return; 620 } 621 printf("\n"); 622 bp->b_flags |= B_ERROR; 623 bp->b_error = EIO; 624 break; 625 case NOERROR: 626 noerror: if ((wd->sc_wdc_bio.flags & ATA_CORR) || wd->retries > 0) 627 printf("%s: soft error (corrected)\n", 628 wd->sc_dev.dv_xname); 629 } 630 disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid), 631 (bp->b_flags & B_READ)); 632 biodone(bp); 633 wd->openings++; 634 wdstart(wd); 635 } 636 637 void 638 wdrestart(void *v) 639 { 640 struct wd_softc *wd = v; 641 struct buf *bp = wd->sc_bp; 642 int s; 643 WDCDEBUG_PRINT(("wdrestart %s\n", wd->sc_dev.dv_xname), 644 DEBUG_XFERS); 645 646 s = splbio(); 647 disk_unbusy(&wd->sc_dk, 0, (bp->b_flags & B_READ)); 648 __wdstart(v, bp); 649 splx(s); 650 } 651 652 int 653 wdread(dev_t dev, struct uio *uio, int flags) 654 { 655 656 WDCDEBUG_PRINT(("wdread\n"), DEBUG_XFERS); 657 return (physio(wdstrategy, NULL, dev, B_READ, minphys, uio)); 658 } 659 660 int 661 wdwrite(dev_t dev, struct uio *uio, int flags) 662 { 663 664 WDCDEBUG_PRINT(("wdwrite\n"), DEBUG_XFERS); 665 return (physio(wdstrategy, NULL, dev, B_WRITE, minphys, uio)); 666 } 667 668 int 669 wdopen(dev_t dev, int flag, int fmt, struct proc *p) 670 { 671 struct wd_softc *wd; 672 int unit, part; 673 int error; 674 675 WDCDEBUG_PRINT(("wdopen\n"), DEBUG_FUNCS); 676 677 unit = DISKUNIT(dev); 678 wd = wdlookup(unit); 679 if (wd == NULL) 680 return ENXIO; 681 682 /* 683 * If this is the first open of this device, add a reference 684 * to the adapter. 685 */ 686 if ((error = wdlock(wd)) != 0) 687 goto bad4; 688 689 if (wd->sc_dk.dk_openmask != 0) { 690 /* 691 * If any partition is open, but the disk has been invalidated, 692 * disallow further opens. 693 */ 694 if ((wd->sc_flags & WDF_LOADED) == 0) { 695 error = EIO; 696 goto bad3; 697 } 698 } else { 699 if ((wd->sc_flags & WDF_LOADED) == 0) { 700 wd->sc_flags |= WDF_LOADED; 701 702 /* Load the physical device parameters. */ 703 wd_get_params(wd, AT_WAIT, &wd->sc_params); 704 705 /* Load the partition info if not already loaded. */ 706 wdgetdisklabel(dev, wd, wd->sc_dk.dk_label, 0); 707 } 708 } 709 710 part = DISKPART(dev); 711 712 /* Check that the partition exists. */ 713 if (part != RAW_PART && 714 (part >= wd->sc_dk.dk_label->d_npartitions || 715 wd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) { 716 error = ENXIO; 717 goto bad; 718 } 719 720 /* Insure only one open at a time. */ 721 switch (fmt) { 722 case S_IFCHR: 723 wd->sc_dk.dk_copenmask |= (1 << part); 724 break; 725 case S_IFBLK: 726 wd->sc_dk.dk_bopenmask |= (1 << part); 727 break; 728 } 729 wd->sc_dk.dk_openmask = 730 wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask; 731 732 wdunlock(wd); 733 device_unref(&wd->sc_dev); 734 return 0; 735 736 bad: 737 if (wd->sc_dk.dk_openmask == 0) { 738 } 739 740 bad3: 741 wdunlock(wd); 742 bad4: 743 device_unref(&wd->sc_dev); 744 return error; 745 } 746 747 int 748 wdclose(dev_t dev, int flag, int fmt, struct proc *p) 749 { 750 struct wd_softc *wd; 751 int part = DISKPART(dev); 752 int error = 0; 753 754 wd = wdlookup(DISKUNIT(dev)); 755 if (wd == NULL) 756 return ENXIO; 757 758 WDCDEBUG_PRINT(("wdclose\n"), DEBUG_FUNCS); 759 if ((error = wdlock(wd)) != 0) 760 goto exit; 761 762 switch (fmt) { 763 case S_IFCHR: 764 wd->sc_dk.dk_copenmask &= ~(1 << part); 765 break; 766 case S_IFBLK: 767 wd->sc_dk.dk_bopenmask &= ~(1 << part); 768 break; 769 } 770 wd->sc_dk.dk_openmask = 771 wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask; 772 773 if (wd->sc_dk.dk_openmask == 0) { 774 wd_flushcache(wd, 0); 775 /* XXXX Must wait for I/O to complete! */ 776 } 777 778 wdunlock(wd); 779 780 exit: 781 device_unref(&wd->sc_dev); 782 return (error); 783 } 784 785 void 786 wdgetdefaultlabel(struct wd_softc *wd, struct disklabel *lp) 787 { 788 WDCDEBUG_PRINT(("wdgetdefaultlabel\n"), DEBUG_FUNCS); 789 bzero(lp, sizeof(struct disklabel)); 790 791 lp->d_secsize = DEV_BSIZE; 792 DL_SETDSIZE(lp, wd->sc_capacity); 793 lp->d_ntracks = wd->sc_params.atap_heads; 794 lp->d_nsectors = wd->sc_params.atap_sectors; 795 lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors; 796 lp->d_ncylinders = DL_GETDSIZE(lp) / lp->d_secpercyl; 797 if (wd->drvp->ata_vers == -1) { 798 lp->d_type = DTYPE_ST506; 799 strncpy(lp->d_typename, "ST506/MFM/RLL", sizeof lp->d_typename); 800 } else { 801 lp->d_type = DTYPE_ESDI; 802 strncpy(lp->d_typename, "ESDI/IDE disk", sizeof lp->d_typename); 803 } 804 /* XXX - user viscopy() like sd.c */ 805 strncpy(lp->d_packname, wd->sc_params.atap_model, sizeof lp->d_packname); 806 lp->d_rpm = 3600; 807 lp->d_interleave = 1; 808 lp->d_flags = 0; 809 lp->d_version = 1; 810 811 lp->d_magic = DISKMAGIC; 812 lp->d_magic2 = DISKMAGIC; 813 lp->d_checksum = dkcksum(lp); 814 } 815 816 /* 817 * Fabricate a default disk label, and try to read the correct one. 818 */ 819 void 820 wdgetdisklabel(dev_t dev, struct wd_softc *wd, struct disklabel *lp, 821 int spoofonly) 822 { 823 char *errstring; 824 825 WDCDEBUG_PRINT(("wdgetdisklabel\n"), DEBUG_FUNCS); 826 827 wdgetdefaultlabel(wd, lp); 828 829 if (wd->drvp->state > RECAL) 830 wd->drvp->drive_flags |= DRIVE_RESET; 831 errstring = readdisklabel(DISKLABELDEV(dev), wdstrategy, lp, 832 spoofonly); 833 if (wd->drvp->state > RECAL) 834 wd->drvp->drive_flags |= DRIVE_RESET; 835 if (errstring) { 836 /*printf("%s: %s\n", wd->sc_dev.dv_xname, errstring);*/ 837 } 838 } 839 840 int 841 wdioctl(dev_t dev, u_long xfer, caddr_t addr, int flag, struct proc *p) 842 { 843 struct wd_softc *wd; 844 struct disklabel *lp; 845 int error = 0; 846 847 WDCDEBUG_PRINT(("wdioctl\n"), DEBUG_FUNCS); 848 849 wd = wdlookup(DISKUNIT(dev)); 850 if (wd == NULL) 851 return ENXIO; 852 853 if ((wd->sc_flags & WDF_LOADED) == 0) { 854 error = EIO; 855 goto exit; 856 } 857 858 switch (xfer) { 859 case DIOCRLDINFO: 860 lp = malloc(sizeof(*lp), M_TEMP, M_WAITOK); 861 wdgetdisklabel(dev, wd, lp, 0); 862 bcopy(lp, wd->sc_dk.dk_label, sizeof(*lp)); 863 free(lp, M_TEMP); 864 goto exit; 865 866 case DIOCGPDINFO: 867 wdgetdisklabel(dev, wd, (struct disklabel *)addr, 1); 868 goto exit; 869 870 case DIOCGDINFO: 871 *(struct disklabel *)addr = *(wd->sc_dk.dk_label); 872 goto exit; 873 874 case DIOCGPART: 875 ((struct partinfo *)addr)->disklab = wd->sc_dk.dk_label; 876 ((struct partinfo *)addr)->part = 877 &wd->sc_dk.dk_label->d_partitions[DISKPART(dev)]; 878 goto exit; 879 880 case DIOCWDINFO: 881 case DIOCSDINFO: 882 if ((flag & FWRITE) == 0) { 883 error = EBADF; 884 goto exit; 885 } 886 887 if ((error = wdlock(wd)) != 0) 888 goto exit; 889 wd->sc_flags |= WDF_LABELLING; 890 891 error = setdisklabel(wd->sc_dk.dk_label, 892 (struct disklabel *)addr, /*wd->sc_dk.dk_openmask : */0); 893 if (error == 0) { 894 if (wd->drvp->state > RECAL) 895 wd->drvp->drive_flags |= DRIVE_RESET; 896 if (xfer == DIOCWDINFO) 897 error = writedisklabel(DISKLABELDEV(dev), 898 wdstrategy, wd->sc_dk.dk_label); 899 } 900 901 wd->sc_flags &= ~WDF_LABELLING; 902 wdunlock(wd); 903 goto exit; 904 905 case DIOCWLABEL: 906 if ((flag & FWRITE) == 0) { 907 error = EBADF; 908 goto exit; 909 } 910 911 if (*(int *)addr) 912 wd->sc_flags |= WDF_WLABEL; 913 else 914 wd->sc_flags &= ~WDF_WLABEL; 915 goto exit; 916 917 #ifdef notyet 918 case DIOCWFORMAT: 919 if ((flag & FWRITE) == 0) 920 return EBADF; 921 { 922 struct format_op *fop; 923 struct iovec aiov; 924 struct uio auio; 925 926 fop = (struct format_op *)addr; 927 aiov.iov_base = fop->df_buf; 928 aiov.iov_len = fop->df_count; 929 auio.uio_iov = &aiov; 930 auio.uio_iovcnt = 1; 931 auio.uio_resid = fop->df_count; 932 auio.uio_segflg = 0; 933 auio.uio_offset = 934 fop->df_startblk * wd->sc_dk.dk_label->d_secsize; 935 auio.uio_procp = p; 936 error = physio(wdformat, NULL, dev, B_WRITE, minphys, 937 &auio); 938 fop->df_count -= auio.uio_resid; 939 fop->df_reg[0] = wdc->sc_status; 940 fop->df_reg[1] = wdc->sc_error; 941 goto exit; 942 } 943 #endif 944 945 default: 946 error = wdc_ioctl(wd->drvp, xfer, addr, flag, p); 947 goto exit; 948 } 949 950 #ifdef DIAGNOSTIC 951 panic("wdioctl: impossible"); 952 #endif 953 954 exit: 955 device_unref(&wd->sc_dev); 956 return (error); 957 } 958 959 #ifdef B_FORMAT 960 int 961 wdformat(struct buf *bp) 962 { 963 964 bp->b_flags |= B_FORMAT; 965 return wdstrategy(bp); 966 } 967 #endif 968 969 daddr64_t 970 wdsize(dev_t dev) 971 { 972 struct wd_softc *wd; 973 int part, omask; 974 int64_t size; 975 976 WDCDEBUG_PRINT(("wdsize\n"), DEBUG_FUNCS); 977 978 wd = wdlookup(DISKUNIT(dev)); 979 if (wd == NULL) 980 return (-1); 981 982 part = DISKPART(dev); 983 omask = wd->sc_dk.dk_openmask & (1 << part); 984 985 if (omask == 0 && wdopen(dev, 0, S_IFBLK, NULL) != 0) { 986 size = -1; 987 goto exit; 988 } 989 990 size = DL_GETPSIZE(&wd->sc_dk.dk_label->d_partitions[part]) * 991 (wd->sc_dk.dk_label->d_secsize / DEV_BSIZE); 992 if (omask == 0 && wdclose(dev, 0, S_IFBLK, NULL) != 0) 993 size = -1; 994 995 exit: 996 device_unref(&wd->sc_dev); 997 return (size); 998 } 999 1000 /* #define WD_DUMP_NOT_TRUSTED if you just want to watch */ 1001 static int wddoingadump = 0; 1002 static int wddumprecalibrated = 0; 1003 static int wddumpmulti = 1; 1004 1005 /* 1006 * Dump core after a system crash. 1007 */ 1008 int 1009 wddump(dev_t dev, daddr64_t blkno, caddr_t va, size_t size) 1010 { 1011 struct wd_softc *wd; /* disk unit to do the I/O */ 1012 struct disklabel *lp; /* disk's disklabel */ 1013 int unit, part; 1014 int nblks; /* total number of sectors left to write */ 1015 int err; 1016 char errbuf[256]; 1017 1018 /* Check if recursive dump; if so, punt. */ 1019 if (wddoingadump) 1020 return EFAULT; 1021 wddoingadump = 1; 1022 1023 unit = DISKUNIT(dev); 1024 wd = wdlookup(unit); 1025 if (wd == NULL) 1026 return ENXIO; 1027 1028 part = DISKPART(dev); 1029 1030 /* Make sure it was initialized. */ 1031 if (wd->drvp->state < READY) 1032 return ENXIO; 1033 1034 /* Convert to disk sectors. Request must be a multiple of size. */ 1035 lp = wd->sc_dk.dk_label; 1036 if ((size % lp->d_secsize) != 0) 1037 return EFAULT; 1038 nblks = size / lp->d_secsize; 1039 blkno = blkno / (lp->d_secsize / DEV_BSIZE); 1040 1041 /* Check transfer bounds against partition size. */ 1042 if ((blkno < 0) || ((blkno + nblks) > DL_GETPSIZE(&lp->d_partitions[part]))) 1043 return EINVAL; 1044 1045 /* Offset block number to start of partition. */ 1046 blkno += DL_GETPOFFSET(&lp->d_partitions[part]); 1047 1048 /* Recalibrate, if first dump transfer. */ 1049 if (wddumprecalibrated == 0) { 1050 wddumpmulti = wd->sc_multi; 1051 wddumprecalibrated = 1; 1052 wd->drvp->state = RECAL; 1053 } 1054 1055 while (nblks > 0) { 1056 wd->sc_wdc_bio.blkno = blkno; 1057 wd->sc_wdc_bio.flags = ATA_POLL; 1058 if (wd->sc_flags & WDF_LBA48) 1059 wd->sc_wdc_bio.flags |= ATA_LBA48; 1060 if (wd->sc_flags & WDF_LBA) 1061 wd->sc_wdc_bio.flags |= ATA_LBA; 1062 wd->sc_wdc_bio.bcount = 1063 min(nblks, wddumpmulti) * lp->d_secsize; 1064 wd->sc_wdc_bio.databuf = va; 1065 wd->sc_wdc_bio.wd = wd; 1066 #ifndef WD_DUMP_NOT_TRUSTED 1067 switch (wdc_ata_bio(wd->drvp, &wd->sc_wdc_bio)) { 1068 case WDC_TRY_AGAIN: 1069 panic("wddump: try again"); 1070 break; 1071 case WDC_QUEUED: 1072 panic("wddump: polled command has been queued"); 1073 break; 1074 case WDC_COMPLETE: 1075 break; 1076 } 1077 switch(wd->sc_wdc_bio.error) { 1078 case TIMEOUT: 1079 printf("wddump: device timed out"); 1080 err = EIO; 1081 break; 1082 case ERR_DF: 1083 printf("wddump: drive fault"); 1084 err = EIO; 1085 break; 1086 case ERR_DMA: 1087 printf("wddump: DMA error"); 1088 err = EIO; 1089 break; 1090 case ERROR: 1091 errbuf[0] = '\0'; 1092 ata_perror(wd->drvp, wd->sc_wdc_bio.r_error, errbuf, 1093 sizeof errbuf); 1094 printf("wddump: %s", errbuf); 1095 err = EIO; 1096 break; 1097 case NOERROR: 1098 err = 0; 1099 break; 1100 default: 1101 panic("wddump: unknown error type"); 1102 } 1103 if (err != 0) { 1104 printf("\n"); 1105 return err; 1106 } 1107 #else /* WD_DUMP_NOT_TRUSTED */ 1108 /* Let's just talk about this first... */ 1109 printf("wd%d: dump addr 0x%x, cylin %d, head %d, sector %d\n", 1110 unit, va, cylin, head, sector); 1111 delay(500 * 1000); /* half a second */ 1112 #endif 1113 1114 /* update block count */ 1115 nblks -= min(nblks, wddumpmulti); 1116 blkno += min(nblks, wddumpmulti); 1117 va += min(nblks, wddumpmulti) * lp->d_secsize; 1118 } 1119 1120 wddoingadump = 0; 1121 return 0; 1122 } 1123 1124 int 1125 wd_get_params(struct wd_softc *wd, u_int8_t flags, struct ataparams *params) 1126 { 1127 switch (ata_get_params(wd->drvp, flags, params)) { 1128 case CMD_AGAIN: 1129 return 1; 1130 case CMD_ERR: 1131 /* If we already have drive parameters, reuse them. */ 1132 if (wd->sc_params.atap_cylinders != 0) { 1133 if (params != &wd->sc_params) 1134 bcopy(&wd->sc_params, params, 1135 sizeof(struct ataparams)); 1136 return 0; 1137 } 1138 /* 1139 * We `know' there's a drive here; just assume it's old. 1140 * This geometry is only used to read the MBR and print a 1141 * (false) attach message. 1142 */ 1143 bzero(params, sizeof(struct ataparams)); 1144 strncpy(params->atap_model, "ST506", 1145 sizeof params->atap_model); 1146 params->atap_config = ATA_CFG_FIXED; 1147 params->atap_cylinders = 1024; 1148 params->atap_heads = 8; 1149 params->atap_sectors = 17; 1150 params->atap_multi = 1; 1151 params->atap_capabilities1 = params->atap_capabilities2 = 0; 1152 wd->drvp->ata_vers = -1; /* Mark it as pre-ATA */ 1153 return 0; 1154 case CMD_OK: 1155 return 0; 1156 default: 1157 panic("wd_get_params: bad return code from ata_get_params"); 1158 /* NOTREACHED */ 1159 } 1160 } 1161 1162 void 1163 wd_flushcache(struct wd_softc *wd, int flags) 1164 { 1165 struct wdc_command wdc_c; 1166 1167 if (wd->drvp->ata_vers < 4) /* WDCC_FLUSHCACHE is here since ATA-4 */ 1168 return; 1169 bzero(&wdc_c, sizeof(struct wdc_command)); 1170 wdc_c.r_command = (wd->sc_flags & WDF_LBA48 ? WDCC_FLUSHCACHE_EXT : 1171 WDCC_FLUSHCACHE); 1172 wdc_c.r_st_bmask = WDCS_DRDY; 1173 wdc_c.r_st_pmask = WDCS_DRDY; 1174 if (flags != 0) { 1175 wdc_c.flags = AT_POLL; 1176 } else { 1177 wdc_c.flags = AT_WAIT; 1178 } 1179 wdc_c.timeout = 30000; /* 30s timeout */ 1180 if (wdc_exec_command(wd->drvp, &wdc_c) != WDC_COMPLETE) { 1181 printf("%s: flush cache command didn't complete\n", 1182 wd->sc_dev.dv_xname); 1183 } 1184 if (wdc_c.flags & AT_TIMEOU) { 1185 printf("%s: flush cache command timeout\n", 1186 wd->sc_dev.dv_xname); 1187 } 1188 if (wdc_c.flags & AT_DF) { 1189 printf("%s: flush cache command: drive fault\n", 1190 wd->sc_dev.dv_xname); 1191 } 1192 /* 1193 * Ignore error register, it shouldn't report anything else 1194 * than COMMAND ABORTED, which means the device doesn't support 1195 * flush cache 1196 */ 1197 } 1198 1199 void 1200 wd_shutdown(void *arg) 1201 { 1202 struct wd_softc *wd = arg; 1203 wd_flushcache(wd, AT_POLL); 1204 } 1205