device_if.m revision 131988
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 131988 2004-07-11 16:17:42Z dfr $ 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 62139507Simp/** 63139507Simp * @brief Probe to see if a device matches a driver. 64139507Simp * 6546913Sdfr * 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 */ 133131988SdfrMETHOD int probe { 134131988Sdfr device_t dev; 135131988Sdfr}; 136131988Sdfr 137131988Sdfr/** 13836973Sdfr * @brief Called by a parent device to allow drivers to add new devices to the parent. 13936973Sdfr * 14036973Sdfr * The DEVICE_IDENTIFY() method is used by some drivers (e.g. the ISA bus driver) 14136973Sdfr * to help populate the bus device with a useful set of child devices, normally by 142131988Sdfr * calling the BUS_ADD_CHILD() method of the parent device. For instance, 143133588Simp * the ISA bus driver uses several special drivers, including the isahint driver and 144131988Sdfr * the pnp driver to create child devices based on configuration hints and PnP bus 145133588Simp * probes respectively. 146133588Simp * 147133588Simp * Many bus drivers which support true plug-and-play do not need to use this method 148133588Simp * at all since child devices can be discovered automatically without help from 149133588Simp * child drivers. 150133588Simp * 151131988Sdfr * To include this method in a device driver, use a line like this 152131988Sdfr * in the driver's method list: 153133588Simp * 154133588Simp * @code 155133588Simp * KOBJMETHOD(device_identify, foo_identify) 156131988Sdfr * @endcode 157131988Sdfr * 158131988Sdfr * @param driver the driver whose identify method is being called 159131988Sdfr * @param parent the parent device to use when adding new children 160131988Sdfr */ 161131988SdfrSTATICMETHOD void identify { 162131988Sdfr driver_t *driver; 163131988Sdfr device_t parent; 164131988Sdfr}; 165131988Sdfr 166131988Sdfr/** 16747178Sdfr * @brief Attach a device to a device driver 16847178Sdfr * 16947178Sdfr * Normally only called via device_probe_and_attach(), this is called 17047178Sdfr * when a driver has succeeded in probing against a device. 17147178Sdfr * This method should initialise the hardware and allocate other 172131988Sdfr * system resources (e.g. devfs entries) as required. 173131988Sdfr * 174131988Sdfr * To include this method in a device driver, use a line like this 175131988Sdfr * in the driver's method list: 176131988Sdfr * 177131988Sdfr * @code 178131988Sdfr * KOBJMETHOD(device_attach, foo_attach) 179131988Sdfr * @endcode 180131988Sdfr * 181131988Sdfr * @param dev the device to probe 182131988Sdfr * 183131988Sdfr * @retval 0 success 184131988Sdfr * @retval non-zero if some kind of error was detected during 185131988Sdfr * the attach, a regular unix error code should 186131988Sdfr * be returned to indicate the type of error 187131988Sdfr * @see DEVICE_PROBE() 188131988Sdfr */ 189131988SdfrMETHOD int attach { 190131988Sdfr device_t dev; 191131988Sdfr}; 192131988Sdfr 193131988Sdfr/** 194131988Sdfr * @brief Detach a driver from a device. 19536973Sdfr * 19636973Sdfr * This can be called if the user is replacing the 19736973Sdfr * driver software or if a device is about to be physically removed 19836973Sdfr * from the system (e.g. for removable hardware such as USB or PCCARD). 199131988Sdfr * 200131988Sdfr * To include this method in a device driver, use a line like this 201131988Sdfr * in the driver's method list: 202131988Sdfr * 203131988Sdfr * @code 204131988Sdfr * KOBJMETHOD(device_detach, foo_detach) 205131988Sdfr * @endcode 206131988Sdfr * 207131988Sdfr * @param dev the device to detach 208131988Sdfr * 209131988Sdfr * @retval 0 success 210131988Sdfr * @retval non-zero the detach could not be performed, e.g. if the 211131988Sdfr * driver does not support detaching. 212131988Sdfr * 213131988Sdfr * @see DEVICE_ATTACH() 214131988Sdfr */ 215131988SdfrMETHOD int detach { 216131988Sdfr device_t dev; 217131988Sdfr}; 218131988Sdfr 219131988Sdfr/** 220131988Sdfr * @brief Called during system shutdown. 22136973Sdfr * 22236973Sdfr * This method allows drivers to detect when the system is being shut down. 22336973Sdfr * Some drivers need to use this to place their hardware in a consistent 22436973Sdfr * state before rebooting the computer. 225131988Sdfr * 226131988Sdfr * To include this method in a device driver, use a line like this 227131988Sdfr * in the driver's method list: 228131988Sdfr * 229131988Sdfr * @code 230131988Sdfr * KOBJMETHOD(device_shutdown, foo_shutdown) 231131988Sdfr * @endcode 232131988Sdfr */ 233131988SdfrMETHOD int shutdown { 234131988Sdfr device_t dev; 235131988Sdfr} DEFAULT null_shutdown; 236131988Sdfr 237131988Sdfr/** 238131988Sdfr * @brief This is called by the power-management subsystem when a suspend has been 23936973Sdfr * requested by the user or by some automatic mechanism. 24036973Sdfr * 24146913Sdfr * This gives 24241153Swollman * drivers a chance to veto the suspend or save their configuration before 243131988Sdfr * power is removed. 244133588Simp * 245133588Simp * To include this method in a device driver, use a line like this 246133588Simp * in the driver's method list: 247131988Sdfr * 248133588Simp * @code 249133588Simp * KOBJMETHOD(device_suspend, foo_suspend) 250131988Sdfr * @endcode 251133588Simp * 252133588Simp * @param dev the device being suspended 253131988Sdfr * 254131988Sdfr * @retval 0 success 255131988Sdfr * @retval non-zero an error occurred while attempting to prepare the device 256131988Sdfr * for suspension 257131988Sdfr * 258131988Sdfr * @see DEVICE_RESUME() 259131988Sdfr */ 260131988SdfrMETHOD int suspend { 261133588Simp device_t dev; 262133588Simp} DEFAULT null_suspend; 263131988Sdfr 264131988Sdfr/** 265131988Sdfr * @brief This is called when the system resumes after a suspend. 26641153Swollman * 26741153Swollman * To include this method in a device driver, use a line like this 26846913Sdfr * in the driver's method list: 26941153Swollman * 270131988Sdfr * @code 271131988Sdfr * KOBJMETHOD(device_resume, foo_resume) 272131988Sdfr * @endcode 273131988Sdfr * 274131988Sdfr * @param dev the device being resumed 275131988Sdfr * 276131988Sdfr * @retval 0 success 277131988Sdfr * @retval non-zero an error occurred while attempting to restore the device 278131988Sdfr * from suspension 279131988Sdfr * 280131988Sdfr * @see DEVICE_SUSPEND() 281131988Sdfr */ 282131988SdfrMETHOD int resume { 283133588Simp device_t dev; 284133588Simp} DEFAULT null_resume; 285131988Sdfr