device_if.m revision 131988
136973Sdfr#
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 131988 2004-07-11 16:17:42Z dfr $
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	
62139507Simp/**
63139507Simp * @brief Probe to see if a device matches a driver.
64139507Simp *
6546913Sdfr * Users should not call this method directly. Normally, this
66131988Sdfr * is called via device_probe_and_attach() to select a driver
67131988Sdfr * calling the DEVICE_PROBE() of all candidate drivers and attach
68131988Sdfr * the winning driver (if any) to the device.
69131988Sdfr *
70131988Sdfr * This function is used to match devices to device drivers.
71131988Sdfr * Typically, the driver will examine the device to see if
72131988Sdfr * it is suitable for this driver. This might include checking
73131988Sdfr * the values of various device instance variables or reading
74131988Sdfr * hardware registers.
75131988Sdfr *  
76131988Sdfr * In some cases, there may be more than one driver available
77131988Sdfr * which can be used for a device (for instance there might
78131988Sdfr * be a generic driver which works for a set of many types of
79131988Sdfr * device and a more specific driver which works for a subset
80131988Sdfr * of devices). Because of this, a driver should not assume
81131988Sdfr * that it will be the driver that attaches to the device even
82131988Sdfr * if it returns a success status from DEVICE_PROBE(). In particular,
83131988Sdfr * a driver must free any resources which it allocated during
84131988Sdfr * the probe before returning. The return value of DEVICE_PROBE()
85131988Sdfr * is used to elect which driver is used - the driver which returns
86131988Sdfr * the largest non-error value wins the election and attaches to
87131988Sdfr * the device.
88131988Sdfr *
89131988Sdfr * If a driver matches the hardware, it should set the device
90131988Sdfr * description string using device_set_desc() or
91131988Sdfr * device_set_desc_copy(). This string is
92131988Sdfr * used to generate an informative message when DEVICE_ATTACH()
93131988Sdfr * is called.
94131988Sdfr * 
95131988Sdfr * As a special case, if a driver returns zero, the driver election
96131988Sdfr * is cut short and that driver will attach to the device
97131988Sdfr * immediately.
98131988Sdfr *
99131988Sdfr * For example, a probe method for a pci device driver might look
100131988Sdfr * like this:
101131988Sdfr *
102131988Sdfr * @code
103131988Sdfr * int foo_probe(device_t dev)
104131988Sdfr * {
105131988Sdfr *         if (pci_get_vendor(dev) == FOOVENDOR &&
106131988Sdfr *             pci_get_device(dev) == FOODEVICE) {
107131988Sdfr *                 device_set_desc(dev, "Foo device");
108131988Sdfr *                 return (0);
109131988Sdfr *         }
110131988Sdfr *         return (ENXIO);
111131988Sdfr * }
112131988Sdfr * @endcode
113131988Sdfr *
114131988Sdfr * To include this method in a device driver, use a line like this
115131988Sdfr * in the driver's method list:
116131988Sdfr *
117131988Sdfr * @code
118131988Sdfr * 	KOBJMETHOD(device_probe, foo_probe)
119131988Sdfr * @endcode
120131988Sdfr *
121131988Sdfr * @param dev		the device to probe
122131988Sdfr *
123131988Sdfr * @retval 0		if the driver strongly matches this device
124131988Sdfr * @retval negative	if the driver can match this device - the
125131988Sdfr *			least negative value is used to select the
126131988Sdfr *			driver
127131988Sdfr * @retval ENXIO	if the driver does not match the device
128131988Sdfr * @retval positive	if some kind of error was detected during
129131988Sdfr *			the probe, a regular unix error code should
130131988Sdfr *			be returned to indicate the type of error
131131988Sdfr * @see DEVICE_ATTACH(), pci_get_vendor(), pci_get_device()
132131988Sdfr */
133131988SdfrMETHOD int probe {
134131988Sdfr	device_t dev;
135131988Sdfr};
136131988Sdfr
137131988Sdfr/**
13836973Sdfr * @brief Called by a parent device to allow drivers to add new devices to the parent.
13936973Sdfr *
14036973Sdfr * The DEVICE_IDENTIFY() method is used by some drivers (e.g. the ISA bus driver)
14136973Sdfr * to help populate the bus device with a useful set of child devices, normally by
142131988Sdfr * calling the BUS_ADD_CHILD() method of the parent device. For instance,
143133588Simp * the ISA bus driver uses several special drivers, including the isahint driver and
144131988Sdfr * the pnp driver to create child devices based on configuration hints and PnP bus
145133588Simp * probes respectively.
146133588Simp *
147133588Simp * Many bus drivers which support true plug-and-play do not need to use this method
148133588Simp * at all since child devices can be discovered automatically without help from
149133588Simp * child drivers.
150133588Simp *
151131988Sdfr * To include this method in a device driver, use a line like this
152131988Sdfr * in the driver's method list:
153133588Simp *
154133588Simp * @code
155133588Simp * 	KOBJMETHOD(device_identify, foo_identify)
156131988Sdfr * @endcode
157131988Sdfr *
158131988Sdfr * @param driver	the driver whose identify method is being called
159131988Sdfr * @param parent	the parent device to use when adding new children
160131988Sdfr */
161131988SdfrSTATICMETHOD void identify {
162131988Sdfr	driver_t *driver;
163131988Sdfr	device_t parent;
164131988Sdfr};
165131988Sdfr
166131988Sdfr/**
16747178Sdfr * @brief Attach a device to a device driver
16847178Sdfr *
16947178Sdfr * Normally only called via device_probe_and_attach(), this is called
17047178Sdfr * when a driver has succeeded in probing against a device.
17147178Sdfr * This method should initialise the hardware and allocate other
172131988Sdfr * system resources (e.g. devfs entries) as required.
173131988Sdfr *
174131988Sdfr * To include this method in a device driver, use a line like this
175131988Sdfr * in the driver's method list:
176131988Sdfr *
177131988Sdfr * @code
178131988Sdfr * 	KOBJMETHOD(device_attach, foo_attach)
179131988Sdfr * @endcode
180131988Sdfr *
181131988Sdfr * @param dev		the device to probe
182131988Sdfr *
183131988Sdfr * @retval 0		success
184131988Sdfr * @retval non-zero	if some kind of error was detected during
185131988Sdfr *			the attach, a regular unix error code should
186131988Sdfr *			be returned to indicate the type of error
187131988Sdfr * @see DEVICE_PROBE()
188131988Sdfr */
189131988SdfrMETHOD int attach {
190131988Sdfr	device_t dev;
191131988Sdfr};
192131988Sdfr
193131988Sdfr/**
194131988Sdfr * @brief Detach a driver from a device.
19536973Sdfr *
19636973Sdfr * This can be called if the user is replacing the
19736973Sdfr * driver software or if a device is about to be physically removed
19836973Sdfr * from the system (e.g. for removable hardware such as USB or PCCARD).
199131988Sdfr *
200131988Sdfr * To include this method in a device driver, use a line like this
201131988Sdfr * in the driver's method list:
202131988Sdfr *
203131988Sdfr * @code
204131988Sdfr * 	KOBJMETHOD(device_detach, foo_detach)
205131988Sdfr * @endcode
206131988Sdfr *
207131988Sdfr * @param dev		the device to detach
208131988Sdfr *
209131988Sdfr * @retval 0		success
210131988Sdfr * @retval non-zero	the detach could not be performed, e.g. if the
211131988Sdfr *			driver does not support detaching.
212131988Sdfr *
213131988Sdfr * @see DEVICE_ATTACH()
214131988Sdfr */
215131988SdfrMETHOD int detach {
216131988Sdfr	device_t dev;
217131988Sdfr};
218131988Sdfr
219131988Sdfr/**
220131988Sdfr * @brief Called during system shutdown.
22136973Sdfr *
22236973Sdfr * This method allows drivers to detect when the system is being shut down.
22336973Sdfr * Some drivers need to use this to place their hardware in a consistent
22436973Sdfr * state before rebooting the computer.
225131988Sdfr *
226131988Sdfr * To include this method in a device driver, use a line like this
227131988Sdfr * in the driver's method list:
228131988Sdfr *
229131988Sdfr * @code
230131988Sdfr * 	KOBJMETHOD(device_shutdown, foo_shutdown)
231131988Sdfr * @endcode
232131988Sdfr */
233131988SdfrMETHOD int shutdown {
234131988Sdfr	device_t dev;
235131988Sdfr} DEFAULT null_shutdown;
236131988Sdfr
237131988Sdfr/**
238131988Sdfr * @brief This is called by the power-management subsystem when a suspend has been
23936973Sdfr * requested by the user or by some automatic mechanism.
24036973Sdfr *
24146913Sdfr * This gives
24241153Swollman * drivers a chance to veto the suspend or save their configuration before
243131988Sdfr * power is removed.
244133588Simp *
245133588Simp * To include this method in a device driver, use a line like this
246133588Simp * in the driver's method list:
247131988Sdfr *
248133588Simp * @code
249133588Simp * 	KOBJMETHOD(device_suspend, foo_suspend)
250131988Sdfr * @endcode
251133588Simp *
252133588Simp * @param dev		the device being suspended
253131988Sdfr *
254131988Sdfr * @retval 0		success
255131988Sdfr * @retval non-zero	an error occurred while attempting to prepare the device
256131988Sdfr * 			for suspension
257131988Sdfr *
258131988Sdfr * @see DEVICE_RESUME()
259131988Sdfr */
260131988SdfrMETHOD int suspend {
261133588Simp	device_t dev;
262133588Simp} DEFAULT null_suspend;
263131988Sdfr
264131988Sdfr/**
265131988Sdfr * @brief This is called when the system resumes after a suspend.
26641153Swollman *
26741153Swollman * To include this method in a device driver, use a line like this
26846913Sdfr * in the driver's method list:
26941153Swollman *
270131988Sdfr * @code
271131988Sdfr * 	KOBJMETHOD(device_resume, foo_resume)
272131988Sdfr * @endcode
273131988Sdfr *
274131988Sdfr * @param dev		the device being resumed
275131988Sdfr *
276131988Sdfr * @retval 0		success
277131988Sdfr * @retval non-zero	an error occurred while attempting to restore the device
278131988Sdfr * 			from suspension
279131988Sdfr *
280131988Sdfr * @see DEVICE_SUSPEND()
281131988Sdfr */
282131988SdfrMETHOD int resume {
283133588Simp	device_t dev;
284133588Simp} DEFAULT null_resume;
285131988Sdfr