1 /*
2  * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
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 St, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef _IPXE_LINUX_H
20 #define _IPXE_LINUX_H
21 
22 FILE_LICENCE(GPL2_OR_LATER);
23 
24 /** @file
25  *
26  * Linux devices, drivers and device requests.
27  */
28 
29 #include <ipxe/list.h>
30 #include <ipxe/device.h>
31 #include <ipxe/settings.h>
32 
33 /**
34  * Convert a Linux error number to an iPXE status code
35  *
36  * @v errno		Linux error number
37  * @ret rc		iPXE status code (before negation)
38  */
39 #define ELINUX( errno ) EPLATFORM ( EINFO_EPLATFORM, errno )
40 
41 /** A linux device */
42 struct linux_device {
43 	/** Generic device */
44 	struct device dev;
45 	/** Driver that's handling the device */
46 	struct linux_driver *driver;
47 	/** Private data used by drivers */
48 	void *priv;
49 };
50 
51 struct linux_device_request;
52 
53 /** A linux driver */
54 struct linux_driver {
55 	/** Name */
56 	char *name;
57 	/** Probe function */
58 	int (*probe)(struct linux_device *device, struct linux_device_request *request);
59 	/** Remove function */
60 	void (*remove)(struct linux_device *device);
61 	/** Can the driver probe any more devices? */
62 	int can_probe;
63 };
64 
65 /** Linux driver table */
66 #define LINUX_DRIVERS __table(struct linux_driver, "linux_drivers")
67 
68 /** Declare a Linux driver */
69 #define __linux_driver __table_entry(LINUX_DRIVERS, 01)
70 
71 /**
72  * Set linux device driver-private data
73  *
74  * @v device	Linux device
75  * @v priv		Private data
76  */
linux_set_drvdata(struct linux_device * device,void * priv)77 static inline void linux_set_drvdata(struct linux_device * device, void *priv)
78 {
79 	device->priv = priv;
80 }
81 
82 /**
83  * Get linux device driver-private data
84  *
85  * @v device	Linux device
86  * @ret priv	Private data
87  */
linux_get_drvdata(struct linux_device * device)88 static inline void *linux_get_drvdata(struct linux_device *device)
89 {
90 	return device->priv;
91 }
92 
93 /**
94  * A device request.
95  *
96  * To be created and filled by the UI code.
97  */
98 struct linux_device_request {
99 	/** Driver name. Compared to the linux drivers' names */
100 	char *driver;
101 	/** List node */
102 	struct list_head list;
103 	/** List of settings */
104 	struct list_head settings;
105 };
106 
107 /** A device request setting */
108 struct linux_setting {
109 	/** Name */
110 	char *name;
111 	/** Value */
112 	char *value;
113 	/** Was the setting already applied? */
114 	int applied;
115 	/** List node */
116 	struct list_head list;
117 };
118 
119 /**
120  * List of requested devices.
121  *
122  * Filled by the UI code. Linux root_driver walks over this list looking for an
123  * appropriate driver to handle each request by matching the driver's name.
124  */
125 extern struct list_head linux_device_requests;
126 
127 /**
128  * List of global settings to apply.
129  *
130  * Filled by the UI code. Linux root_driver applies these settings.
131  */
132 extern struct list_head linux_global_settings;
133 
134 /**
135  * Look for the last occurrence of a setting with the specified name
136  *
137  * @v name     Name of the setting to look for
138  * @v settings List of the settings to look through
139  */
140 struct linux_setting *linux_find_setting(char *name, struct list_head *settings);
141 
142 /**
143  * Apply a list of linux settings to a settings block
144  *
145  * @v new_settings     List of linux_setting's to apply
146  * @v settings_block   Settings block to apply the settings to
147  * @ret rc             0 on success
148  */
149 extern void linux_apply_settings(struct list_head *new_settings, struct settings *settings_block);
150 
151 
152 #endif /* _IPXE_LINUX_H */
153