10 * 11 */ 12 13#include <sys/param.h> 14#include <sys/systm.h> 15#include <sys/kernel.h> 16#include <sys/sysctl.h> 17#include <sys/buf.h> 18#include <sys/conf.h> 19#include <sys/disk.h> 20#include <sys/malloc.h> 21#include <machine/md_var.h> 22 23MALLOC_DEFINE(M_DISK, "disk", "disk data"); 24 25static d_strategy_t diskstrategy; 26static d_open_t diskopen; 27static d_close_t diskclose; 28static d_ioctl_t diskioctl; 29static d_psize_t diskpsize; 30 31dev_t 32disk_create(int unit, struct disk *dp, int flags, struct cdevsw *cdevsw, struct cdevsw *proto) 33{ 34 dev_t dev; 35 36 bzero(dp, sizeof(*dp)); 37 38 dev = makedev(cdevsw->d_maj, 0); 39 if (!devsw(dev)) { 40 *proto = *cdevsw; 41 proto->d_open = diskopen; 42 proto->d_close = diskclose; 43 proto->d_ioctl = diskioctl; 44 proto->d_strategy = diskstrategy; 45 proto->d_psize = diskpsize; 46 cdevsw_add(proto); 47 } 48 49 if (bootverbose) 50 printf("Creating DISK %s%d\n", cdevsw->d_name, unit); 51 dev = make_dev(proto, dkmakeminor(unit, WHOLE_DISK_SLICE, RAW_PART), 52 0, 0, 0, "r%s%d", cdevsw->d_name, unit); 53 54 dev->si_disk = dp; 55 dp->d_dev = dev; 56 dp->d_dsflags = flags; 57 dp->d_devsw = cdevsw; 58 return (dev); 59} 60 61int 62disk_dumpcheck(dev_t dev, u_int *count, u_int *blkno, u_int *secsize) 63{ 64 struct disk *dp; 65 struct disklabel *dl; 66 u_int boff; 67 68 dp = dev->si_disk; 69 if (!dp) 70 return (ENXIO); 71 if (!dp->d_slice) 72 return (ENXIO); 73 dl = dsgetlabel(dev, dp->d_slice); 74 if (!dl) 75 return (ENXIO); 76 *count = (u_long)Maxmem * PAGE_SIZE / dl->d_secsize; 77 if (dumplo < 0 || 78 (dumplo + *count > dl->d_partitions[dkpart(dev)].p_size)) 79 return (EINVAL); 80 boff = dl->d_partitions[dkpart(dev)].p_offset + 81 dp->d_slice->dss_slices[dkslice(dev)].ds_offset; 82 *blkno = boff + dumplo; 83 *secsize = dl->d_secsize; 84 return (0); 85 86} 87 88void 89disk_invalidate (struct disk *disk) 90{
| 10 * 11 */ 12 13#include <sys/param.h> 14#include <sys/systm.h> 15#include <sys/kernel.h> 16#include <sys/sysctl.h> 17#include <sys/buf.h> 18#include <sys/conf.h> 19#include <sys/disk.h> 20#include <sys/malloc.h> 21#include <machine/md_var.h> 22 23MALLOC_DEFINE(M_DISK, "disk", "disk data"); 24 25static d_strategy_t diskstrategy; 26static d_open_t diskopen; 27static d_close_t diskclose; 28static d_ioctl_t diskioctl; 29static d_psize_t diskpsize; 30 31dev_t 32disk_create(int unit, struct disk *dp, int flags, struct cdevsw *cdevsw, struct cdevsw *proto) 33{ 34 dev_t dev; 35 36 bzero(dp, sizeof(*dp)); 37 38 dev = makedev(cdevsw->d_maj, 0); 39 if (!devsw(dev)) { 40 *proto = *cdevsw; 41 proto->d_open = diskopen; 42 proto->d_close = diskclose; 43 proto->d_ioctl = diskioctl; 44 proto->d_strategy = diskstrategy; 45 proto->d_psize = diskpsize; 46 cdevsw_add(proto); 47 } 48 49 if (bootverbose) 50 printf("Creating DISK %s%d\n", cdevsw->d_name, unit); 51 dev = make_dev(proto, dkmakeminor(unit, WHOLE_DISK_SLICE, RAW_PART), 52 0, 0, 0, "r%s%d", cdevsw->d_name, unit); 53 54 dev->si_disk = dp; 55 dp->d_dev = dev; 56 dp->d_dsflags = flags; 57 dp->d_devsw = cdevsw; 58 return (dev); 59} 60 61int 62disk_dumpcheck(dev_t dev, u_int *count, u_int *blkno, u_int *secsize) 63{ 64 struct disk *dp; 65 struct disklabel *dl; 66 u_int boff; 67 68 dp = dev->si_disk; 69 if (!dp) 70 return (ENXIO); 71 if (!dp->d_slice) 72 return (ENXIO); 73 dl = dsgetlabel(dev, dp->d_slice); 74 if (!dl) 75 return (ENXIO); 76 *count = (u_long)Maxmem * PAGE_SIZE / dl->d_secsize; 77 if (dumplo < 0 || 78 (dumplo + *count > dl->d_partitions[dkpart(dev)].p_size)) 79 return (EINVAL); 80 boff = dl->d_partitions[dkpart(dev)].p_offset + 81 dp->d_slice->dss_slices[dkslice(dev)].ds_offset; 82 *blkno = boff + dumplo; 83 *secsize = dl->d_secsize; 84 return (0); 85 86} 87 88void 89disk_invalidate (struct disk *disk) 90{
|
97 return; 98} 99 100/* 101 * The cdevsw functions 102 */ 103 104static int 105diskopen(dev_t dev, int oflags, int devtype, struct proc *p) 106{ 107 dev_t pdev; 108 struct disk *dp; 109 int error; 110 111 error = 0; 112 pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); 113 114 dp = pdev->si_disk; 115 if (!dp) 116 return (ENXIO); 117 118 while (dp->d_flags & DISKFLAG_LOCK) { 119 dp->d_flags |= DISKFLAG_WANTED; 120 error = tsleep(dp, PRIBIO | PCATCH, "diskopen", hz); 121 if (error) 122 return (error); 123 } 124 dp->d_flags |= DISKFLAG_LOCK; 125 126 if (!dsisopen(dp->d_slice)) { 127 if (!pdev->si_iosize_max) 128 pdev->si_iosize_max = dev->si_iosize_max; 129 error = dp->d_devsw->d_open(pdev, oflags, devtype, p); 130 } 131 132 /* Inherit properties from the whole/raw dev_t */ 133 dev->si_disk = pdev->si_disk; 134 dev->si_drv1 = pdev->si_drv1; 135 dev->si_drv2 = pdev->si_drv2; 136 dev->si_iosize_max = pdev->si_iosize_max; 137 dev->si_bsize_phys = pdev->si_bsize_phys; 138 dev->si_bsize_best = pdev->si_bsize_best; 139 140 if (error) 141 goto out; 142 143 error = dsopen(dev, devtype, dp->d_dsflags, &dp->d_slice, &dp->d_label); 144 145 if (!dsisopen(dp->d_slice)) 146 dp->d_devsw->d_close(pdev, oflags, devtype, p); 147out: 148 dp->d_flags &= ~DISKFLAG_LOCK; 149 if (dp->d_flags & DISKFLAG_WANTED) { 150 dp->d_flags &= ~DISKFLAG_WANTED; 151 wakeup(dp); 152 } 153 154 return(error); 155} 156 157static int 158diskclose(dev_t dev, int fflag, int devtype, struct proc *p) 159{ 160 struct disk *dp; 161 int error; 162 163 error = 0; 164 dp = dev->si_disk; 165 dsclose(dev, devtype, dp->d_slice); 166 if (!dsisopen(dp->d_slice)) { 167 error = dp->d_devsw->d_close(dp->d_dev, fflag, devtype, p); 168 } 169 return (error); 170} 171 172static void 173diskstrategy(struct buf *bp) 174{ 175 dev_t pdev; 176 struct disk *dp; 177 178 dp = bp->b_dev->si_disk; 179 if (!dp) { 180 pdev = dkmodpart(dkmodslice(bp->b_dev, WHOLE_DISK_SLICE), RAW_PART); 181 dp = bp->b_dev->si_disk = pdev->si_disk; 182 bp->b_dev->si_drv1 = pdev->si_drv1; 183 bp->b_dev->si_drv2 = pdev->si_drv2; 184 bp->b_dev->si_iosize_max = pdev->si_iosize_max; 185 bp->b_dev->si_bsize_phys = pdev->si_bsize_phys; 186 bp->b_dev->si_bsize_best = pdev->si_bsize_best; 187 } 188 189 if (!dp) { 190 bp->b_error = ENXIO; 191 bp->b_flags |= B_ERROR; 192 biodone(bp); 193 return; 194 } 195 196 if (dscheck(bp, dp->d_slice) <= 0) { 197 biodone(bp); 198 return; 199 } 200 201 dp->d_devsw->d_strategy(bp); 202 return; 203 204} 205 206static int 207diskioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) 208{ 209 struct disk *dp; 210 int error; 211 212 dp = dev->si_disk; 213 error = dsioctl(dev, cmd, data, fflag, &dp->d_slice); 214 if (error == ENOIOCTL) 215 error = dp->d_devsw->d_ioctl(dev, cmd, data, fflag, p); 216 return (error); 217} 218 219static int 220diskpsize(dev_t dev) 221{ 222 struct disk *dp; 223 dev_t pdev; 224 225 dp = dev->si_disk; 226 if (!dp) { 227 pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); 228 dp = pdev->si_disk; 229 dev->si_drv1 = pdev->si_drv1; 230 dev->si_drv2 = pdev->si_drv2; 231 /* XXX: don't set bp->b_dev->si_disk (?) */ 232 } 233 return (dssize(dev, &dp->d_slice)); 234} 235 236SYSCTL_DECL(_debug_sizeof); 237 238SYSCTL_INT(_debug_sizeof, OID_AUTO, disklabel, CTLFLAG_RD, 239 0, sizeof(struct disklabel), "sizeof(struct disklabel)"); 240 241SYSCTL_INT(_debug_sizeof, OID_AUTO, diskslices, CTLFLAG_RD, 242 0, sizeof(struct diskslices), "sizeof(struct diskslices)"); 243 244SYSCTL_INT(_debug_sizeof, OID_AUTO, disk, CTLFLAG_RD, 245 0, sizeof(struct disk), "sizeof(struct disk)");
| 100 return; 101} 102 103/* 104 * The cdevsw functions 105 */ 106 107static int 108diskopen(dev_t dev, int oflags, int devtype, struct proc *p) 109{ 110 dev_t pdev; 111 struct disk *dp; 112 int error; 113 114 error = 0; 115 pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); 116 117 dp = pdev->si_disk; 118 if (!dp) 119 return (ENXIO); 120 121 while (dp->d_flags & DISKFLAG_LOCK) { 122 dp->d_flags |= DISKFLAG_WANTED; 123 error = tsleep(dp, PRIBIO | PCATCH, "diskopen", hz); 124 if (error) 125 return (error); 126 } 127 dp->d_flags |= DISKFLAG_LOCK; 128 129 if (!dsisopen(dp->d_slice)) { 130 if (!pdev->si_iosize_max) 131 pdev->si_iosize_max = dev->si_iosize_max; 132 error = dp->d_devsw->d_open(pdev, oflags, devtype, p); 133 } 134 135 /* Inherit properties from the whole/raw dev_t */ 136 dev->si_disk = pdev->si_disk; 137 dev->si_drv1 = pdev->si_drv1; 138 dev->si_drv2 = pdev->si_drv2; 139 dev->si_iosize_max = pdev->si_iosize_max; 140 dev->si_bsize_phys = pdev->si_bsize_phys; 141 dev->si_bsize_best = pdev->si_bsize_best; 142 143 if (error) 144 goto out; 145 146 error = dsopen(dev, devtype, dp->d_dsflags, &dp->d_slice, &dp->d_label); 147 148 if (!dsisopen(dp->d_slice)) 149 dp->d_devsw->d_close(pdev, oflags, devtype, p); 150out: 151 dp->d_flags &= ~DISKFLAG_LOCK; 152 if (dp->d_flags & DISKFLAG_WANTED) { 153 dp->d_flags &= ~DISKFLAG_WANTED; 154 wakeup(dp); 155 } 156 157 return(error); 158} 159 160static int 161diskclose(dev_t dev, int fflag, int devtype, struct proc *p) 162{ 163 struct disk *dp; 164 int error; 165 166 error = 0; 167 dp = dev->si_disk; 168 dsclose(dev, devtype, dp->d_slice); 169 if (!dsisopen(dp->d_slice)) { 170 error = dp->d_devsw->d_close(dp->d_dev, fflag, devtype, p); 171 } 172 return (error); 173} 174 175static void 176diskstrategy(struct buf *bp) 177{ 178 dev_t pdev; 179 struct disk *dp; 180 181 dp = bp->b_dev->si_disk; 182 if (!dp) { 183 pdev = dkmodpart(dkmodslice(bp->b_dev, WHOLE_DISK_SLICE), RAW_PART); 184 dp = bp->b_dev->si_disk = pdev->si_disk; 185 bp->b_dev->si_drv1 = pdev->si_drv1; 186 bp->b_dev->si_drv2 = pdev->si_drv2; 187 bp->b_dev->si_iosize_max = pdev->si_iosize_max; 188 bp->b_dev->si_bsize_phys = pdev->si_bsize_phys; 189 bp->b_dev->si_bsize_best = pdev->si_bsize_best; 190 } 191 192 if (!dp) { 193 bp->b_error = ENXIO; 194 bp->b_flags |= B_ERROR; 195 biodone(bp); 196 return; 197 } 198 199 if (dscheck(bp, dp->d_slice) <= 0) { 200 biodone(bp); 201 return; 202 } 203 204 dp->d_devsw->d_strategy(bp); 205 return; 206 207} 208 209static int 210diskioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) 211{ 212 struct disk *dp; 213 int error; 214 215 dp = dev->si_disk; 216 error = dsioctl(dev, cmd, data, fflag, &dp->d_slice); 217 if (error == ENOIOCTL) 218 error = dp->d_devsw->d_ioctl(dev, cmd, data, fflag, p); 219 return (error); 220} 221 222static int 223diskpsize(dev_t dev) 224{ 225 struct disk *dp; 226 dev_t pdev; 227 228 dp = dev->si_disk; 229 if (!dp) { 230 pdev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); 231 dp = pdev->si_disk; 232 dev->si_drv1 = pdev->si_drv1; 233 dev->si_drv2 = pdev->si_drv2; 234 /* XXX: don't set bp->b_dev->si_disk (?) */ 235 } 236 return (dssize(dev, &dp->d_slice)); 237} 238 239SYSCTL_DECL(_debug_sizeof); 240 241SYSCTL_INT(_debug_sizeof, OID_AUTO, disklabel, CTLFLAG_RD, 242 0, sizeof(struct disklabel), "sizeof(struct disklabel)"); 243 244SYSCTL_INT(_debug_sizeof, OID_AUTO, diskslices, CTLFLAG_RD, 245 0, sizeof(struct diskslices), "sizeof(struct diskslices)"); 246 247SYSCTL_INT(_debug_sizeof, OID_AUTO, disk, CTLFLAG_RD, 248 0, sizeof(struct disk), "sizeof(struct disk)");
|