1 #ifndef _IPXE_SANBOOT_H
2 #define _IPXE_SANBOOT_H
3
4 /** @file
5 *
6 * iPXE sanboot API
7 *
8 * The sanboot API provides methods for hooking, unhooking,
9 * describing, and booting from SAN devices.
10 */
11
12 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
13
14 #include <ipxe/api.h>
15 #include <ipxe/refcnt.h>
16 #include <ipxe/list.h>
17 #include <ipxe/uri.h>
18 #include <ipxe/retry.h>
19 #include <ipxe/process.h>
20 #include <ipxe/blockdev.h>
21 #include <ipxe/acpi.h>
22 #include <config/sanboot.h>
23
24 /** A SAN path */
25 struct san_path {
26 /** Containing SAN device */
27 struct san_device *sandev;
28 /** Path index */
29 unsigned int index;
30 /** SAN device URI */
31 struct uri *uri;
32 /** List of open/closed paths */
33 struct list_head list;
34
35 /** Underlying block device interface */
36 struct interface block;
37 /** Process */
38 struct process process;
39 /** Path status */
40 int path_rc;
41
42 /** ACPI descriptor (if applicable) */
43 struct acpi_descriptor *desc;
44 };
45
46 /** A SAN device */
47 struct san_device {
48 /** Reference count */
49 struct refcnt refcnt;
50 /** List of SAN devices */
51 struct list_head list;
52
53 /** Drive number */
54 unsigned int drive;
55 /** Flags */
56 unsigned int flags;
57
58 /** Command interface */
59 struct interface command;
60 /** Command timeout timer */
61 struct retry_timer timer;
62 /** Command status */
63 int command_rc;
64
65 /** Raw block device capacity */
66 struct block_device_capacity capacity;
67 /** Block size shift
68 *
69 * To allow for emulation of CD-ROM access, this represents
70 * the left-shift required to translate from exposed logical
71 * I/O blocks to underlying blocks.
72 */
73 unsigned int blksize_shift;
74 /** Drive is a CD-ROM */
75 int is_cdrom;
76
77 /** Driver private data */
78 void *priv;
79
80 /** Number of paths */
81 unsigned int paths;
82 /** Current active path */
83 struct san_path *active;
84 /** List of opened SAN paths */
85 struct list_head opened;
86 /** List of closed SAN paths */
87 struct list_head closed;
88 /** SAN paths */
89 struct san_path path[0];
90 };
91
92 /** SAN device flags */
93 enum san_device_flags {
94 /** Device should not be included in description tables */
95 SAN_NO_DESCRIBE = 0x0001,
96 };
97
98 /**
99 * Calculate static inline sanboot API function name
100 *
101 * @v _prefix Subsystem prefix
102 * @v _api_func API function
103 * @ret _subsys_func Subsystem API function
104 */
105 #define SANBOOT_INLINE( _subsys, _api_func ) \
106 SINGLE_API_INLINE ( SANBOOT_PREFIX_ ## _subsys, _api_func )
107
108 /**
109 * Provide a sanboot API implementation
110 *
111 * @v _prefix Subsystem prefix
112 * @v _api_func API function
113 * @v _func Implementing function
114 */
115 #define PROVIDE_SANBOOT( _subsys, _api_func, _func ) \
116 PROVIDE_SINGLE_API ( SANBOOT_PREFIX_ ## _subsys, _api_func, _func )
117
118 /**
119 * Provide a static inline sanboot API implementation
120 *
121 * @v _prefix Subsystem prefix
122 * @v _api_func API function
123 */
124 #define PROVIDE_SANBOOT_INLINE( _subsys, _api_func ) \
125 PROVIDE_SINGLE_API_INLINE ( SANBOOT_PREFIX_ ## _subsys, _api_func )
126
127 /* Include all architecture-independent sanboot API headers */
128 #include <ipxe/null_sanboot.h>
129 #include <ipxe/dummy_sanboot.h>
130 #include <ipxe/efi/efi_block.h>
131
132 /* Include all architecture-dependent sanboot API headers */
133 #include <bits/sanboot.h>
134
135 /**
136 * Hook SAN device
137 *
138 * @v drive Drive number
139 * @v uris List of URIs
140 * @v count Number of URIs
141 * @v flags Flags
142 * @ret drive Drive number, or negative error
143 */
144 int san_hook ( unsigned int drive, struct uri **uris, unsigned int count,
145 unsigned int flags );
146
147 /**
148 * Unhook SAN device
149 *
150 * @v drive Drive number
151 */
152 void san_unhook ( unsigned int drive );
153
154 /**
155 * Attempt to boot from a SAN device
156 *
157 * @v drive Drive number
158 * @v filename Filename (or NULL to use default)
159 * @ret rc Return status code
160 */
161 int san_boot ( unsigned int drive, const char *filename );
162
163 /**
164 * Describe SAN devices for SAN-booted operating system
165 *
166 * @ret rc Return status code
167 */
168 int san_describe ( void );
169
170 extern struct list_head san_devices;
171
172 /** Iterate over all SAN devices */
173 #define for_each_sandev( sandev ) \
174 list_for_each_entry ( (sandev), &san_devices, list )
175
176 /** There exist some SAN devices
177 *
178 * @ret existence Existence of SAN devices
179 */
have_sandevs(void)180 static inline int have_sandevs ( void ) {
181 return ( ! list_empty ( &san_devices ) );
182 }
183
184 /**
185 * Get reference to SAN device
186 *
187 * @v sandev SAN device
188 * @ret sandev SAN device
189 */
190 static inline __attribute__ (( always_inline )) struct san_device *
sandev_get(struct san_device * sandev)191 sandev_get ( struct san_device *sandev ) {
192 ref_get ( &sandev->refcnt );
193 return sandev;
194 }
195
196 /**
197 * Drop reference to SAN device
198 *
199 * @v sandev SAN device
200 */
201 static inline __attribute__ (( always_inline )) void
sandev_put(struct san_device * sandev)202 sandev_put ( struct san_device *sandev ) {
203 ref_put ( &sandev->refcnt );
204 }
205
206 /**
207 * Calculate SAN device block size
208 *
209 * @v sandev SAN device
210 * @ret blksize Sector size
211 */
sandev_blksize(struct san_device * sandev)212 static inline size_t sandev_blksize ( struct san_device *sandev ) {
213 return ( sandev->capacity.blksize << sandev->blksize_shift );
214 }
215
216 /**
217 * Calculate SAN device capacity
218 *
219 * @v sandev SAN device
220 * @ret blocks Number of blocks
221 */
sandev_capacity(struct san_device * sandev)222 static inline uint64_t sandev_capacity ( struct san_device *sandev ) {
223 return ( sandev->capacity.blocks >> sandev->blksize_shift );
224 }
225
226 /**
227 * Check if SAN device needs to be reopened
228 *
229 * @v sandev SAN device
230 * @ret needs_reopen SAN device needs to be reopened
231 */
sandev_needs_reopen(struct san_device * sandev)232 static inline int sandev_needs_reopen ( struct san_device *sandev ) {
233 return ( sandev->active == NULL );
234 }
235
236 extern struct san_device * sandev_find ( unsigned int drive );
237 extern int sandev_reopen ( struct san_device *sandev );
238 extern int sandev_reset ( struct san_device *sandev );
239 extern int sandev_read ( struct san_device *sandev, uint64_t lba,
240 unsigned int count, userptr_t buffer );
241 extern int sandev_write ( struct san_device *sandev, uint64_t lba,
242 unsigned int count, userptr_t buffer );
243 extern struct san_device * alloc_sandev ( struct uri **uris, unsigned int count,
244 size_t priv_size );
245 extern int register_sandev ( struct san_device *sandev, unsigned int drive,
246 unsigned int flags );
247 extern void unregister_sandev ( struct san_device *sandev );
248 extern unsigned int san_default_drive ( void );
249
250 #endif /* _IPXE_SANBOOT_H */
251