| 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.4 |