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$
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
92222253Sjhb * the device. Common non-error values are described in the
93222253Sjhb * DEVICE_PROBE(9) manual page.
94131988Sdfr *
95131988Sdfr * If a driver matches the hardware, it should set the device
96131988Sdfr * description string using device_set_desc() or
97222253Sjhb * device_set_desc_copy(). This string is used to generate an
98222253Sjhb * informative message when DEVICE_ATTACH() 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
102222253Sjhb * immediately. This should rarely be used.
103131988Sdfr *
104222253Sjhb * For example, a probe method for a PCI device driver might look
105131988Sdfr * like this:
106131988Sdfr *
107131988Sdfr * @code
108222253Sjhb * int
109222253Sjhb * foo_probe(device_t dev)
110131988Sdfr * {
111131988Sdfr *         if (pci_get_vendor(dev) == FOOVENDOR &&
112131988Sdfr *             pci_get_device(dev) == FOODEVICE) {
113131988Sdfr *                 device_set_desc(dev, "Foo device");
114222253Sjhb *                 return (BUS_PROBE_DEFAULT);
115131988Sdfr *         }
116131988Sdfr *         return (ENXIO);
117131988Sdfr * }
118131988Sdfr * @endcode
119131988Sdfr *
120131988Sdfr * To include this method in a device driver, use a line like this
121131988Sdfr * in the driver's method list:
122131988Sdfr *
123131988Sdfr * @code
124131988Sdfr * 	KOBJMETHOD(device_probe, foo_probe)
125131988Sdfr * @endcode
126131988Sdfr *
127131988Sdfr * @param dev		the device to probe
128131988Sdfr *
129222253Sjhb * @retval 0		if this is the only possible driver for this
130222253Sjhb *			device
131131988Sdfr * @retval negative	if the driver can match this device - the
132131988Sdfr *			least negative value is used to select the
133131988Sdfr *			driver
134131988Sdfr * @retval ENXIO	if the driver does not match the device
135131988Sdfr * @retval positive	if some kind of error was detected during
136131988Sdfr *			the probe, a regular unix error code should
137131988Sdfr *			be returned to indicate the type of error
138131988Sdfr * @see DEVICE_ATTACH(), pci_get_vendor(), pci_get_device()
139131988Sdfr */
14036973SdfrMETHOD int probe {
14136973Sdfr	device_t dev;
14236973Sdfr};
14336973Sdfr
144131988Sdfr/**
145133588Simp * @brief Allow a device driver to detect devices not otherwise enumerated.
146131988Sdfr *
147133588Simp * The DEVICE_IDENTIFY() method is used by some drivers (e.g. the ISA
148133588Simp * bus driver) to help populate the bus device with a useful set of
149133588Simp * child devices, normally by calling the BUS_ADD_CHILD() method of
150133588Simp * the parent device. For instance, the ISA bus driver uses several
151133588Simp * special drivers, including the isahint driver and the pnp driver to
152133588Simp * create child devices based on configuration hints and PnP bus
153131988Sdfr * probes respectively.
154131988Sdfr *
155133588Simp * Many bus drivers which support true plug-and-play do not need to
156133588Simp * use this method at all since child devices can be discovered
157133588Simp * automatically without help from child drivers.
158131988Sdfr *
159131988Sdfr * To include this method in a device driver, use a line like this
160131988Sdfr * in the driver's method list:
161131988Sdfr *
162131988Sdfr * @code
163131988Sdfr * 	KOBJMETHOD(device_identify, foo_identify)
164131988Sdfr * @endcode
165131988Sdfr *
166131988Sdfr * @param driver	the driver whose identify method is being called
167131988Sdfr * @param parent	the parent device to use when adding new children
168131988Sdfr */
16947178SdfrSTATICMETHOD void identify {
17047178Sdfr	driver_t *driver;
17147178Sdfr	device_t parent;
17247178Sdfr};
17347178Sdfr
174131988Sdfr/**
175131988Sdfr * @brief Attach a device to a device driver
176131988Sdfr *
177131988Sdfr * Normally only called via device_probe_and_attach(), this is called
178131988Sdfr * when a driver has succeeded in probing against a device.
179131988Sdfr * This method should initialise the hardware and allocate other
180131988Sdfr * system resources (e.g. devfs entries) as required.
181131988Sdfr *
182131988Sdfr * To include this method in a device driver, use a line like this
183131988Sdfr * in the driver's method list:
184131988Sdfr *
185131988Sdfr * @code
186131988Sdfr * 	KOBJMETHOD(device_attach, foo_attach)
187131988Sdfr * @endcode
188131988Sdfr *
189131988Sdfr * @param dev		the device to probe
190131988Sdfr *
191131988Sdfr * @retval 0		success
192131988Sdfr * @retval non-zero	if some kind of error was detected during
193131988Sdfr *			the attach, a regular unix error code should
194131988Sdfr *			be returned to indicate the type of error
195131988Sdfr * @see DEVICE_PROBE()
196131988Sdfr */
19736973SdfrMETHOD int attach {
19836973Sdfr	device_t dev;
19936973Sdfr};
20036973Sdfr
201131988Sdfr/**
202131988Sdfr * @brief Detach a driver from a device.
203131988Sdfr *
204131988Sdfr * This can be called if the user is replacing the
205131988Sdfr * driver software or if a device is about to be physically removed
206131988Sdfr * from the system (e.g. for removable hardware such as USB or PCCARD).
207131988Sdfr *
208131988Sdfr * To include this method in a device driver, use a line like this
209131988Sdfr * in the driver's method list:
210131988Sdfr *
211131988Sdfr * @code
212131988Sdfr * 	KOBJMETHOD(device_detach, foo_detach)
213131988Sdfr * @endcode
214131988Sdfr *
215131988Sdfr * @param dev		the device to detach
216131988Sdfr *
217131988Sdfr * @retval 0		success
218131988Sdfr * @retval non-zero	the detach could not be performed, e.g. if the
219131988Sdfr *			driver does not support detaching.
220131988Sdfr *
221131988Sdfr * @see DEVICE_ATTACH()
222131988Sdfr */
22336973SdfrMETHOD int detach {
22436973Sdfr	device_t dev;
22536973Sdfr};
22636973Sdfr
227131988Sdfr/**
228131988Sdfr * @brief Called during system shutdown.
229131988Sdfr *
230131988Sdfr * This method allows drivers to detect when the system is being shut down.
231131988Sdfr * Some drivers need to use this to place their hardware in a consistent
232131988Sdfr * state before rebooting the computer.
233131988Sdfr *
234131988Sdfr * To include this method in a device driver, use a line like this
235131988Sdfr * in the driver's method list:
236131988Sdfr *
237131988Sdfr * @code
238131988Sdfr * 	KOBJMETHOD(device_shutdown, foo_shutdown)
239131988Sdfr * @endcode
240131988Sdfr */
24136973SdfrMETHOD int shutdown {
24236973Sdfr	device_t dev;
24346913Sdfr} DEFAULT null_shutdown;
24441153Swollman
245131988Sdfr/**
246133588Simp * @brief This is called by the power-management subsystem when a
247133588Simp * suspend has been requested by the user or by some automatic
248133588Simp * mechanism.
249131988Sdfr *
250133588Simp * This gives drivers a chance to veto the suspend or save their
251133588Simp * configuration before power is removed.
252131988Sdfr *
253133588Simp * To include this method in a device driver, use a line like this in
254133588Simp * the driver's method list:
255131988Sdfr *
256131988Sdfr * @code
257131988Sdfr * 	KOBJMETHOD(device_suspend, foo_suspend)
258131988Sdfr * @endcode
259131988Sdfr *
260131988Sdfr * @param dev		the device being suspended
261131988Sdfr *
262131988Sdfr * @retval 0		success
263133588Simp * @retval non-zero	an error occurred while attempting to prepare the
264133588Simp *                      device for suspension
265131988Sdfr *
266131988Sdfr * @see DEVICE_RESUME()
267131988Sdfr */
26841153SwollmanMETHOD int suspend {
26941153Swollman	device_t dev;
27046913Sdfr} DEFAULT null_suspend;
27141153Swollman
272131988Sdfr/**
273131988Sdfr * @brief This is called when the system resumes after a suspend.
274131988Sdfr *
275131988Sdfr * To include this method in a device driver, use a line like this
276131988Sdfr * in the driver's method list:
277131988Sdfr *
278131988Sdfr * @code
279131988Sdfr * 	KOBJMETHOD(device_resume, foo_resume)
280131988Sdfr * @endcode
281131988Sdfr *
282131988Sdfr * @param dev		the device being resumed
283131988Sdfr *
284131988Sdfr * @retval 0		success
285133588Simp * @retval non-zero	an error occurred while attempting to restore the
286133588Simp *                      device from suspension
287131988Sdfr *
288131988Sdfr * @see DEVICE_SUSPEND()
289131988Sdfr */
29041153SwollmanMETHOD int resume {
29141153Swollman	device_t dev;
29246913Sdfr} DEFAULT null_resume;
293139507Simp
294139507Simp/**
295139507Simp * @brief This is called when the driver is asked to quiesce itself.
296139507Simp *
297139507Simp * The driver should arrange for the orderly shutdown of this device.
298139507Simp * All further access to the device should be curtailed.  Soon there
299139507Simp * will be a request to detach, but there won't necessarily be one.
300139507Simp *
301139507Simp * To include this method in a device driver, use a line like this
302139507Simp * in the driver's method list:
303139507Simp *
304139507Simp * @code
305139507Simp * 	KOBJMETHOD(device_quiesce, foo_quiesce)
306139507Simp * @endcode
307139507Simp *
308139507Simp * @param dev		the device being quiesced
309139507Simp *
310139507Simp * @retval 0		success
311139507Simp * @retval non-zero	an error occurred while attempting to quiesce the
312139507Simp *                      device
313139507Simp *
314139507Simp * @see DEVICE_DETACH()
315139507Simp */
316139507SimpMETHOD int quiesce {
317139507Simp	device_t dev;
318139507Simp} DEFAULT null_quiesce;
319