1/* 2 * ---------------------------------------------------------------------------- 3 * "THE BEER-WARE LICENSE" (Revision 42): 4 * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you 5 * can do whatever you want with this stuff. If we meet some day, and you think 6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7 * ---------------------------------------------------------------------------- 8 * |
9 * $FreeBSD: head/sys/dev/md/md.c 64880 2000-08-20 21:34:39Z phk $ |
10 * 11 */ 12 13#include "opt_mfs.h" /* We have adopted some tasks from MFS */ |
14#include "opt_md.h" 15#include "opt_devfs.h" |
16 17#include <sys/param.h> 18#include <sys/systm.h> 19#include <sys/bio.h> 20#include <sys/conf.h> 21#include <sys/devicestat.h> 22#include <sys/disk.h> 23#include <sys/kernel.h> 24#include <sys/malloc.h> 25#include <sys/sysctl.h> 26#include <sys/linker.h> |
27#include <sys/queue.h> |
28 |
29#ifdef DEVFS 30#include <sys/eventhandler.h> 31#include <fs/devfs/devfs.h> 32#endif 33 |
34#ifndef MD_NSECT 35#define MD_NSECT (10000 * 2) 36#endif 37 38MALLOC_DEFINE(M_MD, "MD disk", "Memory Disk"); 39MALLOC_DEFINE(M_MDSECT, "MD sectors", "Memory Disk Sectors"); 40 41static int md_debug; --- 12 unchanged lines hidden (view full) --- 54#if defined(MD_ROOT) && defined(MD_ROOT_SIZE) 55/* Image gets put here: */ 56static u_char mfs_root[MD_ROOT_SIZE*1024] = "MFS Filesystem goes here"; 57static u_char end_mfs_root[] __unused = "MFS Filesystem had better STOP here"; 58#endif 59 60static int mdrootready; 61 |
62static void mdcreate_malloc(int unit); |
63 64#define CDEV_MAJOR 95 65#define BDEV_MAJOR 22 66 67static d_strategy_t mdstrategy; 68static d_strategy_t mdstrategy_preload; 69static d_strategy_t mdstrategy_malloc; 70static d_open_t mdopen; --- 13 unchanged lines hidden (view full) --- 84 /* dump */ nodump, 85 /* psize */ nopsize, 86 /* flags */ D_DISK | D_CANFREE | D_MEMDISK, 87 /* bmaj */ BDEV_MAJOR 88}; 89 90static struct cdevsw mddisk_cdevsw; 91 |
92static LIST_HEAD(, md_s) md_softc_list = LIST_HEAD_INITIALIZER(&md_softc_list); 93 |
94struct md_s { 95 int unit; |
96 LIST_ENTRY(md_s) list; |
97 struct devstat stats; 98 struct bio_queue_head bio_queue; 99 struct disk disk; 100 dev_t dev; 101 int busy; 102 enum {MD_MALLOC, MD_PRELOAD} type; 103 unsigned nsect; 104 --- 14 unchanged lines hidden (view full) --- 119 struct md_s *sc; 120 struct disklabel *dl; 121 122 if (md_debug) 123 printf("mdopen(%s %x %x %p)\n", 124 devtoname(dev), flag, fmt, p); 125 126 sc = dev->si_drv1; |
127#ifndef DEVFS |
128 if (sc->unit + 1 == mdunits) |
129 mdcreate_malloc(-1); 130#endif |
131 132 dl = &sc->disk.d_label; 133 bzero(dl, sizeof(*dl)); 134 dl->d_secsize = DEV_BSIZE; 135 dl->d_nsectors = 1024; 136 dl->d_ntracks = 1; 137 dl->d_secpercyl = dl->d_nsectors * dl->d_ntracks; 138 dl->d_secperunit = sc->nsect; --- 209 unchanged lines hidden (view full) --- 348 biodone(bp); 349 s = splbio(); 350 } 351 sc->busy = 0; 352 return; 353} 354 355static struct md_s * |
356mdcreate(int unit) |
357{ 358 struct md_s *sc; 359 |
360 if (unit == -1) 361 unit = mdunits++; 362 /* Make sure this unit isn't already in action */ 363 LIST_FOREACH(sc, &md_softc_list, list) { 364 if (sc->unit == unit) 365 return (NULL); 366 } |
367 MALLOC(sc, struct md_s *,sizeof(*sc), M_MD, M_WAITOK); 368 bzero(sc, sizeof(*sc)); |
369 LIST_INSERT_HEAD(&md_softc_list, sc, list); 370 sc->unit = unit; |
371 bioq_init(&sc->bio_queue); 372 devstat_add_entry(&sc->stats, "md", sc->unit, DEV_BSIZE, 373 DEVSTAT_NO_ORDERED_TAGS, 374 DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER, 375 DEVSTAT_PRIORITY_OTHER); 376 sc->dev = disk_create(sc->unit, &sc->disk, 0, &md_cdevsw, &mddisk_cdevsw); 377 sc->dev->si_drv1 = sc; 378 return (sc); 379} 380 381static void 382mdcreate_preload(u_char *image, unsigned length) 383{ 384 struct md_s *sc; 385 |
386 sc = mdcreate(-1); |
387 sc->type = MD_PRELOAD; 388 sc->nsect = length / DEV_BSIZE; 389 sc->pl_ptr = image; 390 sc->pl_len = length; 391 392 if (sc->unit == 0) 393 mdrootready = 1; 394} 395 396static void |
397mdcreate_malloc(int unit) |
398{ 399 struct md_s *sc; 400 |
401 sc = mdcreate(unit); 402 if (sc == NULL) 403 return; 404 |
405 sc->type = MD_MALLOC; 406 407 sc->nsect = MD_NSECT; /* for now */ 408 MALLOC(sc->secp, u_char **, sizeof(u_char *), M_MD, M_WAITOK); 409 bzero(sc->secp, sizeof(u_char *)); 410 sc->nsecp = 1; 411 printf("md%d: Malloc disk\n", sc->unit); 412} 413 |
414#ifdef DEVFS |
415static void |
416md_clone (void *arg, char *name, int namelen, dev_t *dev) 417{ 418 int i, u; 419 420 if (*dev != NODEV) 421 return; 422 i = devfs_stdclone(name, NULL, "md", &u); 423 if (i == 0) 424 return; 425 /* XXX: should check that next char is [\0sa-h] */ 426 /* 427 * Now we cheat: We just create the disk, but don't match. 428 * Since we run before it, subr_disk.c::disk_clone() will 429 * find our disk and match the sought for device. 430 */ 431 mdcreate_malloc(u); 432 return; 433} 434#endif 435 436static void |
437md_drvinit(void *unused) 438{ 439 440 caddr_t mod; 441 caddr_t c; 442 u_char *ptr, *name, *type; 443 unsigned len; 444 --- 13 unchanged lines hidden (view full) --- 458 c = preload_search_info(mod, MODINFO_ADDR); 459 ptr = *(u_char **)c; 460 c = preload_search_info(mod, MODINFO_SIZE); 461 len = *(unsigned *)c; 462 printf("md%d: Preloaded image <%s> %d bytes at %p\n", 463 mdunits, name, len, ptr); 464 mdcreate_preload(ptr, len); 465 } |
466#ifdef DEVFS 467 EVENTHANDLER_REGISTER(devfs_clone, md_clone, 0, 999); 468#else 469 mdcreate_malloc(-1); 470#endif |
471} 472 473SYSINIT(mddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR, md_drvinit,NULL) 474 475#ifdef MD_ROOT 476static void 477md_takeroot(void *junk) 478{ 479 if (mdrootready) 480 rootdevnames[0] = "ufs:/dev/md0c"; 481} 482 483SYSINIT(md_root, SI_SUB_MOUNT_ROOT, SI_ORDER_FIRST, md_takeroot, NULL); 484#endif |
485 |