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; ... }
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
anddk_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 thed_iosize
callback. dk_ioctl
()- Handles the ioctls
DIOCKLABEL
,DIOCWLABEL
,DIOCGDEFLABEL
,DIOCGSTRATEGY
, andDIOCSSTRATEGY
and passes other disk ioctls through the disk(9) framework. ReturnsENOTTY
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 usedk_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 calldk_start
to trigger queue processing. dk_start
()- If bp !=
NULL
put it into the queue. Run thed_diskstart
callback for every buffer until the queue is empty or the callback returnsEAGAIN
. In the latter case, the buffer is saved and issued on the next queue run. This also callsdisk_busy
accordingly to handle I/O metrics. dk_done
()- Called by the driver when an I/O operation completed.
dk_done
logs errors, callsdisk_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 withdk_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 bydk_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 callsminphys
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
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).