dksubr(9)
- NetBSD Manual Pages
DKSUBR(9) NetBSD 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 parame-
ters. 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 pro-
cessing 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 deter-
mine 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 com-
pleted. 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.1 November 28, 2016 NetBSD 8.1
Powered by man-cgi (2024-03-20).
Maintained for NetBSD
by Kimmo Suominen.
Based on man-cgi by Panagiotis Christias.