#ifndef lint static char sccsid[] = "@(#)simdisk.c 1.1 94/10/31"; #endif /* * Copyright (c) 1987 by Sun Microsystems, Inc. */ /* * Dummy driver for sparc simulated disks. * uses systems calls via simulator to accomplish * base level open, seek, read, and write operations */ int errno; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Defintions for real devices used by simulator */ /* * XXX below should be defined as options to config */ struct simdisk { int fdes; int flag; int size; char *name; } simdunits[] = { 0, 0, SIMD_RSIZE, SIMD_RDEV, 0, 0, SIMD_SSIZE, SIMD_SDEV, 0, 0, SIMD_USIZE, SIMD_UDEV }; #define MAXSIMDUNITS (sizeof (simdunits) / sizeof (simdunits[0])) /* * Attach device (boot time). */ simdattach(md) register struct mb_device *md; { } simdopen(dev, flag) register dev_t dev; register int flag; { register int unit; register char *name; unit = minor(dev); if (unit >= MAXSIMDUNITS) { printf("Illegal simulated disk unit.\n"); return (ENXIO); } simdunits[unit].flag = flag; name = simdunits[unit].name; if ((simdunits[unit].fdes = s_open(name, O_RDWR)) == -1 ) { printf("Couldn't open %s\n", simdunits[unit].name); return (ENXIO); } return(0); } simdsize(dev) register dev_t dev; { return (simdunits[minor(dev)].size); } simdstrategy(bp) register struct buf *bp; { register daddr_t bn; /* block number */ register int unit; /* unit number */ register int fdes; /* file descriptor */ register int cnt; /* completed transfer count */ unit = minor(bp->b_dev); if (unit >= MAXSIMDUNITS) { printf("simd%d: simdstrategy: invalid unit\n", unit); bp->b_flags |= B_ERROR; iodone(bp); return; } bn = dkblock(bp); fdes = simdunits[unit].fdes; bp_mapin(bp); if (s_lseek(fdes, bn << DEV_BSHIFT, L_SET) == -1) { /* avoid a problem in sas by trying the seek once more */ if (s_lseek(fdes, bn << DEV_BSHIFT, L_SET) == -1) { printf("simd%d: can't seek %s\n", unit, simdunits[unit].name); printf("block number = 0x%x\n", bn); bp->b_flags |= B_ERROR; } } else if (bp->b_bcount & (DEV_BSIZE - 1)) { printf("simd%d: non-block size i/o request\n", unit); bp->b_flags |= B_ERROR; } else if (bp->b_flags & B_READ) { if ((cnt=s_read(fdes, bp->b_un.b_addr, bp->b_bcount)) == -1) { printf("simd%d: error reading block %d\n", unit, bn); bp->b_flags |= B_ERROR; } } else { if ((cnt=s_write(fdes, bp->b_un.b_addr, bp->b_bcount)) == -1) { printf("simd%d: error writing block %d\n", unit, bn); bp->b_flags |= B_ERROR; } } bp_mapout(bp); if ((bp->b_flags & B_ERROR) == 0) bp->b_resid = bp->b_bcount - cnt; iodone(bp); }