Annotation of wikisrc/users/mlelstv/disk-driver-template.mdwn, revision 1.1

1.1     ! mlelstv     1: **Contents**
        !             2: 
        !             3: [[!toc levels=2]]
        !             4: 
        !             5: # Disk driver template when using dksubr library
        !             6: 
        !             7: ## Declaration
        !             8: 
        !             9: <pre><code>
        !            10: const struct bdevsw xxx_bdevsww= {
        !            11:        .d_open = xxxopen,
        !            12:        .d_close = xxxclose,
        !            13:        .d_strategy = xxxstrategy,
        !            14:        .d_ioctl = xxxioctl,
        !            15:        .d_dump = xxxdump,
        !            16:        .d_psize = xxxsize,
        !            17:        .d_discard = xxxdiscard,
        !            18:        .d_flag = D_DISK
        !            19: };
        !            20: 
        !            21: const struct cdevsw xxx_cdevsw = {
        !            22:        .d_open = xxxopen,
        !            23:        .d_close = xxxclose,
        !            24:        .d_read = xxxread,
        !            25:        .d_write = xxxwrite,
        !            26:        .d_ioctl = xxxioctl,
        !            27:        .d_stop = nostop,
        !            28:        .d_tty = notty,
        !            29:        .d_poll = nopoll,
        !            30:        .d_mmap = nommap,
        !            31:        .d_kqfilter = nokqfilter,
        !            32:        .d_discard = xxxdiscard,
        !            33:        .d_flag = D_DISK
        !            34: };
        !            35: 
        !            36: static const struct dkdriver xxxdkdriver = {
        !            37:        .d_open = xxxopen,
        !            38:        .d_close = xxxclose,
        !            39:        .d_strategy = xxxstrategy,
        !            40:        .d_iosize = xxx_iosize,
        !            41:        .d_minphys  = xxxminphys,
        !            42:        .d_diskstart = xxx_diskstart,
        !            43:        .d_dumpblocks = xxx_dumpblocks,
        !            44:        .d_lastclose = xxx_lastclose,
        !            45:        .d_discard = xxx_discard
        !            46: };
        !            47: 
        !            48: extern struct   cfdriver xxx_cd;
        !            49: 
        !            50: static dev_type_open(xxxopen);
        !            51: static dev_type_close(xxxclose);
        !            52: static dev_type_read(xxxread);
        !            53: static dev_type_write(xxxwrite);
        !            54: static dev_type_ioctl(xxxioctl);
        !            55: static dev_type_strategy(xxxstrategy);
        !            56: static dev_type_dump(xxxdump);
        !            57: static dev_type_size(xxxsize);
        !            58: static dev_type_discard(xxxdiscard);
        !            59: 
        !            60: static void     xxxminphys(struct buf *bp);
        !            61: static int      xxxdiskstart(device_t, struct buf *bp);
        !            62: static void     xxx_iosize(device_t, int *);
        !            63: static int      xxx_dumpblocks(device_t, void *, daddr_t, int);
        !            64: static int      xxx_lastclose(device_t);
        !            65: static int      xxx_discard(device_t, off_t, off_t);
        !            66: 
        !            67: 
        !            68: #define DEVPROLOG \
        !            69:        struct xxx_softc *sc; \
        !            70:        struct dk_softc *dksc; \
        !            71:        int unit; \
        !            72: \
        !            73:        unit = DISKUNIT(dev); \
        !            74:        if ((sc = device_lookup_private(&xxx_cd, unit)) == NULL) \
        !            75:                return ENXIO; \
        !            76:        dksc = &sc->sc_dksc
        !            77: </code></pre>
        !            78: 
        !            79: ----
        !            80: 
        !            81: ## Attachment and Standard driver interface
        !            82: 
        !            83: <pre><code>
        !            84: void
        !            85: xxxattach(struct xxx_softc *sc)
        !            86: {
        !            87:        device_t self = sc->sc_dv;
        !            88:        struct dk_softc *dksc = &sc->sc_dk;
        !            89: 
        !            90:        dk_init(dksc, self, DKTYPE_xxx);
        !            91:        disk_init(&dksc->sc_dkdev, dksc->sc_xname, &xxdkdriver);
        !            92: 
        !            93:        dk_attach(dksc);
        !            94:        disk_attach(&dksc->sc_dkdev);
        !            95:        // initialize dksc->sc_dkdev.dk_geom
        !            96: 
        !            97:        bufq_alloc(&dksc->sc_bufq, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK);
        !            98: 
        !            99:        // possibly deferred with config_interrupts()
        !           100:        dkwedge_discover(&dksc->sc_dkdev);
        !           101: }
        !           102: 
        !           103: static int
        !           104: xxxopen(dev_t dev, int flags, int fmt, struct lwp *l)
        !           105: {
        !           106:        DEVPROLOG;
        !           107: 
        !           108:        return dk_open(dksc, dev, flags, fmt, l);
        !           109: }
        !           110: 
        !           111: static int
        !           112: xxxclose(dev_t dev, int flags, int fmt, struct lwp *l)
        !           113: {
        !           114:        DEVPROLOG;
        !           115: 
        !           116:        return dk_close(dksc, dev, flags, fmt, l);
        !           117: }
        !           118: 
        !           119: static int
        !           120: xxxread(dev_t dev, struct uio *uio, int ioflag)
        !           121: {
        !           122: 
        !           123:        return physio(xxxstrategy, NULL, dev, B_READ, xxxminphys, uio);
        !           124: }
        !           125: 
        !           126: static int
        !           127: xxxwrite(dev_t dev, struct uio *uio, int ioflag)
        !           128: {
        !           129: 
        !           130:        return physio(xxxstrategy, NULL, dev, B_WRITE, xxxminphys, uio);
        !           131: }
        !           132: 
        !           133: static int
        !           134: xxxioctl(dev_t dev, u_long cmd, void *addr, int32_t flag, struct lwp *l)
        !           135: {
        !           136:        int error;
        !           137:        DEVPROLOG;
        !           138: 
        !           139:        error = dk_ioctl(dksc, dev, cmd, addr, flag, l);
        !           140:        if (error != EPASSTHROUGH)
        !           141:                return error;
        !           142: 
        !           143:        error = 0;
        !           144: 
        !           145:        switch (cmd) {
        !           146:        // private IOCTLs
        !           147:        default:
        !           148:                error = ENOTTY;
        !           149:        }
        !           150: 
        !           151:        return error;
        !           152: }
        !           153: 
        !           154: static void
        !           155: xxxstrategy(struct buf *bp)
        !           156: {
        !           157:        DEVPROLOG;
        !           158: 
        !           159:        dk_strategy(dksc, bp);
        !           160: }
        !           161: 
        !           162: static int
        !           163: xxxdiscard(dev_t dev, off_t pos, off_t len)
        !           164: {
        !           165:        DEVPROLOG;
        !           166: 
        !           167:        return dk_discard(dksc, dev, pos, len);
        !           168: }
        !           169: 
        !           170: static int
        !           171: xxxsize(dev_t dev)
        !           172: {
        !           173:        DEVPROLOG;
        !           174: 
        !           175:        return dk_size(dksc, dev);
        !           176: }
        !           177: 
        !           178: static int
        !           179: xxxdump(dev_t dev, daddr_t blkno, void *va, size_t size)
        !           180: {
        !           181:        DEVPROLOG;
        !           182: 
        !           183:        return dk_dump(dksc, dev, blkno, va, size);
        !           184: }
        !           185: 
        !           186: static void
        !           187: xxxminphys(struct buf *bp)
        !           188: {
        !           189:        struct xxx_softc *sc;
        !           190:        int unit;
        !           191: 
        !           192:        unit = DISKUNIT(bp->b_dev);
        !           193:        if ((sc = device_lookup_private(&xxx_cd, unit)) == NULL)
        !           194:                return;
        !           195: 
        !           196:        xxx_iosize(sc->sc_dv, &bp->b_count);
        !           197:        minphys(bp);
        !           198: }
        !           199: </code></pre>
        !           200: 
        !           201: ----
        !           202: 
        !           203: ## I/O callback
        !           204: 
        !           205: <pre><code>
        !           206: static void
        !           207: xxxdone(struct xxx_softc *sc, struct buf *bp)
        !           208: {
        !           209:        struct dk_softc *dksc = &sc->sc_dksc;
        !           210: 
        !           211:        dk_done(dksc, bp);
        !           212:        dk_start(dksc, NULL);
        !           213: }
        !           214: 
        !           215: ----
        !           216: 
        !           217: ##  DK driver interface
        !           218: 
        !           219: static int
        !           220: xxx_lastclose(device_t dv)
        !           221: {
        !           222:        // private cleanup
        !           223: 
        !           224:        return 0;
        !           225: }
        !           226: 
        !           227: static int
        !           228: xxx_diskstart(device_t dv, struct buf *bp)
        !           229: {
        !           230:        // issue I/O for bp
        !           231:        // return EAGAIN if controller busy
        !           232: }
        !           233: 
        !           234: static int
        !           235: xxx_dumpblocks(device_t dv, void *va, daddr_t blkno, int nblk)
        !           236: {
        !           237:        // issue polling I/O to dump a page
        !           238: }
        !           239: 
        !           240: static void
        !           241: xxx_iosize(device_t dv, int *countp)
        !           242: {
        !           243:        // limit *countp as necessary
        !           244: }
        !           245: 
        !           246: static int
        !           247: xxx_discard(device_t dv, off_t pos, off_t len)
        !           248: {
        !           249:        // issue request to discard bytes
        !           250: }
        !           251: 
        !           252: ----
        !           253: 
        !           254: ## Alternative when using a separate I/O thread
        !           255: 
        !           256: static void
        !           257: xxxstrategy(struct buf *bp)
        !           258: {
        !           259:        DEVPROLOG;
        !           260: 
        !           261:        if (dk_strategy_defer(dksc, bp))
        !           262:                return;
        !           263: 
        !           264:        // wake up I/O thread
        !           265: }
        !           266: 
        !           267: static int
        !           268: xxx_diskstart(device_t dv, struct buf *bp)
        !           269: {
        !           270:        // issue I/O for bp
        !           271: }
        !           272: 
        !           273: static void
        !           274: xxxdone(struct xxx_softc *sc, struct buf *bp)
        !           275: {
        !           276:        struct dk_softc *dksc = &sc->sc_dksc;
        !           277: 
        !           278:        dk_done(dksc, bp);
        !           279:        // wake up I/O thread
        !           280: }
        !           281: 
        !           282: static void
        !           283: xxx_IOTHREAD(struct dk_softc *dksc)
        !           284: {
        !           285:        while (!shutting_down) {
        !           286:                if (dk_strategy_pending(dksc)
        !           287:                        dk_start(dksc, NULL);
        !           288:                // sleep
        !           289:        }
        !           290: }
        !           291: </code></pre>
        !           292: 
        !           293: ----

CVSweb for NetBSD wikisrc <wikimaster@NetBSD.org> software: FreeBSD-CVSweb