device_if.m revision 139804
1139804Simp#-
2133588Simp# Copyright (c) 1998-2004 Doug Rabson
336973Sdfr# All rights reserved.
436973Sdfr#
536973Sdfr# Redistribution and use in source and binary forms, with or without
636973Sdfr# modification, are permitted provided that the following conditions
736973Sdfr# are met:
836973Sdfr# 1. Redistributions of source code must retain the above copyright
936973Sdfr#    notice, this list of conditions and the following disclaimer.
1036973Sdfr# 2. Redistributions in binary form must reproduce the above copyright
1136973Sdfr#    notice, this list of conditions and the following disclaimer in the
1236973Sdfr#    documentation and/or other materials provided with the distribution.
1336973Sdfr#
1436973Sdfr# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1536973Sdfr# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1636973Sdfr# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1736973Sdfr# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1836973Sdfr# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1936973Sdfr# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2036973Sdfr# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2136973Sdfr# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2236973Sdfr# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2336973Sdfr# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2436973Sdfr# SUCH DAMAGE.
2536973Sdfr#
2650477Speter# $FreeBSD: head/sys/kern/device_if.m 139804 2005-01-06 23:35:40Z imp $
2736973Sdfr#
2836973Sdfr
2959093Sdfr#include <sys/bus.h>
3059093Sdfr
31131988Sdfr/**
32131988Sdfr * @defgroup DEVICE device - KObj methods for all device drivers
33131988Sdfr * @brief A basic set of methods required for all device drivers.
34131988Sdfr *
35131988Sdfr * The device interface is used to match devices to drivers during
36131988Sdfr * autoconfiguration and provides methods to allow drivers to handle
37131988Sdfr * system-wide events such as suspend, resume or shutdown.
38131988Sdfr * @{
39131988Sdfr */
4041012SnsouchINTERFACE device;
4136973Sdfr
4236973Sdfr#
4346913Sdfr# Default implementations of some methods.
4446913Sdfr#
4546913SdfrCODE {
4646913Sdfr	static int null_shutdown(device_t dev)
4746913Sdfr	{
4846913Sdfr	    return 0;
4946913Sdfr	}
5046913Sdfr
5146913Sdfr	static int null_suspend(device_t dev)
5246913Sdfr	{
5346913Sdfr	    return 0;
5446913Sdfr	}
5546913Sdfr
5646913Sdfr	static int null_resume(device_t dev)
5746913Sdfr	{
5846913Sdfr	    return 0;
5946913Sdfr	}
60139507Simp
61139507Simp	static int null_quiesce(device_t dev)
62139507Simp	{
63139507Simp	    return EOPNOTSUPP;
64139507Simp	}
6546913Sdfr};
66131988Sdfr	
67131988Sdfr/**
68131988Sdfr * @brief Probe to see if a device matches a driver.
69131988Sdfr *
70131988Sdfr * Users should not call this method directly. Normally, this
71131988Sdfr * is called via device_probe_and_attach() to select a driver
72131988Sdfr * calling the DEVICE_PROBE() of all candidate drivers and attach
73131988Sdfr * the winning driver (if any) to the device.
74131988Sdfr *
75131988Sdfr * This function is used to match devices to device drivers.
76131988Sdfr * Typically, the driver will examine the device to see if
77131988Sdfr * it is suitable for this driver. This might include checking
78131988Sdfr * the values of various device instance variables or reading
79131988Sdfr * hardware registers.
80131988Sdfr *  
81131988Sdfr * In some cases, there may be more than one driver available
82131988Sdfr * which can be used for a device (for instance there might
83131988Sdfr * be a generic driver which works for a set of many types of
84131988Sdfr * device and a more specific driver which works for a subset
85131988Sdfr * of devices). Because of this, a driver should not assume
86131988Sdfr * that it will be the driver that attaches to the device even
87131988Sdfr * if it returns a success status from DEVICE_PROBE(). In particular,
88131988Sdfr * a driver must free any resources which it allocated during
89131988Sdfr * the probe before returning. The return value of DEVICE_PROBE()
90131988Sdfr * is used to elect which driver is used - the driver which returns
91131988Sdfr * the largest non-error value wins the election and attaches to
92131988Sdfr * the device.
93131988Sdfr *
94131988Sdfr * If a driver matches the hardware, it should set the device
95131988Sdfr * description string using device_set_desc() or
96131988Sdfr * device_set_desc_copy(). This string is
97131988Sdfr * used to generate an informative message when DEVICE_ATTACH()
98131988Sdfr * is called.
99131988Sdfr * 
100131988Sdfr * As a special case, if a driver returns zero, the driver election
101131988Sdfr * is cut short and that driver will attach to the device
102131988Sdfr * immediately.
103131988Sdfr *
104131988Sdfr * For example, a probe method for a pci device driver might look
105131988Sdfr * like this:
106131988Sdfr *
107131988Sdfr * @code
108131988Sdfr * int foo_probe(device_t dev)
109131988Sdfr * {
110131988Sdfr *         if (pci_get_vendor(dev) == FOOVENDOR &&
111131988Sdfr *             pci_get_device(dev) == FOODEVICE) {
112131988Sdfr *                 device_set_desc(dev, "Foo device");
113131988Sdfr *                 return (0);
114131988Sdfr *         }
115131988Sdfr *         return (ENXIO);
116131988Sdfr * }
117131988Sdfr * @endcode
118131988Sdfr *
119131988Sdfr * To include this method in a device driver, use a line like this
120131988Sdfr * in the driver's method list:
121131988Sdfr *
122131988Sdfr * @code
123131988Sdfr * 	KOBJMETHOD(device_probe, foo_probe)
124131988Sdfr * @endcode
125131988Sdfr *
126131988Sdfr * @param dev		the device to probe
127131988Sdfr *
128131988Sdfr * @retval 0		if the driver strongly matches this device
129131988Sdfr * @retval negative	if the driver can match this device - the
130131988Sdfr *			least negative value is used to select the
131131988Sdfr *			driver
132131988Sdfr * @retval ENXIO	if the driver does not match the device
133131988Sdfr * @retval positive	if some kind of error was detected during
134131988Sdfr *			the probe, a regular unix error code should
135131988Sdfr *			be returned to indicate the type of error
136131988Sdfr * @see DEVICE_ATTACH(), pci_get_vendor(), pci_get_device()
137131988Sdfr */
13836973SdfrMETHOD int probe {
13936973Sdfr	device_t dev;
14036973Sdfr};
14136973Sdfr
142131988Sdfr/**
143133588Simp * @brief Allow a device driver to detect devices not otherwise enumerated.
144131988Sdfr *
145133588Simp * The DEVICE_IDENTIFY() method is used by some drivers (e.g. the ISA
146133588Simp * bus driver) to help populate the bus device with a useful set of
147133588Simp * child devices, normally by calling the BUS_ADD_CHILD() method of
148133588Simp * the parent device. For instance, the ISA bus driver uses several
149133588Simp * special drivers, including the isahint driver and the pnp driver to
150133588Simp * create child devices based on configuration hints and PnP bus
151131988Sdfr * probes respectively.
152131988Sdfr *
153133588Simp * Many bus drivers which support true plug-and-play do not need to
154133588Simp * use this method at all since child devices can be discovered
155133588Simp * automatically without help from child drivers.
156131988Sdfr *
157131988Sdfr * To include this method in a device driver, use a line like this
158131988Sdfr * in the driver's method list:
159131988Sdfr *
160131988Sdfr * @code
161131988Sdfr * 	KOBJMETHOD(device_identify, foo_identify)
162131988Sdfr * @endcode
163131988Sdfr *
164131988Sdfr * @param driver	the driver whose identify method is being called
165131988Sdfr * @param parent	the parent device to use when adding new children
166131988Sdfr */
16747178SdfrSTATICMETHOD void identify {
16847178Sdfr	driver_t *driver;
16947178Sdfr	device_t parent;
17047178Sdfr};
17147178Sdfr
172131988Sdfr/**
173131988Sdfr * @brief Attach a device to a device driver
174131988Sdfr *
175131988Sdfr * Normally only called via device_probe_and_attach(), this is called
176131988Sdfr * when a driver has succeeded in probing against a device.
177131988Sdfr * This method should initialise the hardware and allocate other
178131988Sdfr * system resources (e.g. devfs entries) as required.
179131988Sdfr *
180131988Sdfr * To include this method in a device driver, use a line like this
181131988Sdfr * in the driver's method list:
182131988Sdfr *
183131988Sdfr * @code
184131988Sdfr * 	KOBJMETHOD(device_attach, foo_attach)
185131988Sdfr * @endcode
186131988Sdfr *
187131988Sdfr * @param dev		the device to probe
188131988Sdfr *
189131988Sdfr * @retval 0		success
190131988Sdfr * @retval non-zero	if some kind of error was detected during
191131988Sdfr *			the attach, a regular unix error code should
192131988Sdfr *			be returned to indicate the type of error
193131988Sdfr * @see DEVICE_PROBE()
194131988Sdfr */
19536973SdfrMETHOD int attach {
19636973Sdfr	device_t dev;
19736973Sdfr};
19836973Sdfr
199131988Sdfr/**
200131988Sdfr * @brief Detach a driver from a device.
201131988Sdfr *
202131988Sdfr * This can be called if the user is replacing the
203131988Sdfr * driver software or if a device is about to be physically removed
204131988Sdfr * from the system (e.g. for removable hardware such as USB or PCCARD).
205131988Sdfr *
206131988Sdfr * To include this method in a device driver, use a line like this
207131988Sdfr * in the driver's method list:
208131988Sdfr *
209131988Sdfr * @code
210131988Sdfr * 	KOBJMETHOD(device_detach, foo_detach)
211131988Sdfr * @endcode
212131988Sdfr *
213131988Sdfr * @param dev		the device to detach
214131988Sdfr *
215131988Sdfr * @retval 0		success
216131988Sdfr * @retval non-zero	the detach could not be performed, e.g. if the
217131988Sdfr *			driver does not support detaching.
218131988Sdfr *
219131988Sdfr * @see DEVICE_ATTACH()
220131988Sdfr */
22136973SdfrMETHOD int detach {
22236973Sdfr	device_t dev;
22336973Sdfr};
22436973Sdfr
225131988Sdfr/**
226131988Sdfr * @brief Called during system shutdown.
227131988Sdfr *
228131988Sdfr * This method allows drivers to detect when the system is being shut down.
229131988Sdfr * Some drivers need to use this to place their hardware in a consistent
230131988Sdfr * state before rebooting the computer.
231131988Sdfr *
232131988Sdfr * To include this method in a device driver, use a line like this
233131988Sdfr * in the driver's method list:
234131988Sdfr *
235131988Sdfr * @code
236131988Sdfr * 	KOBJMETHOD(device_shutdown, foo_shutdown)
237131988Sdfr * @endcode
238131988Sdfr */
23936973SdfrMETHOD int shutdown {
24036973Sdfr	device_t dev;
24146913Sdfr} DEFAULT null_shutdown;
24241153Swollman
243131988Sdfr/**
244133588Simp * @brief This is called by the power-management subsystem when a
245133588Simp * suspend has been requested by the user or by some automatic
246133588Simp * mechanism.
247131988Sdfr *
248133588Simp * This gives drivers a chance to veto the suspend or save their
249133588Simp * configuration before power is removed.
250131988Sdfr *
251133588Simp * To include this method in a device driver, use a line like this in
252133588Simp * the driver's method list:
253131988Sdfr *
254131988Sdfr * @code
255131988Sdfr * 	KOBJMETHOD(device_suspend, foo_suspend)
256131988Sdfr * @endcode
257131988Sdfr *
258131988Sdfr * @param dev		the device being suspended
259131988Sdfr *
260131988Sdfr * @retval 0		success
261133588Simp * @retval non-zero	an error occurred while attempting to prepare the
262133588Simp *                      device for suspension
263131988Sdfr *
264131988Sdfr * @see DEVICE_RESUME()
265131988Sdfr */
26641153SwollmanMETHOD int suspend {
26741153Swollman	device_t dev;
26846913Sdfr} DEFAULT null_suspend;
26941153Swollman
270131988Sdfr/**
271131988Sdfr * @brief This is called when the system resumes after a suspend.
272131988Sdfr *
273131988Sdfr * To include this method in a device driver, use a line like this
274131988Sdfr * in the driver's method list:
275131988Sdfr *
276131988Sdfr * @code
277131988Sdfr * 	KOBJMETHOD(device_resume, foo_resume)
278131988Sdfr * @endcode
279131988Sdfr *
280131988Sdfr * @param dev		the device being resumed
281131988Sdfr *
282131988Sdfr * @retval 0		success
283133588Simp * @retval non-zero	an error occurred while attempting to restore the
284133588Simp *                      device from suspension
285131988Sdfr *
286131988Sdfr * @see DEVICE_SUSPEND()
287131988Sdfr */
28841153SwollmanMETHOD int resume {
28941153Swollman	device_t dev;
29046913Sdfr} DEFAULT null_resume;
291139507Simp
292139507Simp/**
293139507Simp * @brief This is called when the driver is asked to quiesce itself.
294139507Simp *
295139507Simp * The driver should arrange for the orderly shutdown of this device.
296139507Simp * All further access to the device should be curtailed.  Soon there
297139507Simp * will be a request to detach, but there won't necessarily be one.
298139507Simp *
299139507Simp * To include this method in a device driver, use a line like this
300139507Simp * in the driver's method list:
301139507Simp *
302139507Simp * @code
303139507Simp * 	KOBJMETHOD(device_quiesce, foo_quiesce)
304139507Simp * @endcode
305139507Simp *
306139507Simp * @param dev		the device being quiesced
307139507Simp *
308139507Simp * @retval 0		success
309139507Simp * @retval non-zero	an error occurred while attempting to quiesce the
310139507Simp *                      device
311139507Simp *
312139507Simp * @see DEVICE_DETACH()
313139507Simp */
314139507SimpMETHOD int quiesce {
315139507Simp	device_t dev;
316139507Simp} DEFAULT null_quiesce;
317