I would appreciate any donations. Wishlist or send e-mail type donations to maekawa AT daemon-systems.org.

Thank you.


DKSUBR(9)                  Kernel Developer's Manual                 DKSUBR(9)

NAME
     dk_softc, dk_init, dk_attach, dk_detach, dk_open, dk_close, dk_size,
     dk_dump, dk_ioctl, dk_strategy, dk_strategy_defer, dk_strategy_pending,
     dk_start, dk_done, dk_drain, dk_discard, dk_getdefaultlabel,
     dk_getdisklabel, - disk driver subroutines

SYNOPSIS
     #include <sys/bufq.h>
     #include <sys/disk.h>
     #include <dev/dkvar.h>

     void
     dk_init(struct dk_softc *, device_t, int dtype);

     void
     dk_attach(struct dk_softc *);

     void
     dk_detach(struct dk_softc *);

     int
     dk_open(struct dk_softc *, dev_t, int flags, int fmt, struct lwp *);

     int
     dk_close(struct dk_softc *, dev_t, int flags, int fmt, struct lwp *);

     int
     dk_discard(struct dk_softc *, dev_t, off_t pos, off_t len);

     int
     dk_size(struct dk_softc *, dev_t);

     int
     dk_dump(struct dk_softc *, dev_t, daddr_t blkno, void *vav, size_t size);

     int
     dk_ioctl(struct dk_softc *, dev_t, u_long cmd, void *data, int flag,
         struct lwp *);

     void
     dk_strategy(struct dk_softc *, struct buf *);

     int
     dk_strategy_defer(struct dk_softc *, struct buf *);

     int
     dk_strategy_pending(struct dk_softc *);

     void
     dk_start(struct dk_softc *, struct buf *);

     void
     dk_done(struct dk_softc *, struct buf *);

     int
     dk_drain(struct dk_softc *);

     void
     dk_getdefaultlabel(struct dk_softc *, struct disklabel *);

     void
     dk_getdisklabel(struct dk_softc *, dev_t);

DESCRIPTION
     The disk driver subroutines provide common functionality for all disk
     drivers to reduce the amount of replicated code.  For many disk drivers,
     their corresponding entry points can be made mostly stubs.

     The subroutines encapsulate data structures found in a driver's softc
     into

     struct dk_softc {
             device_t                sc_dev;
             struct disk             sc_dkdev;
             struct bufq_state       sc_bufq;
             krndsource_t            sc_rnd_source;
     }
     The dk_softc structure therefore replaces the device_t member of the
     driver's softc struct.

     The following is a brief description of each function in the framework:

     dk_init()                Initialize the dk_softc structure.

     dk_attach()              Attach framework after driver has attached the
                              disk(9) subsystem, created a bufq(9) and is
                              ready to handle I/O.

     dk_detach()              Undo dk_attach.

     dk_open()                Handles open steps for the disk(9) framework,
                              acquires the disklabel and validates open
                              parameters.  The driver may provide the
                              d_firstopen callback to handle initialization
                              steps.

     dk_close()               Handles close steps for the disk(9) framework.
                              The driver may provide the d_lastclose callback
                              to handle finalization steps.  dk_open and
                              dk_close are serialized by the openlock mutex.

     dk_discard()             Validates parameters, computes raw block numbers
                              and passes these to the d_discard callback.

     dk_size()                Returns dump size information from the
                              disklabel(9) and opens and closes the driver
                              when necessary.

     dk_dump()                Validates parameters, computes raw block numbers
                              and iterates over the d_dumpblocks callback in
                              appropriate chunks determined by the d_iosize
                              callback.

     dk_ioctl()               Handles the ioctls DIOCKLABEL, DIOCWLABEL,
                              DIOCGDEFLABEL, DIOCGSTRATEGY, and DIOCSSTRATEGY
                              and passes other disk ioctls through the disk(9)
                              framework.  Returns ENOTTY when an ioctl isn't
                              implemented.  This routine is run as a fallback
                              to handle commands that are not specific to the
                              driver.

     dk_strategy()            Validates parameters, computes raw block
                              numbers, queues a buffer for I/O and triggers
                              queue processing by calling dk_start.

     dk_strategy_defer()      Alternative to dk_strategy that only queues the
                              buffer.  Drivers that implement a separate I/O
                              thread can use dk_strategy_defer within their
                              own strategy routine and signal the thread
                              through a private interface.

     dk_strategy_pending()    This function is called by an I/O thread to
                              determine if work has been queued by
                              dk_strategy_defer.  The driver must then call
                              dk_start to trigger queue processing.

     dk_start()               If bp != NULL put it into the queue.  Run the
                              d_diskstart callback for every buffer until the
                              queue is empty or the callback returns EAGAIN.
                              In the latter case, the buffer is saved and
                              issued on the next queue run.  This also calls
                              disk_busy accordingly to handle I/O metrics.

     dk_done()                Called by the driver when an I/O operation
                              completed.  dk_done logs errors, calls
                              disk_unbusy to handle I/O metrics and collects
                              entropy for the cprng(9).

     dk_drain()               Aborts all queued I/O.  This function must be
                              called instead of bufq_drain() to cooperate with
                              dk_start.

     dk_getdefaultlabel()     Compute a common default disklabel for all disk
                              drivers.  Some drivers provide device specific
                              information or assign specific disk formats to
                              partitions.  Such drivers may implement the
                              d_label callback that is called by
                              dk_getdefaultlabel after initializing the label
                              with common values.

     dk_getdisklabel()        Read disklabel with machine dependent low-level
                              function readdisklabel and do sanity checks.

DRIVER INTERFACE
     The driver needs to provide a common set of entry points that are used by
     the disk driver subroutines and the disk(9) framework.

     struct dkdriver {
             void    (*d_strategy)(struct buf *);
             void    (*d_minphys)(struct buf *);
             int     (*d_open)(dev_t, int, int, struct lwp *);
             int     (*d_close)(dev_t, int, int, struct lwp *);
             int     (*d_diskstart)(device_t, struct buf *);
             void    (*d_iosize)(device_t, int *);
             int     (*d_dumpblocks)(device_t, void *, daddr_t, int);
             int     (*d_lastclose)(device_t);
             int     (*d_discard)(device_t, off_t, off_t);
             int     (*d_firstopen)(device_t, dev_t, int, int);
             void    (*d_label)(device_t, struct disklabel *);
     };

     d_strategy()      The driver strategy routine queues a single buffer for
                       I/O and starts queue processing as appropriate.

     d_minphys()       The driver minphys routine limits the buffer b_bcount
                       to the maximum size for an I/O transfer supported by
                       the driver and hardware.  It also calls minphys to
                       apply the platform limit.

     d_open()          The driver open routine.

     d_close()         The driver close routine.

     d_diskstart()     Issues a single I/O request, called by dk_start.

     d_iosize()        Truncate I/O size to the driver limit.  This is similar
                       to minphys but operates on an integer value instead of
                       a buffer.

     d_dumpblocks()    Issue a single I/O requests, called by dk_dump.

     d_lastclose()     Private cleanup after last user is finished.  Often
                       used to flush write caches.

     d_discard()       Issue a single I/O request to invalidate a disk region.

     d_firstopen()     Private initialization when first user opens the
                       driver.

SEE ALSO
     cgd(4), ld(4), cprng(9), disk(9), driver(9)

HISTORY
     The NetBSD common disk driver subroutines appeared in NetBSD 2.0 as a
     base for the cryptographic disk driver and was extended to handle disk
     wedges in NetBSD 4.0.  Most functionality provided by ld(4) was included
     and extended in NetBSD 8.0 to support other disk drivers.  The callback
     interface used by the disk(9) framework has been merged as well.

BUGS
     The framework includes a dk_lookup helper function, that is used by the
     cgd(4) driver to open a vnode for a block device.  This looks too generic
     and should be put somewhere better (and be renamed).

NetBSD 8.0                     November 28, 2016                    NetBSD 8.0