xref: /freebsd/sys/kern/device_if.m (revision 67f8f14a6e956522a9128a468dbfa4c2f4082f04)
1b1bf6610SDoug Rabson#
267f8f14aSDoug Rabson# Copyright (c) 1998,2004 Doug Rabson
3b1bf6610SDoug Rabson# All rights reserved.
4b1bf6610SDoug Rabson#
5b1bf6610SDoug Rabson# Redistribution and use in source and binary forms, with or without
6b1bf6610SDoug Rabson# modification, are permitted provided that the following conditions
7b1bf6610SDoug Rabson# are met:
8b1bf6610SDoug Rabson# 1. Redistributions of source code must retain the above copyright
9b1bf6610SDoug Rabson#    notice, this list of conditions and the following disclaimer.
10b1bf6610SDoug Rabson# 2. Redistributions in binary form must reproduce the above copyright
11b1bf6610SDoug Rabson#    notice, this list of conditions and the following disclaimer in the
12b1bf6610SDoug Rabson#    documentation and/or other materials provided with the distribution.
13b1bf6610SDoug Rabson#
14b1bf6610SDoug Rabson# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15b1bf6610SDoug Rabson# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16b1bf6610SDoug Rabson# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17b1bf6610SDoug Rabson# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18b1bf6610SDoug Rabson# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19b1bf6610SDoug Rabson# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20b1bf6610SDoug Rabson# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21b1bf6610SDoug Rabson# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22b1bf6610SDoug Rabson# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23b1bf6610SDoug Rabson# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24b1bf6610SDoug Rabson# SUCH DAMAGE.
25b1bf6610SDoug Rabson#
26c3aac50fSPeter Wemm# $FreeBSD$
27b1bf6610SDoug Rabson#
28b1bf6610SDoug Rabson
29f7b77691SDoug Rabson#include <sys/bus.h>
30f7b77691SDoug Rabson
3167f8f14aSDoug Rabson/**
3267f8f14aSDoug Rabson * @defgroup DEVICE device - KObj methods for all device drivers
3367f8f14aSDoug Rabson * @brief A basic set of methods required for all device drivers.
3467f8f14aSDoug Rabson *
3567f8f14aSDoug Rabson * The device interface is used to match devices to drivers during
3667f8f14aSDoug Rabson * autoconfiguration and provides methods to allow drivers to handle
3767f8f14aSDoug Rabson * system-wide events such as suspend, resume or shutdown.
3867f8f14aSDoug Rabson * @{
3967f8f14aSDoug Rabson */
407a8ecb9eSNicolas SouchuINTERFACE device;
41b1bf6610SDoug Rabson
42b1bf6610SDoug Rabson#
438b2970bbSDoug Rabson# Default implementations of some methods.
448b2970bbSDoug Rabson#
458b2970bbSDoug RabsonCODE {
468b2970bbSDoug Rabson	static int null_shutdown(device_t dev)
478b2970bbSDoug Rabson	{
488b2970bbSDoug Rabson	    return 0;
498b2970bbSDoug Rabson	}
508b2970bbSDoug Rabson
518b2970bbSDoug Rabson	static int null_suspend(device_t dev)
528b2970bbSDoug Rabson	{
538b2970bbSDoug Rabson	    return 0;
548b2970bbSDoug Rabson	}
558b2970bbSDoug Rabson
568b2970bbSDoug Rabson	static int null_resume(device_t dev)
578b2970bbSDoug Rabson	{
588b2970bbSDoug Rabson	    return 0;
598b2970bbSDoug Rabson	}
608b2970bbSDoug Rabson};
618b2970bbSDoug Rabson
6267f8f14aSDoug Rabson/**
6367f8f14aSDoug Rabson * @brief Probe to see if a device matches a driver.
6467f8f14aSDoug Rabson *
6567f8f14aSDoug Rabson * Users should not call this method directly. Normally, this
6667f8f14aSDoug Rabson * is called via device_probe_and_attach() to select a driver
6767f8f14aSDoug Rabson * calling the DEVICE_PROBE() of all candidate drivers and attach
6867f8f14aSDoug Rabson * the winning driver (if any) to the device.
6967f8f14aSDoug Rabson *
7067f8f14aSDoug Rabson * This function is used to match devices to device drivers.
7167f8f14aSDoug Rabson * Typically, the driver will examine the device to see if
7267f8f14aSDoug Rabson * it is suitable for this driver. This might include checking
7367f8f14aSDoug Rabson * the values of various device instance variables or reading
7467f8f14aSDoug Rabson * hardware registers.
7567f8f14aSDoug Rabson *
7667f8f14aSDoug Rabson * In some cases, there may be more than one driver available
7767f8f14aSDoug Rabson * which can be used for a device (for instance there might
7867f8f14aSDoug Rabson * be a generic driver which works for a set of many types of
7967f8f14aSDoug Rabson * device and a more specific driver which works for a subset
8067f8f14aSDoug Rabson * of devices). Because of this, a driver should not assume
8167f8f14aSDoug Rabson * that it will be the driver that attaches to the device even
8267f8f14aSDoug Rabson * if it returns a success status from DEVICE_PROBE(). In particular,
8367f8f14aSDoug Rabson * a driver must free any resources which it allocated during
8467f8f14aSDoug Rabson * the probe before returning. The return value of DEVICE_PROBE()
8567f8f14aSDoug Rabson * is used to elect which driver is used - the driver which returns
8667f8f14aSDoug Rabson * the largest non-error value wins the election and attaches to
8767f8f14aSDoug Rabson * the device.
8867f8f14aSDoug Rabson *
8967f8f14aSDoug Rabson * If a driver matches the hardware, it should set the device
9067f8f14aSDoug Rabson * description string using device_set_desc() or
9167f8f14aSDoug Rabson * device_set_desc_copy(). This string is
9267f8f14aSDoug Rabson * used to generate an informative message when DEVICE_ATTACH()
9367f8f14aSDoug Rabson * is called.
9467f8f14aSDoug Rabson *
9567f8f14aSDoug Rabson * As a special case, if a driver returns zero, the driver election
9667f8f14aSDoug Rabson * is cut short and that driver will attach to the device
9767f8f14aSDoug Rabson * immediately.
9867f8f14aSDoug Rabson *
9967f8f14aSDoug Rabson * For example, a probe method for a pci device driver might look
10067f8f14aSDoug Rabson * like this:
10167f8f14aSDoug Rabson *
10267f8f14aSDoug Rabson * @code
10367f8f14aSDoug Rabson * int foo_probe(device_t dev)
10467f8f14aSDoug Rabson * {
10567f8f14aSDoug Rabson *         if (pci_get_vendor(dev) == FOOVENDOR &&
10667f8f14aSDoug Rabson *             pci_get_device(dev) == FOODEVICE) {
10767f8f14aSDoug Rabson *                 device_set_desc(dev, "Foo device");
10867f8f14aSDoug Rabson *                 return (0);
10967f8f14aSDoug Rabson *         }
11067f8f14aSDoug Rabson *         return (ENXIO);
11167f8f14aSDoug Rabson * }
11267f8f14aSDoug Rabson * @endcode
11367f8f14aSDoug Rabson *
11467f8f14aSDoug Rabson * To include this method in a device driver, use a line like this
11567f8f14aSDoug Rabson * in the driver's method list:
11667f8f14aSDoug Rabson *
11767f8f14aSDoug Rabson * @code
11867f8f14aSDoug Rabson * 	KOBJMETHOD(device_probe, foo_probe)
11967f8f14aSDoug Rabson * @endcode
12067f8f14aSDoug Rabson *
12167f8f14aSDoug Rabson * @param dev		the device to probe
12267f8f14aSDoug Rabson *
12367f8f14aSDoug Rabson * @retval 0		if the driver strongly matches this device
12467f8f14aSDoug Rabson * @retval negative	if the driver can match this device - the
12567f8f14aSDoug Rabson *			least negative value is used to select the
12667f8f14aSDoug Rabson *			driver
12767f8f14aSDoug Rabson * @retval ENXIO	if the driver does not match the device
12867f8f14aSDoug Rabson * @retval positive	if some kind of error was detected during
12967f8f14aSDoug Rabson *			the probe, a regular unix error code should
13067f8f14aSDoug Rabson *			be returned to indicate the type of error
13167f8f14aSDoug Rabson * @see DEVICE_ATTACH(), pci_get_vendor(), pci_get_device()
13267f8f14aSDoug Rabson */
133b1bf6610SDoug RabsonMETHOD int probe {
134b1bf6610SDoug Rabson	device_t dev;
135b1bf6610SDoug Rabson};
136b1bf6610SDoug Rabson
13767f8f14aSDoug Rabson/**
13867f8f14aSDoug Rabson * @brief Called by a parent device to allow drivers to add new devices to the parent.
13967f8f14aSDoug Rabson *
14067f8f14aSDoug Rabson * The DEVICE_IDENTIFY() method is used by some drivers (e.g. the ISA bus driver)
14167f8f14aSDoug Rabson * to help populate the bus device with a useful set of child devices, normally by
14267f8f14aSDoug Rabson * calling the BUS_ADD_CHILD() method of the parent device. For instance,
14367f8f14aSDoug Rabson * the ISA bus driver uses several special drivers, including the isahint driver and
14467f8f14aSDoug Rabson * the pnp driver to create child devices based on configuration hints and PnP bus
14567f8f14aSDoug Rabson * probes respectively.
14667f8f14aSDoug Rabson *
14767f8f14aSDoug Rabson * Many bus drivers which support true plug-and-play do not need to use this method
14867f8f14aSDoug Rabson * at all since child devices can be discovered automatically without help from
14967f8f14aSDoug Rabson * child drivers.
15067f8f14aSDoug Rabson *
15167f8f14aSDoug Rabson * To include this method in a device driver, use a line like this
15267f8f14aSDoug Rabson * in the driver's method list:
15367f8f14aSDoug Rabson *
15467f8f14aSDoug Rabson * @code
15567f8f14aSDoug Rabson * 	KOBJMETHOD(device_identify, foo_identify)
15667f8f14aSDoug Rabson * @endcode
15767f8f14aSDoug Rabson *
15867f8f14aSDoug Rabson * @param driver	the driver whose identify method is being called
15967f8f14aSDoug Rabson * @param parent	the parent device to use when adding new children
16067f8f14aSDoug Rabson */
1616c2e3ddeSDoug RabsonSTATICMETHOD void identify {
1626c2e3ddeSDoug Rabson	driver_t *driver;
1636c2e3ddeSDoug Rabson	device_t parent;
1646c2e3ddeSDoug Rabson};
1656c2e3ddeSDoug Rabson
16667f8f14aSDoug Rabson/**
16767f8f14aSDoug Rabson * @brief Attach a device to a device driver
16867f8f14aSDoug Rabson *
16967f8f14aSDoug Rabson * Normally only called via device_probe_and_attach(), this is called
17067f8f14aSDoug Rabson * when a driver has succeeded in probing against a device.
17167f8f14aSDoug Rabson * This method should initialise the hardware and allocate other
17267f8f14aSDoug Rabson * system resources (e.g. devfs entries) as required.
17367f8f14aSDoug Rabson *
17467f8f14aSDoug Rabson * To include this method in a device driver, use a line like this
17567f8f14aSDoug Rabson * in the driver's method list:
17667f8f14aSDoug Rabson *
17767f8f14aSDoug Rabson * @code
17867f8f14aSDoug Rabson * 	KOBJMETHOD(device_attach, foo_attach)
17967f8f14aSDoug Rabson * @endcode
18067f8f14aSDoug Rabson *
18167f8f14aSDoug Rabson * @param dev		the device to probe
18267f8f14aSDoug Rabson *
18367f8f14aSDoug Rabson * @retval 0		success
18467f8f14aSDoug Rabson * @retval non-zero	if some kind of error was detected during
18567f8f14aSDoug Rabson *			the attach, a regular unix error code should
18667f8f14aSDoug Rabson *			be returned to indicate the type of error
18767f8f14aSDoug Rabson * @see DEVICE_PROBE()
18867f8f14aSDoug Rabson */
189b1bf6610SDoug RabsonMETHOD int attach {
190b1bf6610SDoug Rabson	device_t dev;
191b1bf6610SDoug Rabson};
192b1bf6610SDoug Rabson
19367f8f14aSDoug Rabson/**
19467f8f14aSDoug Rabson * @brief Detach a driver from a device.
19567f8f14aSDoug Rabson *
19667f8f14aSDoug Rabson * This can be called if the user is replacing the
19767f8f14aSDoug Rabson * driver software or if a device is about to be physically removed
19867f8f14aSDoug Rabson * from the system (e.g. for removable hardware such as USB or PCCARD).
19967f8f14aSDoug Rabson *
20067f8f14aSDoug Rabson * To include this method in a device driver, use a line like this
20167f8f14aSDoug Rabson * in the driver's method list:
20267f8f14aSDoug Rabson *
20367f8f14aSDoug Rabson * @code
20467f8f14aSDoug Rabson * 	KOBJMETHOD(device_detach, foo_detach)
20567f8f14aSDoug Rabson * @endcode
20667f8f14aSDoug Rabson *
20767f8f14aSDoug Rabson * @param dev		the device to detach
20867f8f14aSDoug Rabson *
20967f8f14aSDoug Rabson * @retval 0		success
21067f8f14aSDoug Rabson * @retval non-zero	the detach could not be performed, e.g. if the
21167f8f14aSDoug Rabson *			driver does not support detaching.
21267f8f14aSDoug Rabson *
21367f8f14aSDoug Rabson * @see DEVICE_ATTACH()
21467f8f14aSDoug Rabson */
215b1bf6610SDoug RabsonMETHOD int detach {
216b1bf6610SDoug Rabson	device_t dev;
217b1bf6610SDoug Rabson};
218b1bf6610SDoug Rabson
21967f8f14aSDoug Rabson/**
22067f8f14aSDoug Rabson * @brief Called during system shutdown.
22167f8f14aSDoug Rabson *
22267f8f14aSDoug Rabson * This method allows drivers to detect when the system is being shut down.
22367f8f14aSDoug Rabson * Some drivers need to use this to place their hardware in a consistent
22467f8f14aSDoug Rabson * state before rebooting the computer.
22567f8f14aSDoug Rabson *
22667f8f14aSDoug Rabson * To include this method in a device driver, use a line like this
22767f8f14aSDoug Rabson * in the driver's method list:
22867f8f14aSDoug Rabson *
22967f8f14aSDoug Rabson * @code
23067f8f14aSDoug Rabson * 	KOBJMETHOD(device_shutdown, foo_shutdown)
23167f8f14aSDoug Rabson * @endcode
23267f8f14aSDoug Rabson */
233b1bf6610SDoug RabsonMETHOD int shutdown {
234b1bf6610SDoug Rabson	device_t dev;
2358b2970bbSDoug Rabson} DEFAULT null_shutdown;
23614177d72SGarrett Wollman
23767f8f14aSDoug Rabson/**
23867f8f14aSDoug Rabson * @brief This is called by the power-management subsystem when a suspend has been
23967f8f14aSDoug Rabson * requested by the user or by some automatic mechanism.
24067f8f14aSDoug Rabson *
24167f8f14aSDoug Rabson * This gives
24267f8f14aSDoug Rabson * drivers a chance to veto the suspend or save their configuration before
24367f8f14aSDoug Rabson * power is removed.
24467f8f14aSDoug Rabson *
24567f8f14aSDoug Rabson * To include this method in a device driver, use a line like this
24667f8f14aSDoug Rabson * in the driver's method list:
24767f8f14aSDoug Rabson *
24867f8f14aSDoug Rabson * @code
24967f8f14aSDoug Rabson * 	KOBJMETHOD(device_suspend, foo_suspend)
25067f8f14aSDoug Rabson * @endcode
25167f8f14aSDoug Rabson *
25267f8f14aSDoug Rabson * @param dev		the device being suspended
25367f8f14aSDoug Rabson *
25467f8f14aSDoug Rabson * @retval 0		success
25567f8f14aSDoug Rabson * @retval non-zero	an error occurred while attempting to prepare the device
25667f8f14aSDoug Rabson * 			for suspension
25767f8f14aSDoug Rabson *
25867f8f14aSDoug Rabson * @see DEVICE_RESUME()
25967f8f14aSDoug Rabson */
26014177d72SGarrett WollmanMETHOD int suspend {
26114177d72SGarrett Wollman	device_t dev;
2628b2970bbSDoug Rabson} DEFAULT null_suspend;
26314177d72SGarrett Wollman
26467f8f14aSDoug Rabson/**
26567f8f14aSDoug Rabson * @brief This is called when the system resumes after a suspend.
26667f8f14aSDoug Rabson *
26767f8f14aSDoug Rabson * To include this method in a device driver, use a line like this
26867f8f14aSDoug Rabson * in the driver's method list:
26967f8f14aSDoug Rabson *
27067f8f14aSDoug Rabson * @code
27167f8f14aSDoug Rabson * 	KOBJMETHOD(device_resume, foo_resume)
27267f8f14aSDoug Rabson * @endcode
27367f8f14aSDoug Rabson *
27467f8f14aSDoug Rabson * @param dev		the device being resumed
27567f8f14aSDoug Rabson *
27667f8f14aSDoug Rabson * @retval 0		success
27767f8f14aSDoug Rabson * @retval non-zero	an error occurred while attempting to restore the device
27867f8f14aSDoug Rabson * 			from suspension
27967f8f14aSDoug Rabson *
28067f8f14aSDoug Rabson * @see DEVICE_SUSPEND()
28167f8f14aSDoug Rabson */
28214177d72SGarrett WollmanMETHOD int resume {
28314177d72SGarrett Wollman	device_t dev;
2848b2970bbSDoug Rabson} DEFAULT null_resume;
285