xref: /netbsd-src/share/man/man9/disk.9 (revision 76dfffe33547c37f8bdd446e3e4ab0f3c16cea4b)
1.\"	$NetBSD: disk.9,v 1.4 1996/09/24 07:18:44 ghudson Exp $
2.\"
3.\" Copyright (c) 1995, 1996 Jason R. Thorpe.
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\"    notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\"    notice, this list of conditions and the following disclaimer in the
13.\"    documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\"    must display the following acknowledgement:
16.\"	This product includes software developed for the NetBSD Project
17.\"	by Jason R. Thorpe.
18.\" 4. The name of the author may not be used to endorse or promote products
19.\"    derived from this software without specific prior written permission.
20.\"
21.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31.\" SUCH DAMAGE.
32.\"
33.Dd Jan 7, 1996
34.Dt DISK 9
35.Os NetBSD
36.Sh NAME
37.Nm disk
38.Nd generic disk framework
39.Sh SYNOPSIS
40.Fd #include <sys/types.h>
41.Fd #include <sys/disklabel.h>
42.Fd #include <sys/disk.h>
43.Ft void
44.Fn disk_init "void"
45.Ft void
46.Fn disk_attach "struct disk *"
47.Ft void
48.Fn disk_detach "struct disk *"
49.Ft void
50.Fn disk_busy "struct disk *"
51.Ft void
52.Fn disk_unbusy "struct disk *"
53.Ft void
54.Fn disk_resetstat "struct disk *"
55.Ft struct disk *
56.Fn disk_find "char *"
57.Sh DESCRIPTION
58The NetBSD generic disk framework is designed to provide flexible,
59scalable, and consistent handling of disk state and metrics information.
60The fundamental component of this framework is the
61.Nm disk
62structure, which is defined as follows:
63.Bd -literal
64struct disk {
65	TAILQ_ENTRY(disk) dk_link;	/* link in global disklist */
66	char	 *dk_name;	/* disk name */
67	int	 dk_bopenmask;	/* block devices open */
68	int	 dk_copenmask;	/* character devices open */
69	int	 dk_openmask;	/* composite (bopen|copen) */
70	int	 dk_state;	/* label state */
71	int	 dk_blkshift;	/* shift to convert DEV_BSIZE to blks */
72	int	 dk_byteshift;	/* shift to convert bytes to blks */
73
74	/*
75	 * Metrics data; note that some metrics may have no meaning
76	 * on certain types of disks.
77	 */
78	int	  dk_busy;	/* busy counter */
79	u_int64_t dk_xfer;	/* total number of transfers */
80	u_int64_t dk_seek;	/* total independent seek operations */
81	u_int64_t dk_bytes;	/* total bytes transfered */
82	struct timeval	dk_attachtime;	/* time disk was attached */
83	struct timeval	dk_timestamp;	/* timestamp of last unbusy */
84	struct timeval	dk_time;	/* total time spent busy */
85
86	struct	dkdriver *dk_driver;	/* pointer to driver */
87
88	/*
89	 * Disk label information.  Storage for the in-core disk label
90	 * must be dynamically allocated, otherwise the size of this
91	 * structure becomes machine-dependent.
92	 */
93	daddr_t	 dk_labelsector;	/* sector containing label */
94	struct disklabel *dk_label;	/* label */
95	struct cpu_disklabel *dk_cpulabel;
96};
97.Ed
98.Pp
99The system maintains a global linked-list of all disks attached to the
100system.  This list, called
101.Nm disklist ,
102may grow or shrink over time as disks are dynamically added and removed
103from the system.  Drivers which currently make use of the detachment
104capability of the framework are the
105.Nm ccd
106and
107.Nm vnd
108pseudo-device drivers.
109.Pp
110The following is a brief description of each function in the framework:
111.Bl -tag -width "disk_resetstat()"
112.It Fn disk_init
113Initialize the disklist and other data structures used by the framework.
114Called by
115.Fn main
116before autoconfiguration.
117.It Fn disk_attach
118Attach a disk; allocate storage for the disklabel, set the
119.Dq attached time
120timestamp, insert the disk into the disklist, and intrement the
121system disk count.
122.It Fn disk_detach
123Detatch a disk; free storage for the disklabel, remove the disk
124from the disklist, and decrement the system disk count.  If the count
125drops below zero, panic.
126.It Fn disk_busy
127Increment the disk's
128.Dq busy counter .
129If this counter goes from 0 to 1, set the timestamp corresponding to
130this transfer.
131.It Fn disk_unbusy
132Decrement a disk's busy counter.  If the count drops below zero, panic.
133Get the current time, subtract it from the disk's timestamp, and add
134the difference to the disk's running total.  Set the disk's timestamp
135to the current time.  If the provided byte count is greater than 0,
136add it to the disk's running total and increment the number of transfers
137performed by the disk.
138.It Fn disk_resetstat
139Reset the running byte, transfer, and time totals.
140.It Fn disk_find
141Return a pointer to the disk structure corresponding to the name provided,
142or NULL if the disk does not exist.
143.El
144.Pp
145The functions typically called by device drivers are
146.Fn disk_attach ,
147.Fn disk_detach ,
148.Fn disk_busy ,
149.Fn disk_unbusy ,
150and
151.Fn disk_resetstat .
152The function
153.Fn disk_find
154is provided as a utility function.
155.Sh USING THE FRAMEWORK
156This section includes a description on basic use of the framework
157and example usage of its functions.  Actual implementation of
158a device driver which utilizes the framework may vary.
159.Pp
160A special routine,
161.Fn disk_init ,
162is provided to perform basic initialization of data structures used by
163the framework.  It is called exactly once by the system, in
164.Fn main ,
165before device autoconfiguration.
166.Pp
167Each device in the system uses a
168.Dq softc
169structure which contains autoconfiguration and state information for that
170device.  In the case of disks, the softc should also contain one instance
171of the disk stucture, eg:
172.Bd -literal
173struct foo_softc {
174	struct	device *sc_dev;		/* generic device information */
175	struct	disk sc_dk;		/* generic disk information */
176	[ . . . more . . . ]
177};
178.Ed
179.Pp
180In order for the system to gather metrics data about a disk, the disk must
181be registered with the system.  The
182.Fn disk_attach
183routine performs all of the functions currently required to register a disk
184with the system including allocation of disklabel storage space,
185recording of the time since boot that the disk was attached, and insertion
186into the disklist.  Note that since this function allocates storage space
187for the disklabel, it must be called before the disklabel is read from the
188media or used in any other way.  Before
189.Fn disk_attach
190is called, a portions of the disk structure must be initialized with
191data specific to that disk.  For example, in the
192.Dq foo
193disk driver, the following would be performed in the autoconfiguration
194.Dq attach
195routine:
196.Bd -literal
197void
198fooattach(parent, self, aux)
199	struct device *parent, *self;
200	void *aux;
201{
202	struct foo_softc *sc = (struct foo_softc *)self;
203	[ . . . ]
204
205	/* Initialize and attach the disk structure. */
206	sc->sc_dk.dk_driver = &foodkdriver;
207	sc->sc_dk.dk_name = sc->sc_dev.dv_xname;
208	disk_attach(&sc->sc_dk);
209
210	/* Read geometry and fill in pertinent parts of disklabel. */
211	[ . . . ]
212}
213.Ed
214.Pp
215The
216.Nm foodkdriver
217above is the disk's
218.Dq driver
219switch.  This switch currently includes a pointer to the disk's
220.Dq strategy
221routine.  This switch needs to have global scope and sould be initialized
222as follows:
223.Bd -literal
224void	foostrategy __P((struct buf *));
225struct	dkdriver foodkdriver = { foostrategy };
226.Ed
227.Pp
228Once the disk is attached, metrics may be gathered on that disk.  In order
229to gather metrics data, the driver must tell the framework when the disk
230starts and stops operations.  This functionality is provided by the
231.Fn disk_busy
232and
233.Fn disk_unbusy
234routines.  The
235.Fn disk_busy
236routine should be called immediately before a command to the disk is
237sent, eg:
238.Bd -literal
239void
240foostart(sc)
241	struct foo_softc *sc;
242{
243	[ . . . ]
244
245	/* Get buffer from drive's transfer queue. */
246	[ . . . ]
247
248	/* Build command to send to drive. */
249	[ . . . ]
250
251	/* Tell the disk framework we're going busy. */
252	disk_busy(&sc->sc_dk);
253
254	/* Send command to the drive. */
255	[ . . . ]
256}
257.Ed
258.Pp
259When
260.Fn disk_busy
261is called, a timestamp is taken if the disk's busy counter moves from
2620 to 1, indicating the disk has gone from an idle to non-idle state.
263Note that
264.Fn disk_busy
265must be called at
266.Fn splbio .
267At the end of a transaction, the
268.Fn disk_unbusy
269routine should be called.  This routine performs some consistency checks,
270such as ensuring that the calls to
271.Fn disk_busy
272and
273.Fn disk_unbusy
274are balanced.  This routine also performs the actual metrics calculation.
275A timestamp is taken, and the difference from the timestamp taken in
276.Fn disk_busy
277is added to the disk's total running time.  The disk's timestamp is then
278updated in case there is more than one pending transfer on the disk.
279A byte count is also added to the disk's running total, and if greater than
280zero, the number of transfers the disk has performed is incremented.
281.Bd -literal
282void
283foodone(xfer)
284	struct foo_xfer *xfer;
285{
286	struct foo_softc = (struct foo_softc *)xfer->xf_softc;
287	struct buf *bp = xfer->xf_buf;
288	long nbytes;
289	[ . . . ]
290
291	/*
292	 * Get number of bytes transfered.  If there is no buf
293	 * associated with the xfer, we are being called at the
294	 * end of a non-I/O command.
295	 */
296	if (bp == NULL)
297		nbytes = 0;
298	else
299		nbytes = bp->b_bcount - bp->b_resid;
300
301	[ . . . ]
302
303	/* Notify the disk framework that we've completed the transfer. */
304	disk_unbusy(&sc->sc_dk, nbytes);
305
306	[ . . . ]
307}
308.Ed
309.Pp
310Like
311.Fn disk_busy ,
312.Fn disk_unbusy
313must be called at
314.Fn splbio .
315.Pp
316At some point a driver may wish to reset the metrics data gathered on a
317particular disk.  For this function, the
318.Fn disk_resetstat
319routine is provided.
320.Sh CODE REFERENCES
321This section describes places within the NetBSD source tree where actual
322code implementing or utilizing the disk framework can be found.  All
323pathnames are relative to
324.Nm /usr/src .
325.Pp
326The disk framework itself is implemented within the file
327.Nm sys/kern/subr_disk.c .
328Data structures and function prototypes for the framework are located in
329.Nm sys/sys/disk.h .
330.Pp
331The NetBSD machine-independent SCSI disk and CD-ROM drivers utilize the
332disk framework.  They are located in
333.Nm sys/scsi/sd.c
334and
335.Nm sys/scsi/cd.c .
336.Pp
337The NetBSD
338.Nm ccd
339and
340.Nm vnd
341drivers utilize the detachment capability of the framework.
342They are located in
343.Nm sys/dev/ccd.c
344and
345.Nm sys/dev/vnd.c .
346.Sh AUTHOR
347The NetBSD generic disk framework was architected and implemented by
348Jason R. Thorpe <thorpej@NetBSD.ORG>.
349.Sh SEE ALSO
350.Xr ccd 4 ,
351.Xr vnd 4 ,
352.Xr spl 9 .
353.Sh HISTORY
354The NetBSD generic disk framework appeared in NetBSD 1.1A.
355