1 /* $NetBSD: ld.c,v 1.110 2020/04/13 08:05:02 maxv 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.110 2020/04/13 08:05:02 maxv 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 rv = 0; 193 194 if ((sc->sc_flags & LDF_ENABLED) == 0) 195 return (0); 196 197 rv = disk_begindetach(&dksc->sc_dkdev, ld_lastclose, dksc->sc_dev, flags); 198 199 if (rv != 0) 200 return rv; 201 202 mutex_enter(&sc->sc_mutex); 203 sc->sc_maxqueuecnt = 0; 204 205 while (sc->sc_queuecnt > 0) { 206 sc->sc_flags |= LDF_DRAIN; 207 cv_wait(&sc->sc_drain, &sc->sc_mutex); 208 } 209 mutex_exit(&sc->sc_mutex); 210 211 return (rv); 212 } 213 214 void 215 ldenddetach(struct ld_softc *sc) 216 { 217 struct dk_softc *dksc = &sc->sc_dksc; 218 int bmaj, cmaj, i, mn; 219 220 if ((sc->sc_flags & LDF_ENABLED) == 0) 221 return; 222 223 mutex_enter(&sc->sc_mutex); 224 225 /* Wait for commands queued with the hardware to complete. */ 226 if (sc->sc_queuecnt != 0) { 227 if (cv_timedwait(&sc->sc_drain, &sc->sc_mutex, 30 * hz)) 228 printf("%s: not drained\n", dksc->sc_xname); 229 } 230 mutex_exit(&sc->sc_mutex); 231 232 /* Kill off any queued buffers. */ 233 dk_drain(dksc); 234 bufq_free(dksc->sc_bufq); 235 236 /* Locate the major numbers. */ 237 bmaj = bdevsw_lookup_major(&ld_bdevsw); 238 cmaj = cdevsw_lookup_major(&ld_cdevsw); 239 240 /* Nuke the vnodes for any open instances. */ 241 for (i = 0; i < MAXPARTITIONS; i++) { 242 mn = DISKMINOR(device_unit(dksc->sc_dev), i); 243 vdevgone(bmaj, mn, mn, VBLK); 244 vdevgone(cmaj, mn, mn, VCHR); 245 } 246 247 /* Delete all of our wedges. */ 248 dkwedge_delall(&dksc->sc_dkdev); 249 250 /* Detach from the disk list. */ 251 disk_detach(&dksc->sc_dkdev); 252 disk_destroy(&dksc->sc_dkdev); 253 254 dk_detach(dksc); 255 256 /* Deregister with PMF */ 257 pmf_device_deregister(dksc->sc_dev); 258 259 /* 260 * XXX We can't really flush the cache here, because the 261 * XXX device may already be non-existent from the controller's 262 * XXX perspective. 263 */ 264 #if 0 265 ld_flush(dksc->sc_dev, false); 266 #endif 267 cv_destroy(&sc->sc_drain); 268 mutex_destroy(&sc->sc_mutex); 269 } 270 271 /* ARGSUSED */ 272 static bool 273 ld_suspend(device_t dev, const pmf_qual_t *qual) 274 { 275 return ld_shutdown(dev, 0); 276 } 277 278 /* ARGSUSED */ 279 static bool 280 ld_shutdown(device_t dev, int flags) 281 { 282 if ((flags & RB_NOSYNC) == 0 && ld_flush(dev, true) != 0) 283 return false; 284 285 return true; 286 } 287 288 /* ARGSUSED */ 289 static int 290 ldopen(dev_t dev, int flags, int fmt, struct lwp *l) 291 { 292 struct ld_softc *sc; 293 struct dk_softc *dksc; 294 int unit; 295 296 unit = DISKUNIT(dev); 297 if ((sc = device_lookup_private(&ld_cd, unit)) == NULL) 298 return (ENXIO); 299 300 if ((sc->sc_flags & LDF_ENABLED) == 0) 301 return (ENODEV); 302 303 dksc = &sc->sc_dksc; 304 305 return dk_open(dksc, dev, flags, fmt, l); 306 } 307 308 static int 309 ld_lastclose(device_t self) 310 { 311 ld_flush(self, false); 312 313 return 0; 314 } 315 316 /* ARGSUSED */ 317 static int 318 ldclose(dev_t dev, int flags, int fmt, struct lwp *l) 319 { 320 struct ld_softc *sc; 321 struct dk_softc *dksc; 322 int unit; 323 324 unit = DISKUNIT(dev); 325 sc = device_lookup_private(&ld_cd, unit); 326 dksc = &sc->sc_dksc; 327 328 return dk_close(dksc, dev, flags, fmt, l); 329 } 330 331 /* ARGSUSED */ 332 static int 333 ldread(dev_t dev, struct uio *uio, int ioflag) 334 { 335 336 return (physio(ldstrategy, NULL, dev, B_READ, ldminphys, uio)); 337 } 338 339 /* ARGSUSED */ 340 static int 341 ldwrite(dev_t dev, struct uio *uio, int ioflag) 342 { 343 344 return (physio(ldstrategy, NULL, dev, B_WRITE, ldminphys, uio)); 345 } 346 347 /* ARGSUSED */ 348 static int 349 ldioctl(dev_t dev, u_long cmd, void *addr, int32_t flag, struct lwp *l) 350 { 351 struct ld_softc *sc; 352 struct dk_softc *dksc; 353 int unit, error; 354 355 unit = DISKUNIT(dev); 356 sc = device_lookup_private(&ld_cd, unit); 357 dksc = &sc->sc_dksc; 358 359 error = 0; 360 361 /* 362 * Some common checks so that individual attachments wouldn't need 363 * to duplicate them. 364 */ 365 switch (cmd) { 366 case DIOCCACHESYNC: 367 /* 368 * XXX Do we really need to care about having a writable 369 * file descriptor here? 370 */ 371 if ((flag & FWRITE) == 0) 372 error = EBADF; 373 else 374 error = 0; 375 break; 376 } 377 378 if (error != 0) 379 return (error); 380 381 if (sc->sc_ioctl) { 382 if ((sc->sc_flags & LDF_MPSAFE) == 0) 383 KERNEL_LOCK(1, curlwp); 384 error = (*sc->sc_ioctl)(sc, cmd, addr, flag, 0); 385 if ((sc->sc_flags & LDF_MPSAFE) == 0) 386 KERNEL_UNLOCK_ONE(curlwp); 387 if (error != EPASSTHROUGH) 388 return (error); 389 } 390 391 /* something not handled by the attachment */ 392 return dk_ioctl(dksc, dev, cmd, addr, flag, l); 393 } 394 395 /* 396 * Flush the device's cache. 397 */ 398 static int 399 ld_flush(device_t self, bool poll) 400 { 401 int error = 0; 402 struct ld_softc *sc = device_private(self); 403 404 if (sc->sc_ioctl) { 405 if ((sc->sc_flags & LDF_MPSAFE) == 0) 406 KERNEL_LOCK(1, curlwp); 407 error = (*sc->sc_ioctl)(sc, DIOCCACHESYNC, NULL, 0, poll); 408 if ((sc->sc_flags & LDF_MPSAFE) == 0) 409 KERNEL_UNLOCK_ONE(curlwp); 410 if (error != 0) 411 device_printf(self, "unable to flush cache\n"); 412 } 413 414 return error; 415 } 416 417 static void 418 ldstrategy(struct buf *bp) 419 { 420 struct ld_softc *sc; 421 struct dk_softc *dksc; 422 int unit; 423 424 unit = DISKUNIT(bp->b_dev); 425 sc = device_lookup_private(&ld_cd, unit); 426 dksc = &sc->sc_dksc; 427 428 dk_strategy(dksc, bp); 429 } 430 431 static int 432 ld_diskstart(device_t dev, struct buf *bp) 433 { 434 struct ld_softc *sc = device_private(dev); 435 int error; 436 437 if (sc->sc_queuecnt >= sc->sc_maxqueuecnt) 438 return EAGAIN; 439 440 if ((sc->sc_flags & LDF_MPSAFE) == 0) 441 KERNEL_LOCK(1, curlwp); 442 443 mutex_enter(&sc->sc_mutex); 444 445 if (sc->sc_queuecnt >= sc->sc_maxqueuecnt) 446 error = EAGAIN; 447 else { 448 error = (*sc->sc_start)(sc, bp); 449 if (error == 0) 450 sc->sc_queuecnt++; 451 } 452 453 mutex_exit(&sc->sc_mutex); 454 455 if ((sc->sc_flags & LDF_MPSAFE) == 0) 456 KERNEL_UNLOCK_ONE(curlwp); 457 458 return error; 459 } 460 461 void 462 lddone(struct ld_softc *sc, struct buf *bp) 463 { 464 struct dk_softc *dksc = &sc->sc_dksc; 465 466 dk_done(dksc, bp); 467 468 mutex_enter(&sc->sc_mutex); 469 if (--sc->sc_queuecnt <= sc->sc_maxqueuecnt) { 470 if ((sc->sc_flags & LDF_DRAIN) != 0) { 471 sc->sc_flags &= ~LDF_DRAIN; 472 cv_broadcast(&sc->sc_drain); 473 } 474 mutex_exit(&sc->sc_mutex); 475 dk_start(dksc, NULL); 476 } else 477 mutex_exit(&sc->sc_mutex); 478 } 479 480 static int 481 ldsize(dev_t dev) 482 { 483 struct ld_softc *sc; 484 struct dk_softc *dksc; 485 int unit; 486 487 unit = DISKUNIT(dev); 488 if ((sc = device_lookup_private(&ld_cd, unit)) == NULL) 489 return (-1); 490 dksc = &sc->sc_dksc; 491 492 if ((sc->sc_flags & LDF_ENABLED) == 0) 493 return (-1); 494 495 return dk_size(dksc, dev); 496 } 497 498 /* 499 * Take a dump. 500 */ 501 static int 502 lddump(dev_t dev, daddr_t blkno, void *va, size_t size) 503 { 504 struct ld_softc *sc; 505 struct dk_softc *dksc; 506 int unit; 507 508 unit = DISKUNIT(dev); 509 if ((sc = device_lookup_private(&ld_cd, unit)) == NULL) 510 return (ENXIO); 511 dksc = &sc->sc_dksc; 512 513 if ((sc->sc_flags & LDF_ENABLED) == 0) 514 return (ENODEV); 515 516 return dk_dump(dksc, dev, blkno, va, size, 0); 517 } 518 519 static int 520 ld_dumpblocks(device_t dev, void *va, daddr_t blkno, int nblk) 521 { 522 struct ld_softc *sc = device_private(dev); 523 524 if (sc->sc_dump == NULL) 525 return (ENODEV); 526 527 return (*sc->sc_dump)(sc, va, blkno, nblk); 528 } 529 530 /* 531 * Adjust the size of a transfer. 532 */ 533 static void 534 ldminphys(struct buf *bp) 535 { 536 int unit; 537 struct ld_softc *sc; 538 539 unit = DISKUNIT(bp->b_dev); 540 sc = device_lookup_private(&ld_cd, unit); 541 542 ld_iosize(sc->sc_dv, &bp->b_bcount); 543 minphys(bp); 544 } 545 546 static void 547 ld_iosize(device_t d, int *countp) 548 { 549 struct ld_softc *sc = device_private(d); 550 551 if (*countp > sc->sc_maxxfer) 552 *countp = sc->sc_maxxfer; 553 } 554 555 static void 556 ld_fake_geometry(struct ld_softc *sc) 557 { 558 uint64_t ncyl; 559 560 if (sc->sc_secperunit <= 528 * 2048) /* 528MB */ 561 sc->sc_nheads = 16; 562 else if (sc->sc_secperunit <= 1024 * 2048) /* 1GB */ 563 sc->sc_nheads = 32; 564 else if (sc->sc_secperunit <= 21504 * 2048) /* 21GB */ 565 sc->sc_nheads = 64; 566 else if (sc->sc_secperunit <= 43008 * 2048) /* 42GB */ 567 sc->sc_nheads = 128; 568 else 569 sc->sc_nheads = 255; 570 571 sc->sc_nsectors = 63; 572 sc->sc_ncylinders = INT_MAX; 573 ncyl = sc->sc_secperunit / 574 (sc->sc_nheads * sc->sc_nsectors); 575 if (ncyl < INT_MAX) 576 sc->sc_ncylinders = (int)ncyl; 577 } 578 579 static void 580 ld_set_geometry(struct ld_softc *sc) 581 { 582 struct dk_softc *dksc = &sc->sc_dksc; 583 struct disk_geom *dg = &dksc->sc_dkdev.dk_geom; 584 char tbuf[9]; 585 586 format_bytes(tbuf, sizeof(tbuf), sc->sc_secperunit * 587 sc->sc_secsize); 588 aprint_normal_dev(dksc->sc_dev, "%s, %d cyl, %d head, %d sec, " 589 "%d bytes/sect x %"PRIu64" sectors\n", 590 tbuf, sc->sc_ncylinders, sc->sc_nheads, 591 sc->sc_nsectors, sc->sc_secsize, sc->sc_secperunit); 592 593 memset(dg, 0, sizeof(*dg)); 594 dg->dg_secperunit = sc->sc_secperunit; 595 dg->dg_secsize = sc->sc_secsize; 596 dg->dg_nsectors = sc->sc_nsectors; 597 dg->dg_ntracks = sc->sc_nheads; 598 dg->dg_ncylinders = sc->sc_ncylinders; 599 600 disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, sc->sc_typename); 601 } 602 603 static void 604 ld_config_interrupts(device_t d) 605 { 606 struct ld_softc *sc = device_private(d); 607 struct dk_softc *dksc = &sc->sc_dksc; 608 609 dkwedge_discover(&dksc->sc_dkdev); 610 } 611 612 static int 613 ld_discard(device_t dev, off_t pos, off_t len) 614 { 615 struct ld_softc *sc = device_private(dev); 616 struct buf dbuf, *bp = &dbuf; 617 int error = 0; 618 619 KASSERT(len <= INT_MAX); 620 621 if (sc->sc_discard == NULL) 622 return (ENODEV); 623 624 if ((sc->sc_flags & LDF_MPSAFE) == 0) 625 KERNEL_LOCK(1, curlwp); 626 627 buf_init(bp); 628 bp->b_vp = NULL; 629 bp->b_data = NULL; 630 bp->b_bufsize = 0; 631 bp->b_rawblkno = pos / sc->sc_secsize; 632 bp->b_bcount = len; 633 bp->b_flags = B_WRITE; 634 bp->b_cflags = BC_BUSY; 635 636 error = (*sc->sc_discard)(sc, bp); 637 if (error == 0) 638 error = biowait(bp); 639 640 buf_destroy(bp); 641 642 if ((sc->sc_flags & LDF_MPSAFE) == 0) 643 KERNEL_UNLOCK_ONE(curlwp); 644 645 return error; 646 } 647 648 void 649 lddiscardend(struct ld_softc *sc, struct buf *bp) 650 { 651 652 if (bp->b_error) 653 bp->b_resid = bp->b_bcount; 654 biodone(bp); 655 } 656 657 static int 658 lddiscard(dev_t dev, off_t pos, off_t len) 659 { 660 struct ld_softc *sc; 661 struct dk_softc *dksc; 662 int unit; 663 664 unit = DISKUNIT(dev); 665 sc = device_lookup_private(&ld_cd, unit); 666 dksc = &sc->sc_dksc; 667 668 return dk_discard(dksc, dev, pos, len); 669 } 670 671 MODULE(MODULE_CLASS_DRIVER, ld, "dk_subr"); 672 673 #ifdef _MODULE 674 CFDRIVER_DECL(ld, DV_DISK, NULL); 675 #endif 676 677 static int 678 ld_modcmd(modcmd_t cmd, void *opaque) 679 { 680 #ifdef _MODULE 681 devmajor_t bmajor, cmajor; 682 #endif 683 int error = 0; 684 685 #ifdef _MODULE 686 switch (cmd) { 687 case MODULE_CMD_INIT: 688 bmajor = cmajor = -1; 689 error = devsw_attach(ld_cd.cd_name, &ld_bdevsw, &bmajor, 690 &ld_cdevsw, &cmajor); 691 if (error) 692 break; 693 error = config_cfdriver_attach(&ld_cd); 694 break; 695 case MODULE_CMD_FINI: 696 error = config_cfdriver_detach(&ld_cd); 697 if (error) 698 break; 699 devsw_detach(&ld_bdevsw, &ld_cdevsw); 700 break; 701 default: 702 error = ENOTTY; 703 break; 704 } 705 #endif 706 707 return error; 708 } 709