device_if.m revision 133588
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 133588 2004-08-12 17:26:22Z 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 } 6046913Sdfr}; 61131988Sdfr 62131988Sdfr/** 63131988Sdfr * @brief Probe to see if a device matches a driver. 64131988Sdfr * 65131988Sdfr * 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 */ 13336973SdfrMETHOD int probe { 13436973Sdfr device_t dev; 13536973Sdfr}; 13636973Sdfr 137131988Sdfr/** 138133588Simp * @brief Allow a device driver to detect devices not otherwise enumerated. 139131988Sdfr * 140133588Simp * The DEVICE_IDENTIFY() method is used by some drivers (e.g. the ISA 141133588Simp * bus driver) to help populate the bus device with a useful set of 142133588Simp * child devices, normally by calling the BUS_ADD_CHILD() method of 143133588Simp * the parent device. For instance, the ISA bus driver uses several 144133588Simp * special drivers, including the isahint driver and the pnp driver to 145133588Simp * create child devices based on configuration hints and PnP bus 146131988Sdfr * probes respectively. 147131988Sdfr * 148133588Simp * Many bus drivers which support true plug-and-play do not need to 149133588Simp * use this method at all since child devices can be discovered 150133588Simp * automatically without help from child drivers. 151131988Sdfr * 152131988Sdfr * To include this method in a device driver, use a line like this 153131988Sdfr * in the driver's method list: 154131988Sdfr * 155131988Sdfr * @code 156131988Sdfr * KOBJMETHOD(device_identify, foo_identify) 157131988Sdfr * @endcode 158131988Sdfr * 159131988Sdfr * @param driver the driver whose identify method is being called 160131988Sdfr * @param parent the parent device to use when adding new children 161131988Sdfr */ 16247178SdfrSTATICMETHOD void identify { 16347178Sdfr driver_t *driver; 16447178Sdfr device_t parent; 16547178Sdfr}; 16647178Sdfr 167131988Sdfr/** 168131988Sdfr * @brief Attach a device to a device driver 169131988Sdfr * 170131988Sdfr * Normally only called via device_probe_and_attach(), this is called 171131988Sdfr * when a driver has succeeded in probing against a device. 172131988Sdfr * This method should initialise the hardware and allocate other 173131988Sdfr * system resources (e.g. devfs entries) as required. 174131988Sdfr * 175131988Sdfr * To include this method in a device driver, use a line like this 176131988Sdfr * in the driver's method list: 177131988Sdfr * 178131988Sdfr * @code 179131988Sdfr * KOBJMETHOD(device_attach, foo_attach) 180131988Sdfr * @endcode 181131988Sdfr * 182131988Sdfr * @param dev the device to probe 183131988Sdfr * 184131988Sdfr * @retval 0 success 185131988Sdfr * @retval non-zero if some kind of error was detected during 186131988Sdfr * the attach, a regular unix error code should 187131988Sdfr * be returned to indicate the type of error 188131988Sdfr * @see DEVICE_PROBE() 189131988Sdfr */ 19036973SdfrMETHOD int attach { 19136973Sdfr device_t dev; 19236973Sdfr}; 19336973Sdfr 194131988Sdfr/** 195131988Sdfr * @brief Detach a driver from a device. 196131988Sdfr * 197131988Sdfr * This can be called if the user is replacing the 198131988Sdfr * driver software or if a device is about to be physically removed 199131988Sdfr * from the system (e.g. for removable hardware such as USB or PCCARD). 200131988Sdfr * 201131988Sdfr * To include this method in a device driver, use a line like this 202131988Sdfr * in the driver's method list: 203131988Sdfr * 204131988Sdfr * @code 205131988Sdfr * KOBJMETHOD(device_detach, foo_detach) 206131988Sdfr * @endcode 207131988Sdfr * 208131988Sdfr * @param dev the device to detach 209131988Sdfr * 210131988Sdfr * @retval 0 success 211131988Sdfr * @retval non-zero the detach could not be performed, e.g. if the 212131988Sdfr * driver does not support detaching. 213131988Sdfr * 214131988Sdfr * @see DEVICE_ATTACH() 215131988Sdfr */ 21636973SdfrMETHOD int detach { 21736973Sdfr device_t dev; 21836973Sdfr}; 21936973Sdfr 220131988Sdfr/** 221131988Sdfr * @brief Called during system shutdown. 222131988Sdfr * 223131988Sdfr * This method allows drivers to detect when the system is being shut down. 224131988Sdfr * Some drivers need to use this to place their hardware in a consistent 225131988Sdfr * state before rebooting the computer. 226131988Sdfr * 227131988Sdfr * To include this method in a device driver, use a line like this 228131988Sdfr * in the driver's method list: 229131988Sdfr * 230131988Sdfr * @code 231131988Sdfr * KOBJMETHOD(device_shutdown, foo_shutdown) 232131988Sdfr * @endcode 233131988Sdfr */ 23436973SdfrMETHOD int shutdown { 23536973Sdfr device_t dev; 23646913Sdfr} DEFAULT null_shutdown; 23741153Swollman 238131988Sdfr/** 239133588Simp * @brief This is called by the power-management subsystem when a 240133588Simp * suspend has been requested by the user or by some automatic 241133588Simp * mechanism. 242131988Sdfr * 243133588Simp * This gives drivers a chance to veto the suspend or save their 244133588Simp * configuration before power is removed. 245131988Sdfr * 246133588Simp * To include this method in a device driver, use a line like this in 247133588Simp * the driver's method list: 248131988Sdfr * 249131988Sdfr * @code 250131988Sdfr * KOBJMETHOD(device_suspend, foo_suspend) 251131988Sdfr * @endcode 252131988Sdfr * 253131988Sdfr * @param dev the device being suspended 254131988Sdfr * 255131988Sdfr * @retval 0 success 256133588Simp * @retval non-zero an error occurred while attempting to prepare the 257133588Simp * device for suspension 258131988Sdfr * 259131988Sdfr * @see DEVICE_RESUME() 260131988Sdfr */ 26141153SwollmanMETHOD int suspend { 26241153Swollman device_t dev; 26346913Sdfr} DEFAULT null_suspend; 26441153Swollman 265131988Sdfr/** 266131988Sdfr * @brief This is called when the system resumes after a suspend. 267131988Sdfr * 268131988Sdfr * To include this method in a device driver, use a line like this 269131988Sdfr * in the driver's method list: 270131988Sdfr * 271131988Sdfr * @code 272131988Sdfr * KOBJMETHOD(device_resume, foo_resume) 273131988Sdfr * @endcode 274131988Sdfr * 275131988Sdfr * @param dev the device being resumed 276131988Sdfr * 277131988Sdfr * @retval 0 success 278133588Simp * @retval non-zero an error occurred while attempting to restore the 279133588Simp * device from suspension 280131988Sdfr * 281131988Sdfr * @see DEVICE_SUSPEND() 282131988Sdfr */ 28341153SwollmanMETHOD int resume { 28441153Swollman device_t dev; 28546913Sdfr} DEFAULT null_resume; 286