1da9e4f55SPoul-Henning Kamp /* 2da9e4f55SPoul-Henning Kamp * ---------------------------------------------------------------------------- 3da9e4f55SPoul-Henning Kamp * "THE BEER-WARE LICENSE" (Revision 42): 4da9e4f55SPoul-Henning Kamp * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you 5da9e4f55SPoul-Henning Kamp * can do whatever you want with this stuff. If we meet some day, and you think 6da9e4f55SPoul-Henning Kamp * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7da9e4f55SPoul-Henning Kamp * ---------------------------------------------------------------------------- 8da9e4f55SPoul-Henning Kamp * 9da9e4f55SPoul-Henning Kamp * $FreeBSD$ 10da9e4f55SPoul-Henning Kamp * 11da9e4f55SPoul-Henning Kamp */ 12da9e4f55SPoul-Henning Kamp 13417fb7f6SPoul-Henning Kamp #include "opt_geom.h" 14417fb7f6SPoul-Henning Kamp #ifndef GEOM 15417fb7f6SPoul-Henning Kamp 16da9e4f55SPoul-Henning Kamp #include <sys/param.h> 17da9e4f55SPoul-Henning Kamp #include <sys/systm.h> 18da9e4f55SPoul-Henning Kamp #include <sys/kernel.h> 1985a219d2SJulian Elischer #include <sys/sysctl.h> 209626b608SPoul-Henning Kamp #include <sys/bio.h> 21da9e4f55SPoul-Henning Kamp #include <sys/conf.h> 22da9e4f55SPoul-Henning Kamp #include <sys/disk.h> 23da9e4f55SPoul-Henning Kamp #include <sys/malloc.h> 24445572c1SNeil Blakey-Milner #include <sys/sysctl.h> 258684f73aSPoul-Henning Kamp #include <machine/md_var.h> 263f54a085SPoul-Henning Kamp #include <sys/ctype.h> 273f54a085SPoul-Henning Kamp 28959b7375SPoul-Henning Kamp static MALLOC_DEFINE(M_DISK, "disk", "disk data"); 29da9e4f55SPoul-Henning Kamp 30da9e4f55SPoul-Henning Kamp static d_strategy_t diskstrategy; 31da9e4f55SPoul-Henning Kamp static d_open_t diskopen; 32da9e4f55SPoul-Henning Kamp static d_close_t diskclose; 33da9e4f55SPoul-Henning Kamp static d_ioctl_t diskioctl; 34da9e4f55SPoul-Henning Kamp static d_psize_t diskpsize; 35da9e4f55SPoul-Henning Kamp 364bd02a56SPoul-Henning Kamp static LIST_HEAD(, disk) disklist = LIST_HEAD_INITIALIZER(&disklist); 374bd02a56SPoul-Henning Kamp 384e4a7663SPoul-Henning Kamp void disk_dev_synth(dev_t dev); 394e4a7663SPoul-Henning Kamp 404e4a7663SPoul-Henning Kamp void 414e4a7663SPoul-Henning Kamp disk_dev_synth(dev_t dev) 424e4a7663SPoul-Henning Kamp { 434e4a7663SPoul-Henning Kamp struct disk *dp; 444e4a7663SPoul-Henning Kamp int u, s, p; 454e4a7663SPoul-Henning Kamp dev_t pdev; 464e4a7663SPoul-Henning Kamp 4720a3b67cSPoul-Henning Kamp if (dksparebits(dev)) 48b456f7e6SPoul-Henning Kamp return; 494e4a7663SPoul-Henning Kamp LIST_FOREACH(dp, &disklist, d_list) { 504e4a7663SPoul-Henning Kamp if (major(dev) != dp->d_devsw->d_maj) 514e4a7663SPoul-Henning Kamp continue; 524e4a7663SPoul-Henning Kamp u = dkunit(dev); 534e4a7663SPoul-Henning Kamp p = RAW_PART; 544e4a7663SPoul-Henning Kamp s = WHOLE_DISK_SLICE; 554e4a7663SPoul-Henning Kamp pdev = makedev(dp->d_devsw->d_maj, dkmakeminor(u, s, p)); 564e130067SPoul-Henning Kamp if (pdev->si_devsw == NULL) 574e130067SPoul-Henning Kamp return; /* Probably a unit we don't have */ 584e4a7663SPoul-Henning Kamp s = dkslice(dev); 594e4a7663SPoul-Henning Kamp p = dkpart(dev); 604e4a7663SPoul-Henning Kamp if (s == WHOLE_DISK_SLICE && p == RAW_PART) { 614e4a7663SPoul-Henning Kamp /* XXX: actually should not happen */ 624e4a7663SPoul-Henning Kamp dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), 634e4a7663SPoul-Henning Kamp UID_ROOT, GID_OPERATOR, 0640, "%s%d", 644e4a7663SPoul-Henning Kamp dp->d_devsw->d_name, u); 654e4a7663SPoul-Henning Kamp dev_depends(pdev, dev); 664e4a7663SPoul-Henning Kamp return; 674e4a7663SPoul-Henning Kamp } 684e4a7663SPoul-Henning Kamp if (s == COMPATIBILITY_SLICE) { 694e4a7663SPoul-Henning Kamp dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), 704e4a7663SPoul-Henning Kamp UID_ROOT, GID_OPERATOR, 0640, "%s%d%c", 714e4a7663SPoul-Henning Kamp dp->d_devsw->d_name, u, 'a' + p); 724e4a7663SPoul-Henning Kamp dev_depends(pdev, dev); 734e4a7663SPoul-Henning Kamp return; 744e4a7663SPoul-Henning Kamp } 75a2d7281cSPoul-Henning Kamp if (p != RAW_PART) { 764e4a7663SPoul-Henning Kamp dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), 774e4a7663SPoul-Henning Kamp UID_ROOT, GID_OPERATOR, 0640, "%s%ds%d%c", 78a2d7281cSPoul-Henning Kamp dp->d_devsw->d_name, u, s - BASE_SLICE + 1, 79a2d7281cSPoul-Henning Kamp 'a' + p); 80a2d7281cSPoul-Henning Kamp } else { 81a2d7281cSPoul-Henning Kamp dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), 82a2d7281cSPoul-Henning Kamp UID_ROOT, GID_OPERATOR, 0640, "%s%ds%d", 834e4a7663SPoul-Henning Kamp dp->d_devsw->d_name, u, s - BASE_SLICE + 1); 84a2d7281cSPoul-Henning Kamp make_dev_alias(dev, "%s%ds%dc", 85a2d7281cSPoul-Henning Kamp dp->d_devsw->d_name, u, s - BASE_SLICE + 1); 86a2d7281cSPoul-Henning Kamp } 87a2d7281cSPoul-Henning Kamp dev_depends(pdev, dev); 884e4a7663SPoul-Henning Kamp return; 894e4a7663SPoul-Henning Kamp } 904e4a7663SPoul-Henning Kamp } 914e4a7663SPoul-Henning Kamp 923f54a085SPoul-Henning Kamp static void 933f54a085SPoul-Henning Kamp disk_clone(void *arg, char *name, int namelen, dev_t *dev) 943f54a085SPoul-Henning Kamp { 953f54a085SPoul-Henning Kamp struct disk *dp; 963f54a085SPoul-Henning Kamp char const *d; 97417fb7f6SPoul-Henning Kamp char *e; 98417fb7f6SPoul-Henning Kamp int j, u, s, p; 993f54a085SPoul-Henning Kamp dev_t pdev; 1003f54a085SPoul-Henning Kamp 1013f54a085SPoul-Henning Kamp if (*dev != NODEV) 1023f54a085SPoul-Henning Kamp return; 1033f54a085SPoul-Henning Kamp 1043f54a085SPoul-Henning Kamp LIST_FOREACH(dp, &disklist, d_list) { 1053f54a085SPoul-Henning Kamp d = dp->d_devsw->d_name; 106417fb7f6SPoul-Henning Kamp j = dev_stdclone(name, &e, d, &u); 107417fb7f6SPoul-Henning Kamp if (j == 0) 1083f54a085SPoul-Henning Kamp continue; 109f84ee0ffSPoul-Henning Kamp if (u > DKMAXUNIT) 110f84ee0ffSPoul-Henning Kamp continue; 1113f54a085SPoul-Henning Kamp p = RAW_PART; 1123f54a085SPoul-Henning Kamp s = WHOLE_DISK_SLICE; 1133f54a085SPoul-Henning Kamp pdev = makedev(dp->d_devsw->d_maj, dkmakeminor(u, s, p)); 1143f54a085SPoul-Henning Kamp if (pdev->si_disk == NULL) 1153f54a085SPoul-Henning Kamp continue; 116417fb7f6SPoul-Henning Kamp if (*e != '\0') { 117417fb7f6SPoul-Henning Kamp j = dev_stdclone(e, &e, "s", &s); 118417fb7f6SPoul-Henning Kamp if (j == 0) 1193f54a085SPoul-Henning Kamp s = COMPATIBILITY_SLICE; 120417fb7f6SPoul-Henning Kamp else if (j == 1 || j == 2) 121417fb7f6SPoul-Henning Kamp s += BASE_SLICE - 1; 122417fb7f6SPoul-Henning Kamp if (!*e) 123417fb7f6SPoul-Henning Kamp ; /* ad0s1 case */ 124417fb7f6SPoul-Henning Kamp else if (e[1] != '\0') 125417fb7f6SPoul-Henning Kamp return; /* can never be a disk name */ 126417fb7f6SPoul-Henning Kamp else if (*e < 'a' || *e > 'h') 127417fb7f6SPoul-Henning Kamp return; /* can never be a disk name */ 1283f54a085SPoul-Henning Kamp else 129417fb7f6SPoul-Henning Kamp p = *e - 'a'; 1303f54a085SPoul-Henning Kamp } 131417fb7f6SPoul-Henning Kamp if (s == WHOLE_DISK_SLICE && p == RAW_PART) { 132417fb7f6SPoul-Henning Kamp return; 133417fb7f6SPoul-Henning Kamp } else if (s >= BASE_SLICE && p != RAW_PART) { 1344e4a7663SPoul-Henning Kamp *dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), 1354e4a7663SPoul-Henning Kamp UID_ROOT, GID_OPERATOR, 0640, "%s%ds%d%c", 136a2d7281cSPoul-Henning Kamp pdev->si_devsw->d_name, u, s - BASE_SLICE + 1, 137a2d7281cSPoul-Henning Kamp p + 'a'); 138a2d7281cSPoul-Henning Kamp } else if (s >= BASE_SLICE) { 139a2d7281cSPoul-Henning Kamp *dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), 140a2d7281cSPoul-Henning Kamp UID_ROOT, GID_OPERATOR, 0640, "%s%ds%d", 141a2d7281cSPoul-Henning Kamp pdev->si_devsw->d_name, u, s - BASE_SLICE + 1); 142a2d7281cSPoul-Henning Kamp make_dev_alias(*dev, "%s%ds%dc", 143a2d7281cSPoul-Henning Kamp pdev->si_devsw->d_name, u, s - BASE_SLICE + 1); 144a2d7281cSPoul-Henning Kamp } else { 1453f54a085SPoul-Henning Kamp *dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), 146417fb7f6SPoul-Henning Kamp UID_ROOT, GID_OPERATOR, 0640, "%s%d%c", 147417fb7f6SPoul-Henning Kamp pdev->si_devsw->d_name, u, p + 'a'); 1484e4a7663SPoul-Henning Kamp } 149a2d7281cSPoul-Henning Kamp dev_depends(pdev, *dev); 1503f54a085SPoul-Henning Kamp return; 1513f54a085SPoul-Henning Kamp } 1523f54a085SPoul-Henning Kamp } 1533f54a085SPoul-Henning Kamp 1545d10777cSWarner Losh static void 1555d10777cSWarner Losh inherit_raw(dev_t pdev, dev_t dev) 1565d10777cSWarner Losh { 1575d10777cSWarner Losh dev->si_disk = pdev->si_disk; 1585d10777cSWarner Losh dev->si_drv1 = pdev->si_drv1; 1595d10777cSWarner Losh dev->si_drv2 = pdev->si_drv2; 1605d10777cSWarner Losh dev->si_iosize_max = pdev->si_iosize_max; 1615d10777cSWarner Losh dev->si_bsize_phys = pdev->si_bsize_phys; 1625d10777cSWarner Losh dev->si_bsize_best = pdev->si_bsize_best; 1635d10777cSWarner Losh } 1645d10777cSWarner Losh 165da9e4f55SPoul-Henning Kamp dev_t 1662016e4e9SPoul-Henning Kamp disk_create(int unit, struct disk *dp, int flags, struct cdevsw *cdevsw, struct cdevsw *proto) 167da9e4f55SPoul-Henning Kamp { 1683f54a085SPoul-Henning Kamp static int once; 16922628ccfSPoul-Henning Kamp dev_t dev; 1703344c5a1SPoul-Henning Kamp 1713344c5a1SPoul-Henning Kamp if (!once) { 1723344c5a1SPoul-Henning Kamp EVENTHANDLER_REGISTER(dev_clone, disk_clone, 0, 1000); 1733344c5a1SPoul-Henning Kamp once++; 1743344c5a1SPoul-Henning Kamp } 175da9e4f55SPoul-Henning Kamp 1768684f73aSPoul-Henning Kamp bzero(dp, sizeof(*dp)); 1773febdd8fSPoul-Henning Kamp 1788576c652SPoul-Henning Kamp if (proto->d_open != diskopen) { 1792016e4e9SPoul-Henning Kamp *proto = *cdevsw; 1802016e4e9SPoul-Henning Kamp proto->d_open = diskopen; 1812016e4e9SPoul-Henning Kamp proto->d_close = diskclose; 1822016e4e9SPoul-Henning Kamp proto->d_ioctl = diskioctl; 1832016e4e9SPoul-Henning Kamp proto->d_strategy = diskstrategy; 1842016e4e9SPoul-Henning Kamp proto->d_psize = diskpsize; 1853febdd8fSPoul-Henning Kamp } 1863febdd8fSPoul-Henning Kamp 1878d67e113SJordan K. Hubbard if (bootverbose) 1883febdd8fSPoul-Henning Kamp printf("Creating DISK %s%d\n", cdevsw->d_name, unit); 189abd1f573SPoul-Henning Kamp dev = make_dev(proto, dkmakeminor(unit, WHOLE_DISK_SLICE, RAW_PART), 1903f54a085SPoul-Henning Kamp UID_ROOT, GID_OPERATOR, 0640, "%s%d", cdevsw->d_name, unit); 1913febdd8fSPoul-Henning Kamp 192da9e4f55SPoul-Henning Kamp dev->si_disk = dp; 193da9e4f55SPoul-Henning Kamp dp->d_dev = dev; 1948db34b3aSPoul-Henning Kamp dp->d_dsflags = flags; 1952016e4e9SPoul-Henning Kamp dp->d_devsw = cdevsw; 1964bd02a56SPoul-Henning Kamp LIST_INSERT_HEAD(&disklist, dp, d_list); 1973344c5a1SPoul-Henning Kamp 198da9e4f55SPoul-Henning Kamp return (dev); 199da9e4f55SPoul-Henning Kamp } 200da9e4f55SPoul-Henning Kamp 2018684f73aSPoul-Henning Kamp int 2028684f73aSPoul-Henning Kamp disk_dumpcheck(dev_t dev, u_int *count, u_int *blkno, u_int *secsize) 2038684f73aSPoul-Henning Kamp { 2048684f73aSPoul-Henning Kamp struct disk *dp; 2058684f73aSPoul-Henning Kamp struct disklabel *dl; 2068684f73aSPoul-Henning Kamp u_int boff; 2078684f73aSPoul-Henning Kamp 2088684f73aSPoul-Henning Kamp dp = dev->si_disk; 2098684f73aSPoul-Henning Kamp if (!dp) 2108684f73aSPoul-Henning Kamp return (ENXIO); 2118684f73aSPoul-Henning Kamp if (!dp->d_slice) 2128684f73aSPoul-Henning Kamp return (ENXIO); 2138684f73aSPoul-Henning Kamp dl = dsgetlabel(dev, dp->d_slice); 2148684f73aSPoul-Henning Kamp if (!dl) 2158684f73aSPoul-Henning Kamp return (ENXIO); 216a572c95cSBruce Evans *count = Maxmem * (PAGE_SIZE / dl->d_secsize); 217a572c95cSBruce Evans if (dumplo <= LABELSECTOR || 2188684f73aSPoul-Henning Kamp (dumplo + *count > dl->d_partitions[dkpart(dev)].p_size)) 2198684f73aSPoul-Henning Kamp return (EINVAL); 2208684f73aSPoul-Henning Kamp boff = dl->d_partitions[dkpart(dev)].p_offset + 2218684f73aSPoul-Henning Kamp dp->d_slice->dss_slices[dkslice(dev)].ds_offset; 2228684f73aSPoul-Henning Kamp *blkno = boff + dumplo; 2238684f73aSPoul-Henning Kamp *secsize = dl->d_secsize; 2248684f73aSPoul-Henning Kamp return (0); 2258684f73aSPoul-Henning Kamp 2268684f73aSPoul-Henning Kamp } 2278684f73aSPoul-Henning Kamp 2288684f73aSPoul-Henning Kamp void 2298684f73aSPoul-Henning Kamp disk_invalidate (struct disk *disk) 2308684f73aSPoul-Henning Kamp { 23147351d27SSøren Schmidt if (disk->d_slice) 2328684f73aSPoul-Henning Kamp dsgone(&disk->d_slice); 2338684f73aSPoul-Henning Kamp } 2348684f73aSPoul-Henning Kamp 235da9e4f55SPoul-Henning Kamp void 2361edde29eSPoul-Henning Kamp disk_destroy(dev_t dev) 237da9e4f55SPoul-Henning Kamp { 2384bd02a56SPoul-Henning Kamp LIST_REMOVE(dev->si_disk, d_list); 2394bd02a56SPoul-Henning Kamp bzero(dev->si_disk, sizeof(*dev->si_disk)); 24047351d27SSøren Schmidt dev->si_disk = NULL; 24147351d27SSøren Schmidt destroy_dev(dev); 242da9e4f55SPoul-Henning Kamp return; 243da9e4f55SPoul-Henning Kamp } 244da9e4f55SPoul-Henning Kamp 2454bd02a56SPoul-Henning Kamp struct disk * 2464bd02a56SPoul-Henning Kamp disk_enumerate(struct disk *disk) 2474bd02a56SPoul-Henning Kamp { 2484bd02a56SPoul-Henning Kamp if (!disk) 2494bd02a56SPoul-Henning Kamp return (LIST_FIRST(&disklist)); 2504bd02a56SPoul-Henning Kamp else 2514bd02a56SPoul-Henning Kamp return (LIST_NEXT(disk, d_list)); 2524bd02a56SPoul-Henning Kamp } 2534bd02a56SPoul-Henning Kamp 254445572c1SNeil Blakey-Milner static int 25582d9ae4eSPoul-Henning Kamp sysctl_disks(SYSCTL_HANDLER_ARGS) 256445572c1SNeil Blakey-Milner { 257445572c1SNeil Blakey-Milner struct disk *disk; 258445572c1SNeil Blakey-Milner int error, first; 259445572c1SNeil Blakey-Milner 260445572c1SNeil Blakey-Milner disk = NULL; 261445572c1SNeil Blakey-Milner first = 1; 262445572c1SNeil Blakey-Milner 263445572c1SNeil Blakey-Milner while ((disk = disk_enumerate(disk))) { 264445572c1SNeil Blakey-Milner if (!first) { 265445572c1SNeil Blakey-Milner error = SYSCTL_OUT(req, " ", 1); 266445572c1SNeil Blakey-Milner if (error) 267445572c1SNeil Blakey-Milner return error; 268445572c1SNeil Blakey-Milner } else { 269445572c1SNeil Blakey-Milner first = 0; 270445572c1SNeil Blakey-Milner } 271445572c1SNeil Blakey-Milner error = SYSCTL_OUT(req, disk->d_dev->si_name, strlen(disk->d_dev->si_name)); 272445572c1SNeil Blakey-Milner if (error) 273445572c1SNeil Blakey-Milner return error; 274445572c1SNeil Blakey-Milner } 275445572c1SNeil Blakey-Milner error = SYSCTL_OUT(req, "", 1); 276445572c1SNeil Blakey-Milner return error; 277445572c1SNeil Blakey-Milner } 278445572c1SNeil Blakey-Milner 279445572c1SNeil Blakey-Milner SYSCTL_PROC(_kern, OID_AUTO, disks, CTLTYPE_STRING | CTLFLAG_RD, 0, NULL, 280445572c1SNeil Blakey-Milner sysctl_disks, "A", "names of available disks"); 281445572c1SNeil Blakey-Milner 2828684f73aSPoul-Henning Kamp /* 2838684f73aSPoul-Henning Kamp * The cdevsw functions 2848684f73aSPoul-Henning Kamp */ 2858684f73aSPoul-Henning Kamp 286da9e4f55SPoul-Henning Kamp static int 287b40ce416SJulian Elischer diskopen(dev_t dev, int oflags, int devtype, struct thread *td) 288da9e4f55SPoul-Henning Kamp { 289da9e4f55SPoul-Henning Kamp dev_t pdev; 290da9e4f55SPoul-Henning Kamp struct disk *dp; 291da9e4f55SPoul-Henning Kamp int error; 292da9e4f55SPoul-Henning Kamp 2938684f73aSPoul-Henning Kamp error = 0; 294da9e4f55SPoul-Henning Kamp pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); 2958684f73aSPoul-Henning Kamp 296da9e4f55SPoul-Henning Kamp dp = pdev->si_disk; 297da9e4f55SPoul-Henning Kamp if (!dp) 298da9e4f55SPoul-Henning Kamp return (ENXIO); 2998684f73aSPoul-Henning Kamp 3008db34b3aSPoul-Henning Kamp while (dp->d_flags & DISKFLAG_LOCK) { 3018db34b3aSPoul-Henning Kamp dp->d_flags |= DISKFLAG_WANTED; 3021b4ce5ceSPoul-Henning Kamp error = tsleep(dp, PRIBIO | PCATCH, "diskopen", hz); 3031b4ce5ceSPoul-Henning Kamp if (error) 3041b4ce5ceSPoul-Henning Kamp return (error); 3058db34b3aSPoul-Henning Kamp } 3068db34b3aSPoul-Henning Kamp dp->d_flags |= DISKFLAG_LOCK; 3078db34b3aSPoul-Henning Kamp 30845604de3SPoul-Henning Kamp if (!dsisopen(dp->d_slice)) { 309dc722a14SSøren Schmidt if (!pdev->si_iosize_max) 31045604de3SPoul-Henning Kamp pdev->si_iosize_max = dev->si_iosize_max; 311b40ce416SJulian Elischer error = dp->d_devsw->d_open(pdev, oflags, devtype, td); 31245604de3SPoul-Henning Kamp } 31366c12520SPoul-Henning Kamp 31466c12520SPoul-Henning Kamp /* Inherit properties from the whole/raw dev_t */ 3155d10777cSWarner Losh inherit_raw(pdev, dev); 3168684f73aSPoul-Henning Kamp 317da9e4f55SPoul-Henning Kamp if (error) 3188db34b3aSPoul-Henning Kamp goto out; 319da9e4f55SPoul-Henning Kamp 3208db34b3aSPoul-Henning Kamp error = dsopen(dev, devtype, dp->d_dsflags, &dp->d_slice, &dp->d_label); 321da9e4f55SPoul-Henning Kamp 3228684f73aSPoul-Henning Kamp if (!dsisopen(dp->d_slice)) 323b40ce416SJulian Elischer dp->d_devsw->d_close(pdev, oflags, devtype, td); 3248db34b3aSPoul-Henning Kamp out: 3258db34b3aSPoul-Henning Kamp dp->d_flags &= ~DISKFLAG_LOCK; 3268db34b3aSPoul-Henning Kamp if (dp->d_flags & DISKFLAG_WANTED) { 3278db34b3aSPoul-Henning Kamp dp->d_flags &= ~DISKFLAG_WANTED; 3288db34b3aSPoul-Henning Kamp wakeup(dp); 3298db34b3aSPoul-Henning Kamp } 3308684f73aSPoul-Henning Kamp 331da9e4f55SPoul-Henning Kamp return(error); 332da9e4f55SPoul-Henning Kamp } 333da9e4f55SPoul-Henning Kamp 334da9e4f55SPoul-Henning Kamp static int 335b40ce416SJulian Elischer diskclose(dev_t dev, int fflag, int devtype, struct thread *td) 336da9e4f55SPoul-Henning Kamp { 337da9e4f55SPoul-Henning Kamp struct disk *dp; 338da9e4f55SPoul-Henning Kamp int error; 3395d10777cSWarner Losh dev_t pdev; 340da9e4f55SPoul-Henning Kamp 341da9e4f55SPoul-Henning Kamp error = 0; 3425d10777cSWarner Losh pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); 3435d10777cSWarner Losh dp = pdev->si_disk; 344b417a1a8SSøren Schmidt if (!dp) 345b417a1a8SSøren Schmidt return (ENXIO); 34646a706dcSMike Smith dsclose(dev, devtype, dp->d_slice); 347b417a1a8SSøren Schmidt if (!dsisopen(dp->d_slice)) 348b40ce416SJulian Elischer error = dp->d_devsw->d_close(dp->d_dev, fflag, devtype, td); 349da9e4f55SPoul-Henning Kamp return (error); 350da9e4f55SPoul-Henning Kamp } 351da9e4f55SPoul-Henning Kamp 352da9e4f55SPoul-Henning Kamp static void 3538177437dSPoul-Henning Kamp diskstrategy(struct bio *bp) 354da9e4f55SPoul-Henning Kamp { 355da9e4f55SPoul-Henning Kamp dev_t pdev; 356da9e4f55SPoul-Henning Kamp struct disk *dp; 357da9e4f55SPoul-Henning Kamp 3588177437dSPoul-Henning Kamp pdev = dkmodpart(dkmodslice(bp->bio_dev, WHOLE_DISK_SLICE), RAW_PART); 3595d10777cSWarner Losh dp = pdev->si_disk; 360e0e0b661SPoul-Henning Kamp bp->bio_resid = bp->bio_bcount; 3615d10777cSWarner Losh if (dp != bp->bio_dev->si_disk) 3625d10777cSWarner Losh inherit_raw(pdev, bp->bio_dev); 363da9e4f55SPoul-Henning Kamp 364da9e4f55SPoul-Henning Kamp if (!dp) { 365a468031cSPoul-Henning Kamp biofinish(bp, NULL, ENXIO); 366da9e4f55SPoul-Henning Kamp return; 367da9e4f55SPoul-Henning Kamp } 368da9e4f55SPoul-Henning Kamp 369d685023eSPoul-Henning Kamp if (dscheck(bp, dp->d_slice) <= 0) { 370da9e4f55SPoul-Henning Kamp biodone(bp); 371da9e4f55SPoul-Henning Kamp return; 372da9e4f55SPoul-Henning Kamp } 373da9e4f55SPoul-Henning Kamp 374079f2df3SPoul-Henning Kamp if (bp->bio_bcount == 0) { 375079f2df3SPoul-Henning Kamp biodone(bp); 376079f2df3SPoul-Henning Kamp return; 377079f2df3SPoul-Henning Kamp } 378079f2df3SPoul-Henning Kamp 37967f3c95cSPoul-Henning Kamp KASSERT(dp->d_devsw != NULL, ("NULL devsw")); 38067f3c95cSPoul-Henning Kamp KASSERT(dp->d_devsw->d_strategy != NULL, ("NULL d_strategy")); 3812016e4e9SPoul-Henning Kamp dp->d_devsw->d_strategy(bp); 382da9e4f55SPoul-Henning Kamp return; 383da9e4f55SPoul-Henning Kamp 384da9e4f55SPoul-Henning Kamp } 385da9e4f55SPoul-Henning Kamp 386da9e4f55SPoul-Henning Kamp static int 387b40ce416SJulian Elischer diskioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td) 388da9e4f55SPoul-Henning Kamp { 389da9e4f55SPoul-Henning Kamp struct disk *dp; 390da9e4f55SPoul-Henning Kamp int error; 3915d10777cSWarner Losh dev_t pdev; 392da9e4f55SPoul-Henning Kamp 3935d10777cSWarner Losh pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); 3945d10777cSWarner Losh dp = pdev->si_disk; 395b417a1a8SSøren Schmidt if (!dp) 396b417a1a8SSøren Schmidt return (ENXIO); 397da9e4f55SPoul-Henning Kamp error = dsioctl(dev, cmd, data, fflag, &dp->d_slice); 398da9e4f55SPoul-Henning Kamp if (error == ENOIOCTL) 399b40ce416SJulian Elischer error = dp->d_devsw->d_ioctl(dev, cmd, data, fflag, td); 400da9e4f55SPoul-Henning Kamp return (error); 401da9e4f55SPoul-Henning Kamp } 402da9e4f55SPoul-Henning Kamp 403da9e4f55SPoul-Henning Kamp static int 404da9e4f55SPoul-Henning Kamp diskpsize(dev_t dev) 405da9e4f55SPoul-Henning Kamp { 406da9e4f55SPoul-Henning Kamp struct disk *dp; 4078684f73aSPoul-Henning Kamp dev_t pdev; 408da9e4f55SPoul-Henning Kamp 4098684f73aSPoul-Henning Kamp pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); 4108684f73aSPoul-Henning Kamp dp = pdev->si_disk; 411a4fcac54SBruce Evans if (!dp) 412a4fcac54SBruce Evans return (-1); 4135d10777cSWarner Losh if (dp != dev->si_disk) { 4148684f73aSPoul-Henning Kamp dev->si_drv1 = pdev->si_drv1; 4158684f73aSPoul-Henning Kamp dev->si_drv2 = pdev->si_drv2; 4168684f73aSPoul-Henning Kamp /* XXX: don't set bp->b_dev->si_disk (?) */ 4178684f73aSPoul-Henning Kamp } 418da9e4f55SPoul-Henning Kamp return (dssize(dev, &dp->d_slice)); 419da9e4f55SPoul-Henning Kamp } 42085a219d2SJulian Elischer 42185a219d2SJulian Elischer SYSCTL_INT(_debug_sizeof, OID_AUTO, disklabel, CTLFLAG_RD, 42285a219d2SJulian Elischer 0, sizeof(struct disklabel), "sizeof(struct disklabel)"); 42385a219d2SJulian Elischer 42485a219d2SJulian Elischer SYSCTL_INT(_debug_sizeof, OID_AUTO, diskslices, CTLFLAG_RD, 42585a219d2SJulian Elischer 0, sizeof(struct diskslices), "sizeof(struct diskslices)"); 42685a219d2SJulian Elischer 42785a219d2SJulian Elischer SYSCTL_INT(_debug_sizeof, OID_AUTO, disk, CTLFLAG_RD, 42885a219d2SJulian Elischer 0, sizeof(struct disk), "sizeof(struct disk)"); 429417fb7f6SPoul-Henning Kamp 430417fb7f6SPoul-Henning Kamp #endif 431