device_if.m revision 139804
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: head/sys/kern/device_if.m 139804 2005-01-06 23:35:40Z 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 } 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 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 133131988Sdfr * @retval positive if some kind of error was detected during 134131988Sdfr * the probe, a regular unix error code should 135131988Sdfr * be returned to indicate the type of error 136131988Sdfr * @see DEVICE_ATTACH(), pci_get_vendor(), pci_get_device() 137131988Sdfr */ 13836973SdfrMETHOD int probe { 13936973Sdfr device_t dev; 14036973Sdfr}; 14136973Sdfr 142131988Sdfr/** 143133588Simp * @brief Allow a device driver to detect devices not otherwise enumerated. 144131988Sdfr * 145133588Simp * The DEVICE_IDENTIFY() method is used by some drivers (e.g. the ISA 146133588Simp * bus driver) to help populate the bus device with a useful set of 147133588Simp * child devices, normally by calling the BUS_ADD_CHILD() method of 148133588Simp * the parent device. For instance, the ISA bus driver uses several 149133588Simp * special drivers, including the isahint driver and the pnp driver to 150133588Simp * create child devices based on configuration hints and PnP bus 151131988Sdfr * probes respectively. 152131988Sdfr * 153133588Simp * Many bus drivers which support true plug-and-play do not need to 154133588Simp * use this method at all since child devices can be discovered 155133588Simp * 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 161131988Sdfr * KOBJMETHOD(device_identify, foo_identify) 162131988Sdfr * @endcode 163131988Sdfr * 164131988Sdfr * @param driver the driver whose identify method is being called 165131988Sdfr * @param parent the parent device to use when adding new children 166131988Sdfr */ 16747178SdfrSTATICMETHOD void identify { 16847178Sdfr driver_t *driver; 16947178Sdfr device_t parent; 17047178Sdfr}; 17147178Sdfr 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 * 189131988Sdfr * @retval 0 success 190131988Sdfr * @retval non-zero if some kind of error was detected during 191131988Sdfr * the attach, a regular unix error code should 192131988Sdfr * be returned to indicate the type of error 193131988Sdfr * @see DEVICE_PROBE() 194131988Sdfr */ 19536973SdfrMETHOD int attach { 19636973Sdfr device_t dev; 19736973Sdfr}; 19836973Sdfr 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 * 215131988Sdfr * @retval 0 success 216131988Sdfr * @retval non-zero the detach could not be performed, e.g. if the 217131988Sdfr * driver does not support detaching. 218131988Sdfr * 219131988Sdfr * @see DEVICE_ATTACH() 220131988Sdfr */ 22136973SdfrMETHOD int detach { 22236973Sdfr device_t dev; 22336973Sdfr}; 22436973Sdfr 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 233131988Sdfr * in the driver's method list: 234131988Sdfr * 235131988Sdfr * @code 236131988Sdfr * KOBJMETHOD(device_shutdown, foo_shutdown) 237131988Sdfr * @endcode 238131988Sdfr */ 23936973SdfrMETHOD int shutdown { 24036973Sdfr device_t dev; 24146913Sdfr} DEFAULT null_shutdown; 24241153Swollman 243131988Sdfr/** 244133588Simp * @brief This is called by the power-management subsystem when a 245133588Simp * suspend has been requested by the user or by some automatic 246133588Simp * mechanism. 247131988Sdfr * 248133588Simp * This gives drivers a chance to veto the suspend or save their 249133588Simp * configuration before power is removed. 250131988Sdfr * 251133588Simp * To include this method in a device driver, use a line like this in 252133588Simp * 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 * 260131988Sdfr * @retval 0 success 261133588Simp * @retval non-zero an error occurred while attempting to prepare the 262133588Simp * device for suspension 263131988Sdfr * 264131988Sdfr * @see DEVICE_RESUME() 265131988Sdfr */ 26641153SwollmanMETHOD int suspend { 26741153Swollman device_t dev; 26846913Sdfr} DEFAULT null_suspend; 26941153Swollman 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 * 282131988Sdfr * @retval 0 success 283133588Simp * @retval non-zero an error occurred while attempting to restore the 284133588Simp * device from suspension 285131988Sdfr * 286131988Sdfr * @see DEVICE_SUSPEND() 287131988Sdfr */ 28841153SwollmanMETHOD int resume { 28941153Swollman device_t dev; 29046913Sdfr} DEFAULT null_resume; 291139507Simp 292139507Simp/** 293139507Simp * @brief This is called when the driver is asked to quiesce itself. 294139507Simp * 295139507Simp * The driver should arrange for the orderly shutdown of this device. 296139507Simp * All further access to the device should be curtailed. Soon there 297139507Simp * will be a request to detach, but there won't necessarily be one. 298139507Simp * 299139507Simp * To include this method in a device driver, use a line like this 300139507Simp * in the driver's method list: 301139507Simp * 302139507Simp * @code 303139507Simp * KOBJMETHOD(device_quiesce, foo_quiesce) 304139507Simp * @endcode 305139507Simp * 306139507Simp * @param dev the device being quiesced 307139507Simp * 308139507Simp * @retval 0 success 309139507Simp * @retval non-zero an error occurred while attempting to quiesce the 310139507Simp * device 311139507Simp * 312139507Simp * @see DEVICE_DETACH() 313139507Simp */ 314139507SimpMETHOD int quiesce { 315139507Simp device_t dev; 316139507Simp} DEFAULT null_quiesce; 317