| DKSUBR(9) | Kernel Developer's Manual | DKSUBR(9) | 
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 —
#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);
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;
...
}
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()dk_attach()dk_detach()dk_open()d_firstopen callback to handle initialization
      steps.dk_close()d_lastclose callback to handle
      finalization steps. dk_open and
      dk_close are serialized by the openlock
    mutex.dk_discard()d_discard callback.dk_size()dk_dump()d_dumpblocks callback in appropriate chunks
      determined by the d_iosize callback.dk_ioctl()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()dk_start.dk_strategy_defer()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()dk_strategy_defer. The driver must then
      call dk_start to trigger queue processing.dk_start()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()dk_done logs errors, calls
      disk_unbusy to handle I/O metrics and collects
      entropy for the
    cprng(9).dk_drain()bufq_drain() to cooperate with
      dk_start.dk_getdefaultlabel()d_label
      callback that is called by dk_getdefaultlabel
      after initializing the label with common values.dk_getdisklabel()readdisklabel and do sanity checks.
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()d_minphys()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()d_close()d_diskstart()dk_start.d_iosize()minphys but operates on an integer value instead
      of a buffer.d_dumpblocks()dk_dump.d_lastclose()d_discard()d_firstopen()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).
| November 28, 2016 | NetBSD 9.3 |