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