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

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: }
1.2     ! mlelstv   214: </code></pre>
1.1       mlelstv   215: 
                    216: ----
                    217: 
                    218: ##  DK driver interface
                    219: 
1.2     ! mlelstv   220: <pre><code>
1.1       mlelstv   221: static int
                    222: xxx_lastclose(device_t dv)
                    223: {
                    224:        // private cleanup
                    225: 
                    226:        return 0;
                    227: }
                    228: 
                    229: static int
                    230: xxx_diskstart(device_t dv, struct buf *bp)
                    231: {
                    232:        // issue I/O for bp
                    233:        // return EAGAIN if controller busy
                    234: }
                    235: 
                    236: static int
                    237: xxx_dumpblocks(device_t dv, void *va, daddr_t blkno, int nblk)
                    238: {
                    239:        // issue polling I/O to dump a page
                    240: }
                    241: 
                    242: static void
                    243: xxx_iosize(device_t dv, int *countp)
                    244: {
                    245:        // limit *countp as necessary
                    246: }
                    247: 
                    248: static int
                    249: xxx_discard(device_t dv, off_t pos, off_t len)
                    250: {
                    251:        // issue request to discard bytes
                    252: }
1.2     ! mlelstv   253: </code></pre>
1.1       mlelstv   254: 
                    255: ----
                    256: 
                    257: ## Alternative when using a separate I/O thread
                    258: 
1.2     ! mlelstv   259: <pre><code>
1.1       mlelstv   260: static void
                    261: xxxstrategy(struct buf *bp)
                    262: {
                    263:        DEVPROLOG;
                    264: 
                    265:        if (dk_strategy_defer(dksc, bp))
                    266:                return;
                    267: 
                    268:        // wake up I/O thread
                    269: }
                    270: 
                    271: static int
                    272: xxx_diskstart(device_t dv, struct buf *bp)
                    273: {
                    274:        // issue I/O for bp
                    275: }
                    276: 
                    277: static void
                    278: xxxdone(struct xxx_softc *sc, struct buf *bp)
                    279: {
                    280:        struct dk_softc *dksc = &sc->sc_dksc;
                    281: 
                    282:        dk_done(dksc, bp);
                    283:        // wake up I/O thread
                    284: }
                    285: 
                    286: static void
                    287: xxx_IOTHREAD(struct dk_softc *dksc)
                    288: {
                    289:        while (!shutting_down) {
                    290:                if (dk_strategy_pending(dksc)
                    291:                        dk_start(dksc, NULL);
                    292:                // sleep
                    293:        }
                    294: }
                    295: </code></pre>
                    296: 
                    297: ----

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