1 /* $NetBSD: ld.c,v 1.111 2020/08/02 01:17:56 riastradh Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran and Charles M. Hannum. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Disk driver for use by RAID controllers. 34 */ 35 36 #include <sys/cdefs.h> 37 __KERNEL_RCSID(0, "$NetBSD: ld.c,v 1.111 2020/08/02 01:17:56 riastradh Exp $"); 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/kernel.h> 42 #include <sys/device.h> 43 #include <sys/queue.h> 44 #include <sys/proc.h> 45 #include <sys/buf.h> 46 #include <sys/bufq.h> 47 #include <sys/endian.h> 48 #include <sys/disklabel.h> 49 #include <sys/disk.h> 50 #include <sys/dkio.h> 51 #include <sys/stat.h> 52 #include <sys/conf.h> 53 #include <sys/fcntl.h> 54 #include <sys/vnode.h> 55 #include <sys/syslog.h> 56 #include <sys/mutex.h> 57 #include <sys/module.h> 58 #include <sys/reboot.h> 59 60 #include <dev/ldvar.h> 61 62 #include "ioconf.h" 63 64 static void ldminphys(struct buf *bp); 65 static bool ld_suspend(device_t, const pmf_qual_t *); 66 static bool ld_shutdown(device_t, int); 67 static int ld_diskstart(device_t, struct buf *bp); 68 static void ld_iosize(device_t, int *); 69 static int ld_dumpblocks(device_t, void *, daddr_t, int); 70 static void ld_fake_geometry(struct ld_softc *); 71 static void ld_set_geometry(struct ld_softc *); 72 static void ld_config_interrupts (device_t); 73 static int ld_lastclose(device_t); 74 static int ld_discard(device_t, off_t, off_t); 75 static int ld_flush(device_t, bool); 76 77 static dev_type_open(ldopen); 78 static dev_type_close(ldclose); 79 static dev_type_read(ldread); 80 static dev_type_write(ldwrite); 81 static dev_type_ioctl(ldioctl); 82 static dev_type_strategy(ldstrategy); 83 static dev_type_dump(lddump); 84 static dev_type_size(ldsize); 85 static dev_type_discard(lddiscard); 86 87 const struct bdevsw ld_bdevsw = { 88 .d_open = ldopen, 89 .d_close = ldclose, 90 .d_strategy = ldstrategy, 91 .d_ioctl = ldioctl, 92 .d_dump = lddump, 93 .d_psize = ldsize, 94 .d_discard = lddiscard, 95 .d_flag = D_DISK | D_MPSAFE 96 }; 97 98 const struct cdevsw ld_cdevsw = { 99 .d_open = ldopen, 100 .d_close = ldclose, 101 .d_read = ldread, 102 .d_write = ldwrite, 103 .d_ioctl = ldioctl, 104 .d_stop = nostop, 105 .d_tty = notty, 106 .d_poll = nopoll, 107 .d_mmap = nommap, 108 .d_kqfilter = nokqfilter, 109 .d_discard = lddiscard, 110 .d_flag = D_DISK | D_MPSAFE 111 }; 112 113 static const struct dkdriver lddkdriver = { 114 .d_open = ldopen, 115 .d_close = ldclose, 116 .d_strategy = ldstrategy, 117 .d_iosize = ld_iosize, 118 .d_minphys = ldminphys, 119 .d_diskstart = ld_diskstart, 120 .d_dumpblocks = ld_dumpblocks, 121 .d_lastclose = ld_lastclose, 122 .d_discard = ld_discard 123 }; 124 125 void 126 ldattach(struct ld_softc *sc, const char *default_strategy) 127 { 128 device_t self = sc->sc_dv; 129 struct dk_softc *dksc = &sc->sc_dksc; 130 131 mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM); 132 cv_init(&sc->sc_drain, "lddrain"); 133 134 if ((sc->sc_flags & LDF_ENABLED) == 0) { 135 return; 136 } 137 138 /* don't attach a disk that we cannot handle */ 139 if (sc->sc_secsize < DEV_BSIZE) { 140 sc->sc_flags &= ~LDF_ENABLED; 141 return; 142 } 143 144 /* Initialise dk and disk structure. */ 145 dk_init(dksc, self, DKTYPE_LD); 146 disk_init(&dksc->sc_dkdev, dksc->sc_xname, &lddkdriver); 147 148 if (sc->sc_maxxfer > MAXPHYS) 149 sc->sc_maxxfer = MAXPHYS; 150 151 /* Build synthetic geometry if necessary. */ 152 if (sc->sc_nheads == 0 || sc->sc_nsectors == 0 || 153 sc->sc_ncylinders == 0) 154 ld_fake_geometry(sc); 155 156 sc->sc_disksize512 = sc->sc_secperunit * sc->sc_secsize / DEV_BSIZE; 157 158 if (sc->sc_flags & LDF_NO_RND) 159 dksc->sc_flags |= DKF_NO_RND; 160 161 /* Attach dk and disk subsystems */ 162 dk_attach(dksc); 163 disk_attach(&dksc->sc_dkdev); 164 ld_set_geometry(sc); 165 166 bufq_alloc(&dksc->sc_bufq, default_strategy, BUFQ_SORT_RAWBLOCK); 167 168 /* Register with PMF */ 169 if (!pmf_device_register1(dksc->sc_dev, ld_suspend, NULL, ld_shutdown)) 170 aprint_error_dev(dksc->sc_dev, 171 "couldn't establish power handler\n"); 172 173 /* Discover wedges on this disk. */ 174 config_interrupts(sc->sc_dv, ld_config_interrupts); 175 } 176 177 int 178 ldadjqparam(struct ld_softc *sc, int xmax) 179 { 180 181 mutex_enter(&sc->sc_mutex); 182 sc->sc_maxqueuecnt = xmax; 183 mutex_exit(&sc->sc_mutex); 184 185 return (0); 186 } 187 188 int 189 ldbegindetach(struct ld_softc *sc, int flags) 190 { 191 struct dk_softc *dksc = &sc->sc_dksc; 192 int error; 193 194 /* If we never attached properly, no problem with detaching. */ 195 if ((sc->sc_flags & LDF_ENABLED) == 0) 196 return 0; 197 198 /* 199 * If the disk is still open, back out before we commit to 200 * detaching. 201 */ 202 error = disk_begindetach(&dksc->sc_dkdev, ld_lastclose, dksc->sc_dev, 203 flags); 204 if (error) 205 return error; 206 207 /* We are now committed to detaching. Prevent new xfers. */ 208 ldadjqparam(sc, 0); 209 210 return 0; 211 } 212 213 void 214 ldenddetach(struct ld_softc *sc) 215 { 216 struct dk_softc *dksc = &sc->sc_dksc; 217 int bmaj, cmaj, i, mn; 218 219 if ((sc->sc_flags & LDF_ENABLED) == 0) 220 return; 221 222 /* Wait for commands queued with the hardware to complete. */ 223 mutex_enter(&sc->sc_mutex); 224 while (sc->sc_queuecnt > 0) { 225 if (cv_timedwait(&sc->sc_drain, &sc->sc_mutex, 30 * hz)) { 226 /* 227 * XXX This seems like a recipe for crashing on 228 * use after free... 229 */ 230 printf("%s: not drained\n", dksc->sc_xname); 231 break; 232 } 233 } 234 mutex_exit(&sc->sc_mutex); 235 236 /* Kill off any queued buffers. */ 237 dk_drain(dksc); 238 bufq_free(dksc->sc_bufq); 239 240 /* Locate the major numbers. */ 241 bmaj = bdevsw_lookup_major(&ld_bdevsw); 242 cmaj = cdevsw_lookup_major(&ld_cdevsw); 243 244 /* Nuke the vnodes for any open instances. */ 245 for (i = 0; i < MAXPARTITIONS; i++) { 246 mn = DISKMINOR(device_unit(dksc->sc_dev), i); 247 vdevgone(bmaj, mn, mn, VBLK); 248 vdevgone(cmaj, mn, mn, VCHR); 249 } 250 251 /* Delete all of our wedges. */ 252 dkwedge_delall(&dksc->sc_dkdev); 253 254 /* Detach from the disk list. */ 255 disk_detach(&dksc->sc_dkdev); 256 disk_destroy(&dksc->sc_dkdev); 257 258 dk_detach(dksc); 259 260 /* Deregister with PMF */ 261 pmf_device_deregister(dksc->sc_dev); 262 263 /* 264 * XXX We can't really flush the cache here, because the 265 * XXX device may already be non-existent from the controller's 266 * XXX perspective. 267 */ 268 #if 0 269 ld_flush(dksc->sc_dev, false); 270 #endif 271 cv_destroy(&sc->sc_drain); 272 mutex_destroy(&sc->sc_mutex); 273 } 274 275 /* ARGSUSED */ 276 static bool 277 ld_suspend(device_t dev, const pmf_qual_t *qual) 278 { 279 return ld_shutdown(dev, 0); 280 } 281 282 /* ARGSUSED */ 283 static bool 284 ld_shutdown(device_t dev, int flags) 285 { 286 if ((flags & RB_NOSYNC) == 0 && ld_flush(dev, true) != 0) 287 return false; 288 289 return true; 290 } 291 292 /* ARGSUSED */ 293 static int 294 ldopen(dev_t dev, int flags, int fmt, struct lwp *l) 295 { 296 struct ld_softc *sc; 297 struct dk_softc *dksc; 298 int unit; 299 300 unit = DISKUNIT(dev); 301 if ((sc = device_lookup_private(&ld_cd, unit)) == NULL) 302 return (ENXIO); 303 304 if ((sc->sc_flags & LDF_ENABLED) == 0) 305 return (ENODEV); 306 307 dksc = &sc->sc_dksc; 308 309 return dk_open(dksc, dev, flags, fmt, l); 310 } 311 312 static int 313 ld_lastclose(device_t self) 314 { 315 ld_flush(self, false); 316 317 return 0; 318 } 319 320 /* ARGSUSED */ 321 static int 322 ldclose(dev_t dev, int flags, int fmt, struct lwp *l) 323 { 324 struct ld_softc *sc; 325 struct dk_softc *dksc; 326 int unit; 327 328 unit = DISKUNIT(dev); 329 sc = device_lookup_private(&ld_cd, unit); 330 dksc = &sc->sc_dksc; 331 332 return dk_close(dksc, dev, flags, fmt, l); 333 } 334 335 /* ARGSUSED */ 336 static int 337 ldread(dev_t dev, struct uio *uio, int ioflag) 338 { 339 340 return (physio(ldstrategy, NULL, dev, B_READ, ldminphys, uio)); 341 } 342 343 /* ARGSUSED */ 344 static int 345 ldwrite(dev_t dev, struct uio *uio, int ioflag) 346 { 347 348 return (physio(ldstrategy, NULL, dev, B_WRITE, ldminphys, uio)); 349 } 350 351 /* ARGSUSED */ 352 static int 353 ldioctl(dev_t dev, u_long cmd, void *addr, int32_t flag, struct lwp *l) 354 { 355 struct ld_softc *sc; 356 struct dk_softc *dksc; 357 int unit, error; 358 359 unit = DISKUNIT(dev); 360 sc = device_lookup_private(&ld_cd, unit); 361 dksc = &sc->sc_dksc; 362 363 error = 0; 364 365 /* 366 * Some common checks so that individual attachments wouldn't need 367 * to duplicate them. 368 */ 369 switch (cmd) { 370 case DIOCCACHESYNC: 371 /* 372 * XXX Do we really need to care about having a writable 373 * file descriptor here? 374 */ 375 if ((flag & FWRITE) == 0) 376 error = EBADF; 377 else 378 error = 0; 379 break; 380 } 381 382 if (error != 0) 383 return (error); 384 385 if (sc->sc_ioctl) { 386 if ((sc->sc_flags & LDF_MPSAFE) == 0) 387 KERNEL_LOCK(1, curlwp); 388 error = (*sc->sc_ioctl)(sc, cmd, addr, flag, 0); 389 if ((sc->sc_flags & LDF_MPSAFE) == 0) 390 KERNEL_UNLOCK_ONE(curlwp); 391 if (error != EPASSTHROUGH) 392 return (error); 393 } 394 395 /* something not handled by the attachment */ 396 return dk_ioctl(dksc, dev, cmd, addr, flag, l); 397 } 398 399 /* 400 * Flush the device's cache. 401 */ 402 static int 403 ld_flush(device_t self, bool poll) 404 { 405 int error = 0; 406 struct ld_softc *sc = device_private(self); 407 408 if (sc->sc_ioctl) { 409 if ((sc->sc_flags & LDF_MPSAFE) == 0) 410 KERNEL_LOCK(1, curlwp); 411 error = (*sc->sc_ioctl)(sc, DIOCCACHESYNC, NULL, 0, poll); 412 if ((sc->sc_flags & LDF_MPSAFE) == 0) 413 KERNEL_UNLOCK_ONE(curlwp); 414 if (error != 0) 415 device_printf(self, "unable to flush cache\n"); 416 } 417 418 return error; 419 } 420 421 static void 422 ldstrategy(struct buf *bp) 423 { 424 struct ld_softc *sc; 425 struct dk_softc *dksc; 426 int unit; 427 428 unit = DISKUNIT(bp->b_dev); 429 sc = device_lookup_private(&ld_cd, unit); 430 dksc = &sc->sc_dksc; 431 432 dk_strategy(dksc, bp); 433 } 434 435 static int 436 ld_diskstart(device_t dev, struct buf *bp) 437 { 438 struct ld_softc *sc = device_private(dev); 439 int error; 440 441 if (sc->sc_queuecnt >= sc->sc_maxqueuecnt) 442 return EAGAIN; 443 444 if ((sc->sc_flags & LDF_MPSAFE) == 0) 445 KERNEL_LOCK(1, curlwp); 446 447 mutex_enter(&sc->sc_mutex); 448 449 if (sc->sc_queuecnt >= sc->sc_maxqueuecnt) 450 error = EAGAIN; 451 else { 452 error = (*sc->sc_start)(sc, bp); 453 if (error == 0) 454 sc->sc_queuecnt++; 455 } 456 457 mutex_exit(&sc->sc_mutex); 458 459 if ((sc->sc_flags & LDF_MPSAFE) == 0) 460 KERNEL_UNLOCK_ONE(curlwp); 461 462 return error; 463 } 464 465 void 466 lddone(struct ld_softc *sc, struct buf *bp) 467 { 468 struct dk_softc *dksc = &sc->sc_dksc; 469 470 dk_done(dksc, bp); 471 472 mutex_enter(&sc->sc_mutex); 473 if (--sc->sc_queuecnt <= sc->sc_maxqueuecnt) { 474 cv_broadcast(&sc->sc_drain); 475 mutex_exit(&sc->sc_mutex); 476 dk_start(dksc, NULL); 477 } else 478 mutex_exit(&sc->sc_mutex); 479 } 480 481 static int 482 ldsize(dev_t dev) 483 { 484 struct ld_softc *sc; 485 struct dk_softc *dksc; 486 int unit; 487 488 unit = DISKUNIT(dev); 489 if ((sc = device_lookup_private(&ld_cd, unit)) == NULL) 490 return (-1); 491 dksc = &sc->sc_dksc; 492 493 if ((sc->sc_flags & LDF_ENABLED) == 0) 494 return (-1); 495 496 return dk_size(dksc, dev); 497 } 498 499 /* 500 * Take a dump. 501 */ 502 static int 503 lddump(dev_t dev, daddr_t blkno, void *va, size_t size) 504 { 505 struct ld_softc *sc; 506 struct dk_softc *dksc; 507 int unit; 508 509 unit = DISKUNIT(dev); 510 if ((sc = device_lookup_private(&ld_cd, unit)) == NULL) 511 return (ENXIO); 512 dksc = &sc->sc_dksc; 513 514 if ((sc->sc_flags & LDF_ENABLED) == 0) 515 return (ENODEV); 516 517 return dk_dump(dksc, dev, blkno, va, size, 0); 518 } 519 520 static int 521 ld_dumpblocks(device_t dev, void *va, daddr_t blkno, int nblk) 522 { 523 struct ld_softc *sc = device_private(dev); 524 525 if (sc->sc_dump == NULL) 526 return (ENODEV); 527 528 return (*sc->sc_dump)(sc, va, blkno, nblk); 529 } 530 531 /* 532 * Adjust the size of a transfer. 533 */ 534 static void 535 ldminphys(struct buf *bp) 536 { 537 int unit; 538 struct ld_softc *sc; 539 540 unit = DISKUNIT(bp->b_dev); 541 sc = device_lookup_private(&ld_cd, unit); 542 543 ld_iosize(sc->sc_dv, &bp->b_bcount); 544 minphys(bp); 545 } 546 547 static void 548 ld_iosize(device_t d, int *countp) 549 { 550 struct ld_softc *sc = device_private(d); 551 552 if (*countp > sc->sc_maxxfer) 553 *countp = sc->sc_maxxfer; 554 } 555 556 static void 557 ld_fake_geometry(struct ld_softc *sc) 558 { 559 uint64_t ncyl; 560 561 if (sc->sc_secperunit <= 528 * 2048) /* 528MB */ 562 sc->sc_nheads = 16; 563 else if (sc->sc_secperunit <= 1024 * 2048) /* 1GB */ 564 sc->sc_nheads = 32; 565 else if (sc->sc_secperunit <= 21504 * 2048) /* 21GB */ 566 sc->sc_nheads = 64; 567 else if (sc->sc_secperunit <= 43008 * 2048) /* 42GB */ 568 sc->sc_nheads = 128; 569 else 570 sc->sc_nheads = 255; 571 572 sc->sc_nsectors = 63; 573 sc->sc_ncylinders = INT_MAX; 574 ncyl = sc->sc_secperunit / 575 (sc->sc_nheads * sc->sc_nsectors); 576 if (ncyl < INT_MAX) 577 sc->sc_ncylinders = (int)ncyl; 578 } 579 580 static void 581 ld_set_geometry(struct ld_softc *sc) 582 { 583 struct dk_softc *dksc = &sc->sc_dksc; 584 struct disk_geom *dg = &dksc->sc_dkdev.dk_geom; 585 char tbuf[9]; 586 587 format_bytes(tbuf, sizeof(tbuf), sc->sc_secperunit * 588 sc->sc_secsize); 589 aprint_normal_dev(dksc->sc_dev, "%s, %d cyl, %d head, %d sec, " 590 "%d bytes/sect x %"PRIu64" sectors\n", 591 tbuf, sc->sc_ncylinders, sc->sc_nheads, 592 sc->sc_nsectors, sc->sc_secsize, sc->sc_secperunit); 593 594 memset(dg, 0, sizeof(*dg)); 595 dg->dg_secperunit = sc->sc_secperunit; 596 dg->dg_secsize = sc->sc_secsize; 597 dg->dg_nsectors = sc->sc_nsectors; 598 dg->dg_ntracks = sc->sc_nheads; 599 dg->dg_ncylinders = sc->sc_ncylinders; 600 601 disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, sc->sc_typename); 602 } 603 604 static void 605 ld_config_interrupts(device_t d) 606 { 607 struct ld_softc *sc = device_private(d); 608 struct dk_softc *dksc = &sc->sc_dksc; 609 610 dkwedge_discover(&dksc->sc_dkdev); 611 } 612 613 static int 614 ld_discard(device_t dev, off_t pos, off_t len) 615 { 616 struct ld_softc *sc = device_private(dev); 617 struct buf dbuf, *bp = &dbuf; 618 int error = 0; 619 620 KASSERT(len <= INT_MAX); 621 622 if (sc->sc_discard == NULL) 623 return (ENODEV); 624 625 if ((sc->sc_flags & LDF_MPSAFE) == 0) 626 KERNEL_LOCK(1, curlwp); 627 628 buf_init(bp); 629 bp->b_vp = NULL; 630 bp->b_data = NULL; 631 bp->b_bufsize = 0; 632 bp->b_rawblkno = pos / sc->sc_secsize; 633 bp->b_bcount = len; 634 bp->b_flags = B_WRITE; 635 bp->b_cflags = BC_BUSY; 636 637 error = (*sc->sc_discard)(sc, bp); 638 if (error == 0) 639 error = biowait(bp); 640 641 buf_destroy(bp); 642 643 if ((sc->sc_flags & LDF_MPSAFE) == 0) 644 KERNEL_UNLOCK_ONE(curlwp); 645 646 return error; 647 } 648 649 void 650 lddiscardend(struct ld_softc *sc, struct buf *bp) 651 { 652 653 if (bp->b_error) 654 bp->b_resid = bp->b_bcount; 655 biodone(bp); 656 } 657 658 static int 659 lddiscard(dev_t dev, off_t pos, off_t len) 660 { 661 struct ld_softc *sc; 662 struct dk_softc *dksc; 663 int unit; 664 665 unit = DISKUNIT(dev); 666 sc = device_lookup_private(&ld_cd, unit); 667 dksc = &sc->sc_dksc; 668 669 return dk_discard(dksc, dev, pos, len); 670 } 671 672 MODULE(MODULE_CLASS_DRIVER, ld, "dk_subr"); 673 674 #ifdef _MODULE 675 CFDRIVER_DECL(ld, DV_DISK, NULL); 676 #endif 677 678 static int 679 ld_modcmd(modcmd_t cmd, void *opaque) 680 { 681 #ifdef _MODULE 682 devmajor_t bmajor, cmajor; 683 #endif 684 int error = 0; 685 686 #ifdef _MODULE 687 switch (cmd) { 688 case MODULE_CMD_INIT: 689 bmajor = cmajor = -1; 690 error = devsw_attach(ld_cd.cd_name, &ld_bdevsw, &bmajor, 691 &ld_cdevsw, &cmajor); 692 if (error) 693 break; 694 error = config_cfdriver_attach(&ld_cd); 695 break; 696 case MODULE_CMD_FINI: 697 error = config_cfdriver_detach(&ld_cd); 698 if (error) 699 break; 700 devsw_detach(&ld_bdevsw, &ld_cdevsw); 701 break; 702 default: 703 error = ENOTTY; 704 break; 705 } 706 #endif 707 708 return error; 709 } 710