device_if.m revision 133588
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 133588 2004-08-12 17:26:22Z 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	
62131988Sdfr/**
63131988Sdfr * @brief Probe to see if a device matches a driver.
64131988Sdfr *
65131988Sdfr * 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 */
13336973SdfrMETHOD int probe {
13436973Sdfr	device_t dev;
13536973Sdfr};
13636973Sdfr
137131988Sdfr/**
138133588Simp * @brief Allow a device driver to detect devices not otherwise enumerated.
139131988Sdfr *
140133588Simp * The DEVICE_IDENTIFY() method is used by some drivers (e.g. the ISA
141133588Simp * bus driver) to help populate the bus device with a useful set of
142133588Simp * child devices, normally by calling the BUS_ADD_CHILD() method of
143133588Simp * the parent device. For instance, the ISA bus driver uses several
144133588Simp * special drivers, including the isahint driver and the pnp driver to
145133588Simp * create child devices based on configuration hints and PnP bus
146131988Sdfr * probes respectively.
147131988Sdfr *
148133588Simp * Many bus drivers which support true plug-and-play do not need to
149133588Simp * use this method at all since child devices can be discovered
150133588Simp * automatically without help from child drivers.
151131988Sdfr *
152131988Sdfr * To include this method in a device driver, use a line like this
153131988Sdfr * in the driver's method list:
154131988Sdfr *
155131988Sdfr * @code
156131988Sdfr * 	KOBJMETHOD(device_identify, foo_identify)
157131988Sdfr * @endcode
158131988Sdfr *
159131988Sdfr * @param driver	the driver whose identify method is being called
160131988Sdfr * @param parent	the parent device to use when adding new children
161131988Sdfr */
16247178SdfrSTATICMETHOD void identify {
16347178Sdfr	driver_t *driver;
16447178Sdfr	device_t parent;
16547178Sdfr};
16647178Sdfr
167131988Sdfr/**
168131988Sdfr * @brief Attach a device to a device driver
169131988Sdfr *
170131988Sdfr * Normally only called via device_probe_and_attach(), this is called
171131988Sdfr * when a driver has succeeded in probing against a device.
172131988Sdfr * This method should initialise the hardware and allocate other
173131988Sdfr * system resources (e.g. devfs entries) as required.
174131988Sdfr *
175131988Sdfr * To include this method in a device driver, use a line like this
176131988Sdfr * in the driver's method list:
177131988Sdfr *
178131988Sdfr * @code
179131988Sdfr * 	KOBJMETHOD(device_attach, foo_attach)
180131988Sdfr * @endcode
181131988Sdfr *
182131988Sdfr * @param dev		the device to probe
183131988Sdfr *
184131988Sdfr * @retval 0		success
185131988Sdfr * @retval non-zero	if some kind of error was detected during
186131988Sdfr *			the attach, a regular unix error code should
187131988Sdfr *			be returned to indicate the type of error
188131988Sdfr * @see DEVICE_PROBE()
189131988Sdfr */
19036973SdfrMETHOD int attach {
19136973Sdfr	device_t dev;
19236973Sdfr};
19336973Sdfr
194131988Sdfr/**
195131988Sdfr * @brief Detach a driver from a device.
196131988Sdfr *
197131988Sdfr * This can be called if the user is replacing the
198131988Sdfr * driver software or if a device is about to be physically removed
199131988Sdfr * from the system (e.g. for removable hardware such as USB or PCCARD).
200131988Sdfr *
201131988Sdfr * To include this method in a device driver, use a line like this
202131988Sdfr * in the driver's method list:
203131988Sdfr *
204131988Sdfr * @code
205131988Sdfr * 	KOBJMETHOD(device_detach, foo_detach)
206131988Sdfr * @endcode
207131988Sdfr *
208131988Sdfr * @param dev		the device to detach
209131988Sdfr *
210131988Sdfr * @retval 0		success
211131988Sdfr * @retval non-zero	the detach could not be performed, e.g. if the
212131988Sdfr *			driver does not support detaching.
213131988Sdfr *
214131988Sdfr * @see DEVICE_ATTACH()
215131988Sdfr */
21636973SdfrMETHOD int detach {
21736973Sdfr	device_t dev;
21836973Sdfr};
21936973Sdfr
220131988Sdfr/**
221131988Sdfr * @brief Called during system shutdown.
222131988Sdfr *
223131988Sdfr * This method allows drivers to detect when the system is being shut down.
224131988Sdfr * Some drivers need to use this to place their hardware in a consistent
225131988Sdfr * state before rebooting the computer.
226131988Sdfr *
227131988Sdfr * To include this method in a device driver, use a line like this
228131988Sdfr * in the driver's method list:
229131988Sdfr *
230131988Sdfr * @code
231131988Sdfr * 	KOBJMETHOD(device_shutdown, foo_shutdown)
232131988Sdfr * @endcode
233131988Sdfr */
23436973SdfrMETHOD int shutdown {
23536973Sdfr	device_t dev;
23646913Sdfr} DEFAULT null_shutdown;
23741153Swollman
238131988Sdfr/**
239133588Simp * @brief This is called by the power-management subsystem when a
240133588Simp * suspend has been requested by the user or by some automatic
241133588Simp * mechanism.
242131988Sdfr *
243133588Simp * This gives drivers a chance to veto the suspend or save their
244133588Simp * configuration before power is removed.
245131988Sdfr *
246133588Simp * To include this method in a device driver, use a line like this in
247133588Simp * the driver's method list:
248131988Sdfr *
249131988Sdfr * @code
250131988Sdfr * 	KOBJMETHOD(device_suspend, foo_suspend)
251131988Sdfr * @endcode
252131988Sdfr *
253131988Sdfr * @param dev		the device being suspended
254131988Sdfr *
255131988Sdfr * @retval 0		success
256133588Simp * @retval non-zero	an error occurred while attempting to prepare the
257133588Simp *                      device for suspension
258131988Sdfr *
259131988Sdfr * @see DEVICE_RESUME()
260131988Sdfr */
26141153SwollmanMETHOD int suspend {
26241153Swollman	device_t dev;
26346913Sdfr} DEFAULT null_suspend;
26441153Swollman
265131988Sdfr/**
266131988Sdfr * @brief This is called when the system resumes after a suspend.
267131988Sdfr *
268131988Sdfr * To include this method in a device driver, use a line like this
269131988Sdfr * in the driver's method list:
270131988Sdfr *
271131988Sdfr * @code
272131988Sdfr * 	KOBJMETHOD(device_resume, foo_resume)
273131988Sdfr * @endcode
274131988Sdfr *
275131988Sdfr * @param dev		the device being resumed
276131988Sdfr *
277131988Sdfr * @retval 0		success
278133588Simp * @retval non-zero	an error occurred while attempting to restore the
279133588Simp *                      device from suspension
280131988Sdfr *
281131988Sdfr * @see DEVICE_SUSPEND()
282131988Sdfr */
28341153SwollmanMETHOD int resume {
28441153Swollman	device_t dev;
28546913Sdfr} DEFAULT null_resume;
286