device_if.m revision 139507
136973Sdfr#
2131988Sdfr# 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 139507 2004-12-31 20:47:51Z 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	}
6046913Sdfr
61131988Sdfr	static int null_quiesce(device_t dev)
62131988Sdfr	{
63131988Sdfr	    return EOPNOTSUPP;
64131988Sdfr	}
65131988Sdfr};
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
13336973Sdfr * @retval positive	if some kind of error was detected during
13436973Sdfr *			the probe, a regular unix error code should
13536973Sdfr *			be returned to indicate the type of error
13636973Sdfr * @see DEVICE_ATTACH(), pci_get_vendor(), pci_get_device()
137131988Sdfr */
138131988SdfrMETHOD int probe {
139131988Sdfr	device_t dev;
140131988Sdfr};
141131988Sdfr
142131988Sdfr/**
143131988Sdfr * @brief Allow a device driver to detect devices not otherwise enumerated.
144131988Sdfr *
145131988Sdfr * The DEVICE_IDENTIFY() method is used by some drivers (e.g. the ISA
146131988Sdfr * bus driver) to help populate the bus device with a useful set of
147131988Sdfr * child devices, normally by calling the BUS_ADD_CHILD() method of
148131988Sdfr * the parent device. For instance, the ISA bus driver uses several
149131988Sdfr * special drivers, including the isahint driver and the pnp driver to
150131988Sdfr * create child devices based on configuration hints and PnP bus
151131988Sdfr * probes respectively.
152131988Sdfr *
153131988Sdfr * Many bus drivers which support true plug-and-play do not need to
154131988Sdfr * use this method at all since child devices can be discovered
155131988Sdfr * 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
16147178Sdfr * 	KOBJMETHOD(device_identify, foo_identify)
16247178Sdfr * @endcode
16347178Sdfr *
16447178Sdfr * @param driver	the driver whose identify method is being called
16547178Sdfr * @param parent	the parent device to use when adding new children
166131988Sdfr */
167131988SdfrSTATICMETHOD void identify {
168131988Sdfr	driver_t *driver;
169131988Sdfr	device_t parent;
170131988Sdfr};
171131988Sdfr
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 *
18936973Sdfr * @retval 0		success
19036973Sdfr * @retval non-zero	if some kind of error was detected during
19136973Sdfr *			the attach, a regular unix error code should
19236973Sdfr *			be returned to indicate the type of error
193131988Sdfr * @see DEVICE_PROBE()
194131988Sdfr */
195131988SdfrMETHOD int attach {
196131988Sdfr	device_t dev;
197131988Sdfr};
198131988Sdfr
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 *
21536973Sdfr * @retval 0		success
21636973Sdfr * @retval non-zero	the detach could not be performed, e.g. if the
21736973Sdfr *			driver does not support detaching.
21836973Sdfr *
219131988Sdfr * @see DEVICE_ATTACH()
220131988Sdfr */
221131988SdfrMETHOD int detach {
222131988Sdfr	device_t dev;
223131988Sdfr};
224131988Sdfr
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
23336973Sdfr * in the driver's method list:
23436973Sdfr *
23546913Sdfr * @code
23641153Swollman * 	KOBJMETHOD(device_shutdown, foo_shutdown)
237131988Sdfr * @endcode
238131988Sdfr */
239131988SdfrMETHOD int shutdown {
240131988Sdfr	device_t dev;
241131988Sdfr} DEFAULT null_shutdown;
242131988Sdfr
243131988Sdfr/**
244131988Sdfr * @brief This is called by the power-management subsystem when a
245131988Sdfr * suspend has been requested by the user or by some automatic
246131988Sdfr * mechanism.
247131988Sdfr *
248131988Sdfr * This gives drivers a chance to veto the suspend or save their
249131988Sdfr * configuration before power is removed.
250131988Sdfr *
251131988Sdfr * To include this method in a device driver, use a line like this in
252131988Sdfr * 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 *
26041153Swollman * @retval 0		success
26141153Swollman * @retval non-zero	an error occurred while attempting to prepare the
26246913Sdfr *                      device for suspension
26341153Swollman *
264131988Sdfr * @see DEVICE_RESUME()
265131988Sdfr */
266131988SdfrMETHOD int suspend {
267131988Sdfr	device_t dev;
268131988Sdfr} DEFAULT null_suspend;
269131988Sdfr
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 *
28241153Swollman * @retval 0		success
28341153Swollman * @retval non-zero	an error occurred while attempting to restore the
28446913Sdfr *                      device from suspension
285 *
286 * @see DEVICE_SUSPEND()
287 */
288METHOD int resume {
289	device_t dev;
290} DEFAULT null_resume;
291
292/**
293 * @brief This is called when the driver is asked to quiesce itself.
294 *
295 * The driver should arrange for the orderly shutdown of this device.
296 * All further access to the device should be curtailed.  Soon there
297 * will be a request to detach, but there won't necessarily be one.
298 *
299 * To include this method in a device driver, use a line like this
300 * in the driver's method list:
301 *
302 * @code
303 * 	KOBJMETHOD(device_quiesce, foo_quiesce)
304 * @endcode
305 *
306 * @param dev		the device being quiesced
307 *
308 * @retval 0		success
309 * @retval non-zero	an error occurred while attempting to quiesce the
310 *                      device
311 *
312 * @see DEVICE_DETACH()
313 */
314METHOD int quiesce {
315	device_t dev;
316} DEFAULT null_quiesce;
317