ld.c revision 1.100.4.3 1 /* $NetBSD: ld.c,v 1.100.4.3 2017/05/02 03:19:18 pgoyette 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.100.4.3 2017/05/02 03:19:18 pgoyette 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 static void ldminphys(struct buf *bp);
63 static bool ld_suspend(device_t, const pmf_qual_t *);
64 static bool ld_shutdown(device_t, int);
65 static int ld_diskstart(device_t, struct buf *bp);
66 static void ld_iosize(device_t, int *);
67 static int ld_dumpblocks(device_t, void *, daddr_t, int);
68 static void ld_fake_geometry(struct ld_softc *);
69 static void ld_set_geometry(struct ld_softc *);
70 static void ld_config_interrupts (device_t);
71 static int ld_lastclose(device_t);
72 static int ld_discard(device_t, off_t, off_t);
73 static int ld_flush(device_t, bool);
74
75 extern struct cfdriver ld_cd;
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 DEVSW_MODULE_INIT
89 .d_open = ldopen,
90 .d_close = ldclose,
91 .d_strategy = ldstrategy,
92 .d_ioctl = ldioctl,
93 .d_dump = lddump,
94 .d_psize = ldsize,
95 .d_discard = lddiscard,
96 .d_flag = D_DISK | D_MPSAFE
97 };
98
99 const struct cdevsw ld_cdevsw = {
100 DEVSW_MODULE_INIT
101 .d_open = ldopen,
102 .d_close = ldclose,
103 .d_read = ldread,
104 .d_write = ldwrite,
105 .d_ioctl = ldioctl,
106 .d_stop = nostop,
107 .d_tty = notty,
108 .d_poll = nopoll,
109 .d_mmap = nommap,
110 .d_kqfilter = nokqfilter,
111 .d_discard = lddiscard,
112 .d_flag = D_DISK | D_MPSAFE
113 };
114
115 static struct dkdriver lddkdriver = {
116 .d_open = ldopen,
117 .d_close = ldclose,
118 .d_strategy = ldstrategy,
119 .d_iosize = ld_iosize,
120 .d_minphys = ldminphys,
121 .d_diskstart = ld_diskstart,
122 .d_dumpblocks = ld_dumpblocks,
123 .d_lastclose = ld_lastclose,
124 .d_discard = ld_discard
125 };
126
127 void
128 ldattach(struct ld_softc *sc, const char *default_strategy)
129 {
130 device_t self = sc->sc_dv;
131 struct dk_softc *dksc = &sc->sc_dksc;
132
133 mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM);
134 cv_init(&sc->sc_drain, "lddrain");
135
136 if ((sc->sc_flags & LDF_ENABLED) == 0) {
137 return;
138 }
139
140 /* Initialise dk and disk structure. */
141 dk_init(dksc, self, DKTYPE_LD);
142 disk_init(&dksc->sc_dkdev, dksc->sc_xname, &lddkdriver);
143
144 if (sc->sc_maxxfer > MAXPHYS)
145 sc->sc_maxxfer = MAXPHYS;
146
147 /* Build synthetic geometry if necessary. */
148 if (sc->sc_nheads == 0 || sc->sc_nsectors == 0 ||
149 sc->sc_ncylinders == 0)
150 ld_fake_geometry(sc);
151
152 sc->sc_disksize512 = sc->sc_secperunit * sc->sc_secsize / DEV_BSIZE;
153
154 if (sc->sc_flags & LDF_NO_RND)
155 dksc->sc_flags |= DKF_NO_RND;
156
157 /* Attach dk and disk subsystems */
158 dk_attach(dksc);
159 disk_attach(&dksc->sc_dkdev);
160 ld_set_geometry(sc);
161
162 bufq_alloc(&dksc->sc_bufq, default_strategy, BUFQ_SORT_RAWBLOCK);
163
164 /* Register with PMF */
165 if (!pmf_device_register1(dksc->sc_dev, ld_suspend, NULL, ld_shutdown))
166 aprint_error_dev(dksc->sc_dev,
167 "couldn't establish power handler\n");
168
169 /* Discover wedges on this disk. */
170 config_interrupts(sc->sc_dv, ld_config_interrupts);
171 }
172
173 int
174 ldadjqparam(struct ld_softc *sc, int xmax)
175 {
176
177 mutex_enter(&sc->sc_mutex);
178 sc->sc_maxqueuecnt = xmax;
179 mutex_exit(&sc->sc_mutex);
180
181 return (0);
182 }
183
184 int
185 ldbegindetach(struct ld_softc *sc, int flags)
186 {
187 struct dk_softc *dksc = &sc->sc_dksc;
188 int rv = 0;
189
190 if ((sc->sc_flags & LDF_ENABLED) == 0)
191 return (0);
192
193 rv = disk_begindetach(&dksc->sc_dkdev, ld_lastclose, dksc->sc_dev, flags);
194
195 if (rv != 0)
196 return rv;
197
198 mutex_enter(&sc->sc_mutex);
199 sc->sc_maxqueuecnt = 0;
200
201 while (sc->sc_queuecnt > 0) {
202 sc->sc_flags |= LDF_DRAIN;
203 cv_wait(&sc->sc_drain, &sc->sc_mutex);
204 }
205 mutex_exit(&sc->sc_mutex);
206
207 return (rv);
208 }
209
210 void
211 ldenddetach(struct ld_softc *sc)
212 {
213 struct dk_softc *dksc = &sc->sc_dksc;
214 int bmaj, cmaj, i, mn;
215
216 if ((sc->sc_flags & LDF_ENABLED) == 0)
217 return;
218
219 mutex_enter(&sc->sc_mutex);
220
221 /* Wait for commands queued with the hardware to complete. */
222 if (sc->sc_queuecnt != 0) {
223 if (cv_timedwait(&sc->sc_drain, &sc->sc_mutex, 30 * hz))
224 printf("%s: not drained\n", dksc->sc_xname);
225 }
226 mutex_exit(&sc->sc_mutex);
227
228 /* Kill off any queued buffers. */
229 dk_drain(dksc);
230 bufq_free(dksc->sc_bufq);
231
232 /* Locate the major numbers. */
233 bmaj = bdevsw_lookup_major(&ld_bdevsw);
234 cmaj = cdevsw_lookup_major(&ld_cdevsw);
235
236 /* Nuke the vnodes for any open instances. */
237 for (i = 0; i < MAXPARTITIONS; i++) {
238 mn = DISKMINOR(device_unit(dksc->sc_dev), i);
239 vdevgone(bmaj, mn, mn, VBLK);
240 vdevgone(cmaj, mn, mn, VCHR);
241 }
242
243 /* Delete all of our wedges. */
244 dkwedge_delall(&dksc->sc_dkdev);
245
246 /* Detach from the disk list. */
247 disk_detach(&dksc->sc_dkdev);
248 disk_destroy(&dksc->sc_dkdev);
249
250 dk_detach(dksc);
251
252 /* Deregister with PMF */
253 pmf_device_deregister(dksc->sc_dev);
254
255 /*
256 * XXX We can't really flush the cache here, because the
257 * XXX device may already be non-existent from the controller's
258 * XXX perspective.
259 */
260 #if 0
261 ld_flush(dksc->sc_dev, false);
262 #endif
263 cv_destroy(&sc->sc_drain);
264 mutex_destroy(&sc->sc_mutex);
265 }
266
267 /* ARGSUSED */
268 static bool
269 ld_suspend(device_t dev, const pmf_qual_t *qual)
270 {
271 return ld_shutdown(dev, 0);
272 }
273
274 /* ARGSUSED */
275 static bool
276 ld_shutdown(device_t dev, int flags)
277 {
278 if ((flags & RB_NOSYNC) == 0 && ld_flush(dev, true) != 0)
279 return false;
280
281 return true;
282 }
283
284 /* ARGSUSED */
285 static int
286 ldopen(dev_t dev, int flags, int fmt, struct lwp *l)
287 {
288 device_t self;
289 struct ld_softc *sc;
290 struct dk_softc *dksc;
291 int unit;
292 int error;
293
294 unit = DISKUNIT(dev);
295 self = device_lookup_acquire(&ld_cd, unit);
296 if (self == NULL)
297 return ENXIO;
298 sc = device_private(self);
299 dksc = &sc->sc_dksc;
300
301 error = dk_open(dksc, dev, flags, fmt, l);
302 device_release(self);
303 return error;
304 }
305
306 static int
307 ld_lastclose(device_t self)
308 {
309 ld_flush(self, false);
310
311 return 0;
312 }
313
314 /* ARGSUSED */
315 static int
316 ldclose(dev_t dev, int flags, int fmt, struct lwp *l)
317 {
318 device_t self;
319 struct ld_softc *sc;
320 struct dk_softc *dksc;
321 int unit;
322 int error;
323
324 unit = DISKUNIT(dev);
325 self = device_lookup_acquire(&ld_cd, unit);
326 if (self == NULL)
327 return ENXIO;
328 sc = device_private(self);
329 dksc = &sc->sc_dksc;
330
331 error = dk_close(dksc, dev, flags, fmt, l);
332 device_release(self);
333 return error;
334 }
335
336 /* ARGSUSED */
337 static int
338 ldread(dev_t dev, struct uio *uio, int ioflag)
339 {
340
341 return (physio(ldstrategy, NULL, dev, B_READ, ldminphys, uio));
342 }
343
344 /* ARGSUSED */
345 static int
346 ldwrite(dev_t dev, struct uio *uio, int ioflag)
347 {
348
349 return (physio(ldstrategy, NULL, dev, B_WRITE, ldminphys, uio));
350 }
351
352 /* ARGSUSED */
353 static int
354 ldioctl(dev_t dev, u_long cmd, void *addr, int32_t flag, struct lwp *l)
355 {
356 device_t self;
357 struct ld_softc *sc;
358 struct dk_softc *dksc;
359 int unit, error;
360
361 unit = DISKUNIT(dev);
362 self = device_lookup_acquire(&ld_cd, unit);
363 if (self == NULL)
364 return ENXIO;
365 sc = device_private(self);
366 dksc = &sc->sc_dksc;
367
368 error = dk_ioctl(dksc, dev, cmd, addr, flag, l);
369 if (error != EPASSTHROUGH) {
370 device_release(self);
371 return (error);
372 }
373
374 error = 0;
375
376 /*
377 * Some common checks so that individual attachments wouldn't need
378 * to duplicate them.
379 */
380 switch (cmd) {
381 case DIOCCACHESYNC:
382 /*
383 * XXX Do we really need to care about having a writable
384 * file descriptor here?
385 */
386 if ((flag & FWRITE) == 0)
387 error = EBADF;
388 else
389 error = 0;
390 break;
391 }
392
393 if (error != 0)
394 return (error);
395
396 if (sc->sc_ioctl) {
397 error = (*sc->sc_ioctl)(sc, cmd, addr, flag, 0);
398 if (error != EPASSTHROUGH)
399 return (error);
400 }
401
402 /* something not handled by the attachment */
403 return dk_ioctl(dksc, dev, cmd, addr, flag, l);
404 }
405
406 /*
407 * Flush the device's cache.
408 */
409 static int
410 ld_flush(device_t self, bool poll)
411 {
412 int error = 0;
413 struct ld_softc *sc = device_private(self);
414
415 if (sc->sc_ioctl) {
416 error = (*sc->sc_ioctl)(sc, DIOCCACHESYNC, NULL, 0, poll);
417 if (error != 0)
418 device_printf(self, "unable to flush cache\n");
419 }
420
421 return error;
422 }
423
424 static void
425 ldstrategy(struct buf *bp)
426 {
427 device_t self;
428 struct ld_softc *sc;
429 struct dk_softc *dksc;
430 int unit;
431
432 unit = DISKUNIT(bp->b_dev);
433 self = device_lookup_acquire(&ld_cd, unit);
434 if (self == NULL)
435 return;
436 sc = device_private(self);
437 dksc = &sc->sc_dksc;
438
439 dk_strategy(dksc, bp);
440 device_release(self);
441 }
442
443 static int
444 ld_diskstart(device_t dev, struct buf *bp)
445 {
446 struct ld_softc *sc;
447 int error;
448
449 device_acquire(dev);
450 sc = device_private(dev);
451 if (sc->sc_queuecnt >= sc->sc_maxqueuecnt) {
452 device_release(dev);
453 return EAGAIN;
454 }
455
456 mutex_enter(&sc->sc_mutex);
457
458 if (sc->sc_queuecnt >= sc->sc_maxqueuecnt)
459 error = EAGAIN;
460 else {
461 error = (*sc->sc_start)(sc, bp);
462 if (error == 0)
463 sc->sc_queuecnt++;
464 }
465
466 mutex_exit(&sc->sc_mutex);
467
468 device_release(dev);
469 return error;
470 }
471
472 void
473 lddone(struct ld_softc *sc, struct buf *bp)
474 {
475 struct dk_softc *dksc = &sc->sc_dksc;
476
477 dk_done(dksc, bp);
478
479 mutex_enter(&sc->sc_mutex);
480 if (--sc->sc_queuecnt <= sc->sc_maxqueuecnt) {
481 if ((sc->sc_flags & LDF_DRAIN) != 0) {
482 sc->sc_flags &= ~LDF_DRAIN;
483 cv_broadcast(&sc->sc_drain);
484 }
485 mutex_exit(&sc->sc_mutex);
486 dk_start(dksc, NULL);
487 } else
488 mutex_exit(&sc->sc_mutex);
489 }
490
491 static int
492 ldsize(dev_t dev)
493 {
494 device_t self;
495 struct ld_softc *sc;
496 struct dk_softc *dksc;
497 int unit;
498 int error;
499
500 unit = DISKUNIT(dev);
501 self = device_lookup_acquire(&ld_cd, unit);
502 if (self == NULL)
503 return (-1);
504 sc = device_private(self);
505 dksc = &sc->sc_dksc;
506
507 if ((sc->sc_flags & LDF_ENABLED) == 0)
508 return (-1);
509
510 return dk_size(dksc, dev);
511
512 device_release(self);
513 return error;
514 }
515
516 /*
517 * Take a dump.
518 */
519 static int
520 lddump(dev_t dev, daddr_t blkno, void *va, size_t size)
521 {
522 device_t self;
523 struct ld_softc *sc;
524 struct dk_softc *dksc;
525 int unit;
526 int error;
527
528 unit = DISKUNIT(dev);
529 self = device_lookup_acquire(&ld_cd, unit);
530 if (self == NULL)
531 return ENXIO;
532 sc = device_private(self);
533 dksc = &sc->sc_dksc;
534
535 if ((sc->sc_flags & LDF_ENABLED) == 0)
536 error = (ENODEV);
537 else
538 error = dk_dump(dksc, dev, blkno, va, size);
539
540 device_release(self);
541 return error;
542 }
543
544 static int
545 ld_dumpblocks(device_t dev, void *va, daddr_t blkno, int nblk)
546 {
547 struct ld_softc *sc;
548 int error;
549
550 device_acquire(dev);
551 sc = device_private(dev);
552 if (sc->sc_dump == NULL)
553 error = ENODEV;
554 else
555 error = (*sc->sc_dump)(sc, va, blkno, nblk);
556
557 device_release(dev);
558 return error;
559 }
560
561 /*
562 * Adjust the size of a transfer.
563 */
564 static void
565 ldminphys(struct buf *bp)
566 {
567 device_t self;
568 int unit;
569 struct ld_softc *sc;
570
571 unit = DISKUNIT(bp->b_dev);
572 self = device_lookup_acquire(&ld_cd, unit);
573 if (self == NULL)
574 return;
575 sc = device_private(self);
576
577 ld_iosize(sc->sc_dv, &bp->b_bcount);
578 minphys(bp);
579 device_release(self);
580 }
581
582 static void
583 ld_iosize(device_t d, int *countp)
584 {
585 struct ld_softc *sc;
586
587 device_acquire(d);
588 sc = device_private(d);
589
590 if (*countp > sc->sc_maxxfer)
591 *countp = sc->sc_maxxfer;
592
593 device_release(d);
594 }
595
596 static void
597 ld_fake_geometry(struct ld_softc *sc)
598 {
599 uint64_t ncyl;
600
601 if (sc->sc_secperunit <= 528 * 2048) /* 528MB */
602 sc->sc_nheads = 16;
603 else if (sc->sc_secperunit <= 1024 * 2048) /* 1GB */
604 sc->sc_nheads = 32;
605 else if (sc->sc_secperunit <= 21504 * 2048) /* 21GB */
606 sc->sc_nheads = 64;
607 else if (sc->sc_secperunit <= 43008 * 2048) /* 42GB */
608 sc->sc_nheads = 128;
609 else
610 sc->sc_nheads = 255;
611
612 sc->sc_nsectors = 63;
613 sc->sc_ncylinders = INT_MAX;
614 ncyl = sc->sc_secperunit /
615 (sc->sc_nheads * sc->sc_nsectors);
616 if (ncyl < INT_MAX)
617 sc->sc_ncylinders = (int)ncyl;
618 }
619
620 static void
621 ld_set_geometry(struct ld_softc *sc)
622 {
623 struct dk_softc *dksc = &sc->sc_dksc;
624 struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
625 char tbuf[9];
626
627 format_bytes(tbuf, sizeof(tbuf), sc->sc_secperunit *
628 sc->sc_secsize);
629 aprint_normal_dev(dksc->sc_dev, "%s, %d cyl, %d head, %d sec, "
630 "%d bytes/sect x %"PRIu64" sectors\n",
631 tbuf, sc->sc_ncylinders, sc->sc_nheads,
632 sc->sc_nsectors, sc->sc_secsize, sc->sc_secperunit);
633
634 memset(dg, 0, sizeof(*dg));
635 dg->dg_secperunit = sc->sc_secperunit;
636 dg->dg_secsize = sc->sc_secsize;
637 dg->dg_nsectors = sc->sc_nsectors;
638 dg->dg_ntracks = sc->sc_nheads;
639 dg->dg_ncylinders = sc->sc_ncylinders;
640
641 disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL);
642 }
643
644 static void
645 ld_config_interrupts(device_t d)
646 {
647 struct ld_softc *sc;
648 struct dk_softc *dksc;
649
650 device_acquire(d);
651 sc = device_private(d);
652 dksc = &sc->sc_dksc;
653 dkwedge_discover(&dksc->sc_dkdev);
654 device_release(d);
655 }
656
657 static int
658 ld_discard(device_t dev, off_t pos, off_t len)
659 {
660 struct ld_softc *sc;
661 int error;
662
663 device_acquire(dev);
664 sc = device_private(dev);
665 if (sc->sc_discard == NULL)
666 error = (ENODEV);
667 else
668 error = (*sc->sc_discard)(sc, pos, len);
669 device_release(dev);
670 return error;
671 }
672
673 static int
674 lddiscard(dev_t dev, off_t pos, off_t len)
675 {
676 device_t self;
677 struct ld_softc *sc;
678 struct dk_softc *dksc;
679 int unit;
680 int error;
681
682 unit = DISKUNIT(dev);
683 self = device_lookup_acquire(&ld_cd, unit);
684 if (self == NULL)
685 return ENXIO;
686 sc = device_private(self);
687 dksc = &sc->sc_dksc;
688
689 error = dk_discard(dksc, dev, pos, len);
690 device_release(self);
691 return error;
692 }
693
694 MODULE(MODULE_CLASS_DRIVER, ld, "dk_subr");
695
696 #ifdef _MODULE
697 CFDRIVER_DECL(ld, DV_DISK, NULL);
698 #endif
699
700 static int
701 ld_modcmd(modcmd_t cmd, void *opaque)
702 {
703 #ifdef _MODULE
704 devmajor_t bmajor, cmajor;
705 #endif
706 int error = 0;
707
708 #ifdef _MODULE
709 switch (cmd) {
710 case MODULE_CMD_INIT:
711 bmajor = cmajor = -1;
712 error = devsw_attach(ld_cd.cd_name, &ld_bdevsw, &bmajor,
713 &ld_cdevsw, &cmajor);
714 if (error)
715 break;
716 error = config_cfdriver_attach(&ld_cd);
717 break;
718 case MODULE_CMD_FINI:
719 error = config_cfdriver_detach(&ld_cd);
720 if (error)
721 break;
722 devsw_detach(&ld_bdevsw, &ld_cdevsw);
723 break;
724 default:
725 error = ENOTTY;
726 break;
727 }
728 #endif
729
730 return error;
731 }
732