subr_disk.c revision 50728
12061Sjkh/* 226504Sjhay * ---------------------------------------------------------------------------- 32061Sjkh * "THE BEER-WARE LICENSE" (Revision 42): 42061Sjkh * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you 515603Smarkm * can do whatever you want with this stuff. If we meet some day, and you think 63197Scsgr * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 720710Sasami * ---------------------------------------------------------------------------- 820710Sasami * 93197Scsgr * $FreeBSD: head/sys/kern/subr_disk.c 50728 1999-09-01 05:38:09Z phk $ 102061Sjkh * 1112483Speter */ 122160Scsgr 132834Swollman#include <sys/param.h> 142061Sjkh#include <sys/systm.h> 152061Sjkh#include <sys/kernel.h> 162160Scsgr#include <sys/buf.h> 1717308Speter#include <sys/conf.h> 1819320Sadam#include <sys/disk.h> 1921536Sjmacd#include <sys/malloc.h> 2025399Sjb#include <sys/vnode.h> 2125980Sasami#include <machine/md_var.h> 221594Srgrimes 2317308SpeterMALLOC_DEFINE(M_DISK, "disk", "disk data"); 2417308Speter 2517308Speterstatic d_strategy_t diskstrategy; 2617308Speterstatic d_open_t diskopen; 2717308Speterstatic d_close_t diskclose; 2817308Speterstatic d_ioctl_t diskioctl; 2917308Speterstatic d_psize_t diskpsize; 3019175Sbde 3119175Sbdestatic struct cdevsw disk_cdevsw = { 3219175Sbde /* open */ diskopen, 3319175Sbde /* close */ diskclose, 3417308Speter /* read */ physread, 3525647Sbde /* write */ physwrite, 3617308Speter /* ioctl */ diskioctl, 372061Sjkh /* stop */ nostop, 382061Sjkh /* reset */ noreset, 391594Srgrimes /* devtotty */ nodevtotty, 4025313Sbde /* poll */ nopoll, 4125313Sbde /* mmap */ nommap, 4225313Sbde /* strategy */ diskstrategy, 4325313Sbde /* name */ "disk", 4425313Sbde /* parms */ noparms, 4525313Sbde /* maj */ -1, 4625313Sbde /* dump */ nodump, 4725313Sbde /* psize */ diskpsize, 487407Srgrimes /* flags */ D_DISK, 497108Sphk /* maxio */ 0, 507108Sphk /* bmaj */ -1, 517108Sphk}; 527407Srgrimes 537407Srgrimesdev_t 547407Srgrimesdisk_create(int unit, struct disk *dp, int flags, struct cdevsw *cdevsw) 557108Sphk{ 562061Sjkh dev_t dev; 572061Sjkh struct cdevsw *cds; 582061Sjkh 5917308Speter dev = makedev(cdevsw->d_maj, 0); 602061Sjkh cds = devsw(dev); 612061Sjkh if (!cds) { 622061Sjkh /* Build the "real" cdevsw */ 632061Sjkh MALLOC(cds, struct cdevsw *, sizeof(*cds), M_DISK, M_WAITOK); 642061Sjkh *cds = disk_cdevsw; 653197Scsgr cds->d_name = cdevsw->d_name; 662626Scsgr cds->d_maj = cdevsw->d_maj; 672626Scsgr cds->d_bmaj = cdevsw->d_bmaj; 682061Sjkh cds->d_flags = cdevsw->d_flags & ~D_TRACKCLOSE; 692061Sjkh cds->d_dump = cdevsw->d_dump; 702061Sjkh 712061Sjkh cdevsw_add(cds); 722061Sjkh } 732061Sjkh 7419320Sadam printf("Creating DISK %s%d\n", cds->d_name, unit); 752061Sjkh dev = make_dev(cds, dkmakeminor(unit, WHOLE_DISK_SLICE, RAW_PART), 762061Sjkh 0, 0, 0, "r%s%d", cds->d_name, unit); 772061Sjkh 782061Sjkh bzero(dp, sizeof(*dp)); 792061Sjkh dp->d_devsw = cdevsw; 802061Sjkh dev->si_disk = dp; 812061Sjkh dp->d_dev = dev; 822061Sjkh dp->d_flags = flags; 832061Sjkh return (dev); 842061Sjkh} 852061Sjkh 862834Swollmanint 872834Swollmandisk_dumpcheck(dev_t dev, u_int *count, u_int *blkno, u_int *secsize) 882834Swollman{ 892834Swollman struct disk *dp; 902834Swollman struct disklabel *dl; 912834Swollman u_int boff; 921594Srgrimes 934486Sphk dp = dev->si_disk; 944486Sphk if (!dp) 954486Sphk return (ENXIO); 964486Sphk if (!dp->d_slice) 974486Sphk return (ENXIO); 982061Sjkh dl = dsgetlabel(dev, dp->d_slice); 992061Sjkh if (!dl) 10025979Sjkh return (ENXIO); 10125979Sjkh *count = (u_long)Maxmem * PAGE_SIZE / dl->d_secsize; 10225979Sjkh if (dumplo < 0 || 10325979Sjkh (dumplo + *count > dl->d_partitions[dkpart(dev)].p_size)) 1042061Sjkh return (EINVAL); 10525979Sjkh boff = dl->d_partitions[dkpart(dev)].p_offset + 1062061Sjkh dp->d_slice->dss_slices[dkslice(dev)].ds_offset; 1072061Sjkh *blkno = boff + dumplo; 10817308Speter *secsize = dl->d_secsize; 1092061Sjkh return (0); 1102061Sjkh 1112061Sjkh} 1122061Sjkh 1132061Sjkhvoid 11412483Speterdisk_invalidate (struct disk *disk) 11512483Speter{ 11612483Speter dsgone(&disk->d_slice); 11712483Speter} 1182061Sjkh 1192061Sjkhvoid 1208854Srgrimesdisk_delete(dev_t dev) 1212061Sjkh{ 1222061Sjkh return; 12312483Speter} 1242061Sjkh 12518714Sache/* 12618714Sache * The cdevsw functions 12718714Sache */ 12817308Speter 12917308Speterstatic int 13017308Speterdiskopen(dev_t dev, int oflags, int devtype, struct proc *p) 13117308Speter{ 13221536Sjmacd dev_t pdev; 13315603Smarkm struct disk *dp; 13417308Speter int error; 13517308Speter 13617308Speter error = 0; 13717308Speter pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); 13817308Speter 13917308Speter dp = pdev->si_disk; 14017308Speter if (!dp) 14117308Speter return (ENXIO); 14217308Speter 14318362Sjkh dev->si_disk = dp; 14419966Sache dev->si_drv1 = pdev->si_drv1; 14518362Sjkh dev->si_drv2 = pdev->si_drv2; 14617308Speter 14717308Speter if (!dsisopen(dp->d_slice)) 14817308Speter error = dp->d_devsw->d_open(dev, oflags, devtype, p); 14917308Speter 15017308Speter if (error) 15117308Speter return(error); 15216550Sjkh 1532061Sjkh error = dsopen(dev, devtype, dp->d_flags, &dp->d_slice, &dp->d_label); 15417308Speter 1552061Sjkh if (!dsisopen(dp->d_slice)) 15617308Speter dp->d_devsw->d_close(dev, oflags, devtype, p); 1572061Sjkh 15817308Speter return(error); 15917308Speter} 16017308Speter 16117308Speterstatic int 16217308Speterdiskclose(dev_t dev, int fflag, int devtype, struct proc *p) 16317308Speter{ 16417466Speter struct disk *dp; 16517308Speter int error; 16617308Speter 16717466Speter error = 0; 16817308Speter dp = dev->si_disk; 16917308Speter dsclose(dev, devtype, dp->d_slice); 17017308Speter if (dsisopen(dp->d_slice)) 17117308Speter error = dp->d_devsw->d_close(dev, fflag, devtype, p); 17217466Speter return (error); 17317308Speter} 17417308Speter 17517308Speterstatic void 17617308Speterdiskstrategy(struct buf *bp) 17717308Speter{ 17817308Speter dev_t pdev; 17917308Speter struct disk *dp; 18017308Speter 18117308Speter dp = bp->b_dev->si_disk; 18217308Speter if (!dp) { 18317308Speter pdev = dkmodpart(dkmodslice(bp->b_dev, WHOLE_DISK_SLICE), RAW_PART); 18417308Speter dp = pdev->si_disk; 18517308Speter bp->b_dev->si_drv1 = pdev->si_drv1; 18617308Speter bp->b_dev->si_drv2 = pdev->si_drv2; 18717308Speter /* XXX: don't set bp->b_dev->si_disk (?) */ 18817308Speter } else { 18917308Speter pdev = dp->d_dev; 19017308Speter } 19117308Speter 19217308Speter if (!dp) { 19317308Speter bp->b_error = ENXIO; 19417308Speter bp->b_flags |= B_ERROR; 19517308Speter biodone(bp); 19617308Speter return; 19717308Speter } 19817308Speter 19917308Speter if (dscheck(bp, dp->d_slice) < 0) { 20018392Speter biodone(bp); 20117308Speter return; 20217308Speter } 20317308Speter 20417308Speter dp->d_devsw->d_strategy(bp); 20517962Speter return; 20617308Speter 20717962Speter} 20817962Speter 20917962Speterstatic int 21017962Speterdiskioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) 21117962Speter{ 21217962Speter struct disk *dp; 21317962Speter int error; 21417962Speter 21517962Speter dp = dev->si_disk; 21617962Speter error = dsioctl(dev, cmd, data, fflag, &dp->d_slice); 21717962Speter if (error == ENOIOCTL) 21817962Speter error = dp->d_devsw->d_ioctl(dev, cmd, data, fflag, p); 21917962Speter return (error); 22017962Speter} 22117962Speter 22217308Speterstatic int 22316550Sjkhdiskpsize(dev_t dev) 22417308Speter{ 22517308Speter struct disk *dp; 22617308Speter dev_t pdev; 22717308Speter 22816550Sjkh dp = dev->si_disk; 22916550Sjkh if (!dp) { 23017308Speter pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); 23117308Speter dp = pdev->si_disk; 23219966Sache dev->si_drv1 = pdev->si_drv1; 23317962Speter dev->si_drv2 = pdev->si_drv2; 2342061Sjkh /* XXX: don't set bp->b_dev->si_disk (?) */ 23517308Speter } 23617308Speter return (dssize(dev, &dp->d_slice)); 23717308Speter} 23817308Speter