iPXE
device.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <string.h>
28#include <ipxe/list.h>
29#include <ipxe/tables.h>
30#include <ipxe/init.h>
31#include <ipxe/interface.h>
32#include <ipxe/device.h>
33
34/**
35 * @file
36 *
37 * Device model
38 *
39 */
40
41/** Registered root devices */
42static LIST_HEAD ( devices );
43
44/** Device removal inhibition counter */
46
47/**
48 * Probe a root device
49 *
50 * @v rootdev Root device
51 * @ret rc Return status code
52 */
53static int rootdev_probe ( struct root_device *rootdev ) {
54 int rc;
55
56 DBG ( "Adding %s root bus\n", rootdev->dev.name );
57 if ( ( rc = rootdev->driver->probe ( rootdev ) ) != 0 ) {
58 DBG ( "Failed to add %s root bus: %s\n",
59 rootdev->dev.name, strerror ( rc ) );
60 return rc;
61 }
62
63 return 0;
64}
65
66/**
67 * Remove a root device
68 *
69 * @v rootdev Root device
70 */
71static void rootdev_remove ( struct root_device *rootdev ) {
72 rootdev->driver->remove ( rootdev );
73 DBG ( "Removed %s root bus\n", rootdev->dev.name );
74}
75
76/**
77 * Probe all devices
78 *
79 * This initiates probing for all devices in the system. After this
80 * call, the device hierarchy will be populated, and all hardware
81 * should be ready to use.
82 */
83static void probe_devices ( void ) {
84 struct root_device *rootdev;
85 int rc;
86
88 list_add ( &rootdev->dev.siblings, &devices );
89 INIT_LIST_HEAD ( &rootdev->dev.children );
90 if ( ( rc = rootdev_probe ( rootdev ) ) != 0 )
91 list_del ( &rootdev->dev.siblings );
92 }
93}
94
95/**
96 * Remove all devices
97 *
98 */
99static void remove_devices ( int booting __unused ) {
100 struct root_device *rootdev;
101 struct root_device *tmp;
102
103 if ( device_keep_count != 0 ) {
104 DBG ( "Refusing to remove devices on shutdown\n" );
105 return;
106 }
107
108 list_for_each_entry_safe ( rootdev, tmp, &devices, dev.siblings ) {
109 rootdev_remove ( rootdev );
110 list_del ( &rootdev->dev.siblings );
111 }
112}
113
114struct startup_fn startup_devices __startup_fn ( STARTUP_NORMAL ) = {
115 .name = "devices",
116 .startup = probe_devices,
117 .shutdown = remove_devices,
118};
119
120/**
121 * Identify a device behind an interface
122 *
123 * @v intf Interface
124 * @ret device Device, or NULL
125 */
126struct device * identify_device ( struct interface *intf ) {
127 struct interface *dest;
128 identify_device_TYPE ( void * ) *op =
130 void *object = intf_object ( dest );
131 void *device;
132
133 if ( op ) {
134 device = op ( object );
135 } else {
136 /* Default is to return NULL */
137 device = NULL;
138 }
139
140 intf_put ( dest );
141 return device;
142}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
static void remove_devices(int booting __unused)
Remove all devices.
Definition device.c:99
static int rootdev_probe(struct root_device *rootdev)
Probe a root device.
Definition device.c:53
struct device * identify_device(struct interface *intf)
Identify a device behind an interface.
Definition device.c:126
static void rootdev_remove(struct root_device *rootdev)
Remove a root device.
Definition device.c:71
static void probe_devices(void)
Probe all devices.
Definition device.c:83
int device_keep_count
Device removal inhibition counter.
Definition device.c:45
Device model.
#define ROOT_DEVICES
Root device table.
Definition device.h:133
#define identify_device_TYPE(object_type)
Definition device.h:178
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define STARTUP_NORMAL
Normal startup.
Definition init.h:65
String functions.
#define __startup_fn(startup_order)
Declare a startup/shutdown function.
Definition init.h:53
void * intf_object(struct interface *intf)
Get pointer to object containing object interface.
Definition interface.c:160
void intf_put(struct interface *intf)
Decrement reference count on an object interface.
Definition interface.c:150
Object interfaces.
#define intf_get_dest_op(intf, type, dest)
Get object interface destination and operation method.
Definition interface.h:270
unsigned long tmp
Definition linux_pci.h:65
Linked lists.
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define LIST_HEAD(list)
Declare a static list head.
Definition list.h:38
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
static uint16_t struct vmbus_xfer_pages_operations * op
Definition netvsc.h:327
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A hardware device.
Definition device.h:77
struct list_head children
Devices attached to this device.
Definition device.h:87
struct list_head siblings
Devices on the same bus.
Definition device.h:85
char name[40]
Name.
Definition device.h:79
An object interface.
Definition interface.h:125
struct interface * intf
Original interface.
Definition interface.h:159
A root device.
Definition device.h:98
struct root_driver * driver
Root device driver.
Definition device.h:105
struct device dev
Device chain.
Definition device.h:103
int(* probe)(struct root_device *rootdev)
Add root device.
Definition device.h:120
void(* remove)(struct root_device *rootdev)
Remove root device.
Definition device.h:129
A startup/shutdown function.
Definition init.h:43
Linker tables.
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386