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$ 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 92222253Sjhb * the device. Common non-error values are described in the 93222253Sjhb * DEVICE_PROBE(9) manual page. 94131988Sdfr * 95131988Sdfr * If a driver matches the hardware, it should set the device 96131988Sdfr * description string using device_set_desc() or 97222253Sjhb * device_set_desc_copy(). This string is used to generate an 98222253Sjhb * informative message when DEVICE_ATTACH() 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 102222253Sjhb * immediately. This should rarely be used. 103131988Sdfr * 104222253Sjhb * For example, a probe method for a PCI device driver might look 105131988Sdfr * like this: 106131988Sdfr * 107131988Sdfr * @code 108222253Sjhb * int 109222253Sjhb * foo_probe(device_t dev) 110131988Sdfr * { 111131988Sdfr * if (pci_get_vendor(dev) == FOOVENDOR && 112131988Sdfr * pci_get_device(dev) == FOODEVICE) { 113131988Sdfr * device_set_desc(dev, "Foo device"); 114222253Sjhb * return (BUS_PROBE_DEFAULT); 115131988Sdfr * } 116131988Sdfr * return (ENXIO); 117131988Sdfr * } 118131988Sdfr * @endcode 119131988Sdfr * 120131988Sdfr * To include this method in a device driver, use a line like this 121131988Sdfr * in the driver's method list: 122131988Sdfr * 123131988Sdfr * @code 124131988Sdfr * KOBJMETHOD(device_probe, foo_probe) 125131988Sdfr * @endcode 126131988Sdfr * 127131988Sdfr * @param dev the device to probe 128131988Sdfr * 129222253Sjhb * @retval 0 if this is the only possible driver for this 130222253Sjhb * device 131131988Sdfr * @retval negative if the driver can match this device - the 132131988Sdfr * least negative value is used to select the 133131988Sdfr * driver 134131988Sdfr * @retval ENXIO if the driver does not match the device 135131988Sdfr * @retval positive if some kind of error was detected during 136131988Sdfr * the probe, a regular unix error code should 137131988Sdfr * be returned to indicate the type of error 138131988Sdfr * @see DEVICE_ATTACH(), pci_get_vendor(), pci_get_device() 139131988Sdfr */ 14036973SdfrMETHOD int probe { 14136973Sdfr device_t dev; 14236973Sdfr}; 14336973Sdfr 144131988Sdfr/** 145133588Simp * @brief Allow a device driver to detect devices not otherwise enumerated. 146131988Sdfr * 147133588Simp * The DEVICE_IDENTIFY() method is used by some drivers (e.g. the ISA 148133588Simp * bus driver) to help populate the bus device with a useful set of 149133588Simp * child devices, normally by calling the BUS_ADD_CHILD() method of 150133588Simp * the parent device. For instance, the ISA bus driver uses several 151133588Simp * special drivers, including the isahint driver and the pnp driver to 152133588Simp * create child devices based on configuration hints and PnP bus 153131988Sdfr * probes respectively. 154131988Sdfr * 155133588Simp * Many bus drivers which support true plug-and-play do not need to 156133588Simp * use this method at all since child devices can be discovered 157133588Simp * automatically without help from child drivers. 158131988Sdfr * 159131988Sdfr * To include this method in a device driver, use a line like this 160131988Sdfr * in the driver's method list: 161131988Sdfr * 162131988Sdfr * @code 163131988Sdfr * KOBJMETHOD(device_identify, foo_identify) 164131988Sdfr * @endcode 165131988Sdfr * 166131988Sdfr * @param driver the driver whose identify method is being called 167131988Sdfr * @param parent the parent device to use when adding new children 168131988Sdfr */ 16947178SdfrSTATICMETHOD void identify { 17047178Sdfr driver_t *driver; 17147178Sdfr device_t parent; 17247178Sdfr}; 17347178Sdfr 174131988Sdfr/** 175131988Sdfr * @brief Attach a device to a device driver 176131988Sdfr * 177131988Sdfr * Normally only called via device_probe_and_attach(), this is called 178131988Sdfr * when a driver has succeeded in probing against a device. 179131988Sdfr * This method should initialise the hardware and allocate other 180131988Sdfr * system resources (e.g. devfs entries) as required. 181131988Sdfr * 182131988Sdfr * To include this method in a device driver, use a line like this 183131988Sdfr * in the driver's method list: 184131988Sdfr * 185131988Sdfr * @code 186131988Sdfr * KOBJMETHOD(device_attach, foo_attach) 187131988Sdfr * @endcode 188131988Sdfr * 189131988Sdfr * @param dev the device to probe 190131988Sdfr * 191131988Sdfr * @retval 0 success 192131988Sdfr * @retval non-zero if some kind of error was detected during 193131988Sdfr * the attach, a regular unix error code should 194131988Sdfr * be returned to indicate the type of error 195131988Sdfr * @see DEVICE_PROBE() 196131988Sdfr */ 19736973SdfrMETHOD int attach { 19836973Sdfr device_t dev; 19936973Sdfr}; 20036973Sdfr 201131988Sdfr/** 202131988Sdfr * @brief Detach a driver from a device. 203131988Sdfr * 204131988Sdfr * This can be called if the user is replacing the 205131988Sdfr * driver software or if a device is about to be physically removed 206131988Sdfr * from the system (e.g. for removable hardware such as USB or PCCARD). 207131988Sdfr * 208131988Sdfr * To include this method in a device driver, use a line like this 209131988Sdfr * in the driver's method list: 210131988Sdfr * 211131988Sdfr * @code 212131988Sdfr * KOBJMETHOD(device_detach, foo_detach) 213131988Sdfr * @endcode 214131988Sdfr * 215131988Sdfr * @param dev the device to detach 216131988Sdfr * 217131988Sdfr * @retval 0 success 218131988Sdfr * @retval non-zero the detach could not be performed, e.g. if the 219131988Sdfr * driver does not support detaching. 220131988Sdfr * 221131988Sdfr * @see DEVICE_ATTACH() 222131988Sdfr */ 22336973SdfrMETHOD int detach { 22436973Sdfr device_t dev; 22536973Sdfr}; 22636973Sdfr 227131988Sdfr/** 228131988Sdfr * @brief Called during system shutdown. 229131988Sdfr * 230131988Sdfr * This method allows drivers to detect when the system is being shut down. 231131988Sdfr * Some drivers need to use this to place their hardware in a consistent 232131988Sdfr * state before rebooting the computer. 233131988Sdfr * 234131988Sdfr * To include this method in a device driver, use a line like this 235131988Sdfr * in the driver's method list: 236131988Sdfr * 237131988Sdfr * @code 238131988Sdfr * KOBJMETHOD(device_shutdown, foo_shutdown) 239131988Sdfr * @endcode 240131988Sdfr */ 24136973SdfrMETHOD int shutdown { 24236973Sdfr device_t dev; 24346913Sdfr} DEFAULT null_shutdown; 24441153Swollman 245131988Sdfr/** 246133588Simp * @brief This is called by the power-management subsystem when a 247133588Simp * suspend has been requested by the user or by some automatic 248133588Simp * mechanism. 249131988Sdfr * 250133588Simp * This gives drivers a chance to veto the suspend or save their 251133588Simp * configuration before power is removed. 252131988Sdfr * 253133588Simp * To include this method in a device driver, use a line like this in 254133588Simp * the driver's method list: 255131988Sdfr * 256131988Sdfr * @code 257131988Sdfr * KOBJMETHOD(device_suspend, foo_suspend) 258131988Sdfr * @endcode 259131988Sdfr * 260131988Sdfr * @param dev the device being suspended 261131988Sdfr * 262131988Sdfr * @retval 0 success 263133588Simp * @retval non-zero an error occurred while attempting to prepare the 264133588Simp * device for suspension 265131988Sdfr * 266131988Sdfr * @see DEVICE_RESUME() 267131988Sdfr */ 26841153SwollmanMETHOD int suspend { 26941153Swollman device_t dev; 27046913Sdfr} DEFAULT null_suspend; 27141153Swollman 272131988Sdfr/** 273131988Sdfr * @brief This is called when the system resumes after a suspend. 274131988Sdfr * 275131988Sdfr * To include this method in a device driver, use a line like this 276131988Sdfr * in the driver's method list: 277131988Sdfr * 278131988Sdfr * @code 279131988Sdfr * KOBJMETHOD(device_resume, foo_resume) 280131988Sdfr * @endcode 281131988Sdfr * 282131988Sdfr * @param dev the device being resumed 283131988Sdfr * 284131988Sdfr * @retval 0 success 285133588Simp * @retval non-zero an error occurred while attempting to restore the 286133588Simp * device from suspension 287131988Sdfr * 288131988Sdfr * @see DEVICE_SUSPEND() 289131988Sdfr */ 29041153SwollmanMETHOD int resume { 29141153Swollman device_t dev; 29246913Sdfr} DEFAULT null_resume; 293139507Simp 294139507Simp/** 295139507Simp * @brief This is called when the driver is asked to quiesce itself. 296139507Simp * 297139507Simp * The driver should arrange for the orderly shutdown of this device. 298139507Simp * All further access to the device should be curtailed. Soon there 299139507Simp * will be a request to detach, but there won't necessarily be one. 300139507Simp * 301139507Simp * To include this method in a device driver, use a line like this 302139507Simp * in the driver's method list: 303139507Simp * 304139507Simp * @code 305139507Simp * KOBJMETHOD(device_quiesce, foo_quiesce) 306139507Simp * @endcode 307139507Simp * 308139507Simp * @param dev the device being quiesced 309139507Simp * 310139507Simp * @retval 0 success 311139507Simp * @retval non-zero an error occurred while attempting to quiesce the 312139507Simp * device 313139507Simp * 314139507Simp * @see DEVICE_DETACH() 315139507Simp */ 316139507SimpMETHOD int quiesce { 317139507Simp device_t dev; 318139507Simp} DEFAULT null_quiesce; 319