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