Просмотр исходного кода

Add iBFT code derived from IBM document.

No Microsoft intellectual property was harmed in the production of
this code.
tags/v0.9.3
Michael Brown 17 лет назад
Родитель
Сommit
54bf2621ed
2 измененных файлов: 620 добавлений и 6 удалений
  1. 325
    0
      src/core/ibft.c
  2. 295
    6
      src/include/gpxe/ibft.h

+ 325
- 0
src/core/ibft.c Просмотреть файл

@@ -0,0 +1,325 @@
1
+/*
2
+ * Copyright Fen Systems Ltd. 2007.  Portions of this code are derived
3
+ * from IBM Corporation Sample Programs.  Copyright IBM Corporation
4
+ * 2004, 2007.  All rights reserved.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use, copy,
10
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
11
+ * of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be
15
+ * included in all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *
26
+ */
27
+
28
+#include <stdint.h>
29
+#include <stdio.h>
30
+#include <string.h>
31
+#include <errno.h>
32
+#include <byteswap.h>
33
+#include <realmode.h>
34
+#include <gpxe/pci.h>
35
+#include <gpxe/acpi.h>
36
+#include <gpxe/in.h>
37
+#include <gpxe/netdevice.h>
38
+#include <gpxe/dhcp.h>
39
+#include <gpxe/iscsi.h>
40
+#include <gpxe/ibft.h>
41
+
42
+/** @file
43
+ *
44
+ * iSCSI boot firmware table
45
+ *
46
+ * The information in this file is derived from the document "iSCSI
47
+ * Boot Firmware Table (iBFT)" as published by IBM at
48
+ *
49
+ * ftp://ftp.software.ibm.com/systems/support/system_x_pdf/ibm_iscsi_boot_firmware_table_v1.02.pdf
50
+ *
51
+ */
52
+
53
+#define ibftab __use_data16 ( ibftab )
54
+/** The iBFT used by gPXE */
55
+struct gpxe_ibft __data16 ( ibftab ) = {
56
+	/* Table header */
57
+	.table = {
58
+		/* ACPI header */
59
+		.acpi = {
60
+			.signature = IBFT_SIG,
61
+			.length = sizeof ( ibftab ),
62
+			.revision = 1,
63
+			.oem_id = "FENSYS",
64
+			.oem_table_id = "gPXE",
65
+		},
66
+		/* Control block */
67
+		.control = {
68
+			.header = {
69
+				.structure_id = IBFT_STRUCTURE_ID_CONTROL,
70
+				.version = 1,
71
+				.length = sizeof ( ibftab.table.control ),
72
+				.flags = 0,
73
+			},
74
+			.initiator = offsetof ( typeof ( ibftab ), initiator ),
75
+			.nic_0 = offsetof ( typeof ( ibftab ), nic ),
76
+			.target_0 = offsetof ( typeof ( ibftab ), target ),
77
+		},
78
+	},
79
+	/* iSCSI initiator information */
80
+	.initiator = {
81
+		.header = {
82
+			.structure_id = IBFT_STRUCTURE_ID_INITIATOR,
83
+			.version = 1,
84
+			.length = sizeof ( ibftab.initiator ),
85
+			.flags = ( IBFT_FL_INITIATOR_BLOCK_VALID |
86
+				   IBFT_FL_INITIATOR_FIRMWARE_BOOT_SELECTED ),
87
+		},
88
+	},
89
+	/* NIC information */
90
+	.nic = {
91
+		.header = {
92
+			.structure_id = IBFT_STRUCTURE_ID_NIC,
93
+			.version = 1,
94
+			.length = sizeof ( ibftab.nic ),
95
+			.flags = ( IBFT_FL_NIC_BLOCK_VALID |
96
+				   IBFT_FL_NIC_FIRMWARE_BOOT_SELECTED ),
97
+		},
98
+	},
99
+	/* iSCSI target information */
100
+	.target = {
101
+		.header = {
102
+			.structure_id = IBFT_STRUCTURE_ID_TARGET,
103
+			.version = 1,
104
+			.length = sizeof ( ibftab.target ),
105
+			.flags = ( IBFT_FL_TARGET_BLOCK_VALID |
106
+				   IBFT_FL_TARGET_FIRMWARE_BOOT_SELECTED ),
107
+		},
108
+	},
109
+};
110
+
111
+/**
112
+ * Fill in an IP address field within iBFT
113
+ *
114
+ * @v ipaddr		IP address field
115
+ * @v in		IPv4 address
116
+ */
117
+static void ibft_set_ipaddr ( struct ibft_ipaddr *ipaddr, struct in_addr in ) {
118
+	memset ( ipaddr, 0, sizeof ( ipaddr ) );
119
+	if ( in.s_addr ) {
120
+		ipaddr->in = in;
121
+		ipaddr->ones = 0xffff;
122
+	}
123
+}
124
+
125
+/**
126
+ * Fill in an IP address within iBFT from DHCP option
127
+ *
128
+ * @v ipaddr		IP address field
129
+ * @v tag		DHCP option tag
130
+ */
131
+static void ibft_set_ipaddr_option ( struct ibft_ipaddr *ipaddr,
132
+				     unsigned int tag ) {
133
+	struct in_addr in;
134
+	find_global_dhcp_ipv4_option ( tag, &in );
135
+	ibft_set_ipaddr ( ipaddr, in );
136
+}
137
+
138
+/**
139
+ * Fill in a string field within iBFT
140
+ *
141
+ * @v strings		iBFT string block descriptor
142
+ * @v string		String field
143
+ * @v data		String to fill in
144
+ * @v len		Length of string to fill in
145
+ * @ret rc		Return status code
146
+ */
147
+static int ibft_set_string ( struct ibft_string_block *strings,
148
+			     struct ibft_string *string,
149
+			     const void *data, size_t len ) {
150
+	char *dest;
151
+	char *end;
152
+	unsigned int remaining;
153
+
154
+	dest = ( ( ( char * ) strings->table ) + strings->offset );
155
+	end = ( ( ( char * ) strings->table ) + strings->table->acpi.length );
156
+	remaining = ( end - dest );
157
+
158
+	if ( len >= remaining )
159
+		return -ENOMEM;
160
+
161
+	memcpy ( dest, data, len );
162
+	dest[len] = '\0';
163
+
164
+	string->offset = strings->offset;
165
+	string->length = len;
166
+	strings->offset += ( len + 1 );
167
+	return 0;
168
+}
169
+
170
+/**
171
+ * Fill in a string field within iBFT from DHCP option
172
+ *
173
+ * @v strings		iBFT string block descriptor
174
+ * @v string		String field
175
+ * @v tag		DHCP option tag
176
+ * @ret rc		Return status code
177
+ */
178
+static int ibft_set_string_option ( struct ibft_string_block *strings,
179
+				    struct ibft_string *string,
180
+				    unsigned int tag ) {
181
+	struct dhcp_option *option;
182
+
183
+	option = find_global_dhcp_option ( tag );
184
+	if ( ! option ) {
185
+		string->offset = 0;
186
+		string->length = 0;
187
+		return 0;
188
+	}
189
+
190
+	return ibft_set_string ( strings, string, option->data.string,
191
+				 option->len );
192
+}
193
+
194
+/**
195
+ * Fill in NIC portion of iBFT
196
+ *
197
+ * @v nic		NIC portion of iBFT
198
+ * @v strings		iBFT string block descriptor
199
+ * @v netdev		Network device
200
+ * @ret rc		Return status code
201
+ */
202
+static int ibft_fill_nic ( struct ibft_nic *nic,
203
+			   struct ibft_string_block *strings,
204
+			   struct net_device *netdev ) {
205
+	struct in_addr netmask_addr;
206
+	unsigned int netmask_count = 0;
207
+	int rc;
208
+
209
+	/* Extract values from DHCP configuration */
210
+	ibft_set_ipaddr_option ( &nic->ip_address, DHCP_EB_YIADDR );
211
+	ibft_set_ipaddr_option ( &nic->gateway, DHCP_ROUTERS );
212
+	ibft_set_ipaddr_option ( &nic->dns[0], DHCP_DNS_SERVERS );
213
+	if ( ( rc = ibft_set_string_option ( strings, &nic->hostname,
214
+					     DHCP_HOST_NAME ) ) != 0 )
215
+		return rc;
216
+
217
+	/* Derive subnet mask prefix from subnet mask */
218
+	find_global_dhcp_ipv4_option ( DHCP_SUBNET_MASK, &netmask_addr );
219
+	while ( netmask_addr.s_addr ) {
220
+		if ( netmask_addr.s_addr & 0x1 )
221
+			netmask_count++;
222
+		netmask_addr.s_addr >>= 1;
223
+	}
224
+	nic->subnet_mask_prefix = netmask_count;
225
+
226
+	/* Extract values from net-device configuration */
227
+	memcpy ( nic->mac_address, netdev->ll_addr,
228
+		 sizeof ( nic->mac_address ) );
229
+	nic->pci_bus_dev_func = netdev->dev->desc.location;
230
+
231
+	return 0;
232
+}
233
+
234
+/**
235
+ * Fill in Initiator portion of iBFT
236
+ *
237
+ * @v initiator		Initiator portion of iBFT
238
+ * @v strings		iBFT string block descriptor
239
+ * @ret rc		Return status code
240
+ */
241
+static int ibft_fill_initiator ( struct ibft_initiator *initiator,
242
+				 struct ibft_string_block *strings ) {
243
+	const char *initiator_iqn = iscsi_initiator_iqn();
244
+	int rc;
245
+
246
+	if ( ( rc = ibft_set_string ( strings, &initiator->initiator_name,
247
+				      initiator_iqn,
248
+				      strlen ( initiator_iqn ) ) ) != 0)
249
+		return rc;
250
+
251
+	return 0;
252
+}
253
+
254
+/**
255
+ * Fill in Target portion of iBFT
256
+ *
257
+ * @v target		Target portion of iBFT
258
+ * @v strings		iBFT string block descriptor
259
+ * @v iscsi		iSCSI session
260
+ * @ret rc		Return status code
261
+ */
262
+static int ibft_fill_target ( struct ibft_target *target,
263
+			      struct ibft_string_block *strings,
264
+			      struct iscsi_session *iscsi ) {
265
+	struct sockaddr_in *sin_target =
266
+		( struct sockaddr_in * ) &iscsi->target_sockaddr;
267
+	int rc;
268
+
269
+	/* Fill in Target values */
270
+	ibft_set_ipaddr ( &target->ip_address, sin_target->sin_addr );
271
+	target->socket = ntohs ( sin_target->sin_port );
272
+	if ( ( rc = ibft_set_string ( strings, &target->target_name,
273
+				      iscsi->target_iqn,
274
+				      strlen ( iscsi->target_iqn ) ) ) != 0 )
275
+		return rc;
276
+	if ( iscsi->username ) {
277
+		if ( ( rc = ibft_set_string ( strings, &target->chap_name,
278
+					      iscsi->username,
279
+					      strlen ( iscsi->username ) ))!=0)
280
+			return rc;
281
+	}
282
+	if ( iscsi->password ) {
283
+		if ( ( rc = ibft_set_string ( strings, &target->chap_secret,
284
+					      iscsi->password,
285
+					      strlen ( iscsi->password ) ))!=0)
286
+			return rc;
287
+		target->chap_type = IBFT_CHAP_ONE_WAY;
288
+	}
289
+
290
+	return 0;
291
+}
292
+
293
+/**
294
+ * Fill in all variable portions of iBFT
295
+ *
296
+ * @v netdev		Network device
297
+ * @v initiator_iqn	Initiator IQN
298
+ * @v st_target		Target socket address
299
+ * @v target_iqn	Target IQN
300
+ * @ret rc		Return status code
301
+ *
302
+ */
303
+int ibft_fill_data ( struct net_device *netdev,
304
+		     struct iscsi_session *iscsi ) {
305
+	struct ibft_string_block strings = {
306
+		.table = &ibftab.table,
307
+		.offset = offsetof ( typeof ( ibftab ), strings ),
308
+	};
309
+	int rc;
310
+
311
+	/* Fill in NIC, Initiator and Target portions */
312
+	if ( ( rc = ibft_fill_nic ( &ibftab.nic, &strings, netdev ) ) != 0 )
313
+		return rc;
314
+	if ( ( rc = ibft_fill_initiator ( &ibftab.initiator,
315
+					  &strings ) ) != 0 )
316
+		return rc;
317
+	if ( ( rc = ibft_fill_target ( &ibftab.target, &strings,
318
+				       iscsi ) ) != 0 )
319
+		return rc;
320
+
321
+	/* Update checksum */
322
+	acpi_fix_checksum ( &ibftab.table.acpi );
323
+
324
+	return 0;
325
+}

+ 295
- 6
src/include/gpxe/ibft.h Просмотреть файл

@@ -1,11 +1,300 @@
1 1
 #ifndef _GPXE_IBFT_H
2 2
 #define _GPXE_IBFT_H
3 3
 
4
-/* Placeholder file */
4
+/*
5
+ * Copyright Fen Systems Ltd. 2007.  Portions of this code are derived
6
+ * from IBM Corporation Sample Programs.  Copyright IBM Corporation
7
+ * 2004, 2007.  All rights reserved.
8
+ *
9
+ * Permission is hereby granted, free of charge, to any person
10
+ * obtaining a copy of this software and associated documentation
11
+ * files (the "Software"), to deal in the Software without
12
+ * restriction, including without limitation the rights to use, copy,
13
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
14
+ * of the Software, and to permit persons to whom the Software is
15
+ * furnished to do so, subject to the following conditions:
16
+ *
17
+ * The above copyright notice and this permission notice shall be
18
+ * included in all copies or substantial portions of the Software.
19
+ *
20
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
24
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ * SOFTWARE.
28
+ *
29
+ */
30
+
31
+/** @file
32
+ *
33
+ * iSCSI boot firmware table
34
+ *
35
+ * The information in this file is derived from the document "iSCSI
36
+ * Boot Firmware Table (iBFT)" as published by IBM at
37
+ *
38
+ * ftp://ftp.software.ibm.com/systems/support/system_x_pdf/ibm_iscsi_boot_firmware_table_v1.02.pdf
39
+ *
40
+ */
41
+
42
+#include <stdint.h>
43
+#include <gpxe/acpi.h>
44
+#include <gpxe/in.h>
45
+
46
+/** iSCSI Boot Firmware Table signature */
47
+#define IBFT_SIG "iBFT"
48
+
49
+/** An offset from the start of the iBFT */
50
+typedef uint16_t ibft_off_t;
51
+
52
+/** Length of a string within the iBFT (excluding terminating NUL) */
53
+typedef uint16_t ibft_size_t;
54
+
55
+/** A string within the iBFT */
56
+struct ibft_string {
57
+	/** Length of string */
58
+	ibft_size_t length;
59
+	/** Offset to string */
60
+	ibft_off_t offset;
61
+} __attribute__ (( packed ));
62
+
63
+/** An IP address within the iBFT */
64
+struct ibft_ipaddr {
65
+	/** Reserved; must be zero */
66
+	uint16_t zeroes[5];
67
+	/** Must be 0xffff if IPv4 address is present, otherwise zero */
68
+	uint16_t ones;
69
+	/** The IPv4 address, or zero if not present */
70
+	struct in_addr in;
71
+} __attribute__ (( packed ));
72
+
73
+/**
74
+ * iBFT structure header
75
+ *
76
+ * This structure is common to several sections within the iBFT.
77
+ */
78
+struct ibft_header {
79
+	/** Structure ID
80
+	 *
81
+	 * This is an IBFT_STRUCTURE_ID_XXX constant
82
+	 */
83
+	uint8_t structure_id;
84
+	/** Version (always 1) */
85
+	uint8_t version;
86
+	/** Length, including this header */
87
+	uint16_t length;
88
+	/** Index 
89
+	 *
90
+	 * This is the number of the NIC or Target, when applicable.
91
+	 */
92
+	uint8_t index;
93
+	/** Flags */
94
+	uint8_t flags;
95
+} __attribute__ (( packed ));
96
+
97
+/**
98
+ * iBFT Control structure
99
+ *
100
+ */
101
+struct ibft_control {
102
+	/** Common header */
103
+	struct ibft_header header;
104
+	/** Extensions */
105
+	uint16_t extensions;
106
+	/** Offset to Initiator structure */
107
+	ibft_off_t initiator;
108
+	/** Offset to NIC structure for NIC 0 */
109
+	ibft_off_t nic_0;
110
+	/** Offset to Target structure for target 0 */
111
+	ibft_off_t target_0;
112
+	/** Offset to NIC structure for NIC 1 */
113
+	ibft_off_t nic_1;
114
+	/** Offset to Target structure for target 1 */
115
+	ibft_off_t target_1;
116
+} __attribute__ (( packed ));
117
+
118
+/** Structure ID for Control section */
119
+#define IBFT_STRUCTURE_ID_CONTROL 0x01
120
+
121
+/** Attempt login only to specified target
122
+ *
123
+ * If this flag is not set, all targets will be logged in to.
124
+ */
125
+#define IBFT_FL_CONTROL_SINGLE_LOGIN_ONLY 0x01
126
+
127
+/**
128
+ * iBFT Initiator structure
129
+ *
130
+ */
131
+struct ibft_initiator {
132
+	/** Common header */
133
+	struct ibft_header header;
134
+	/** iSNS server */
135
+	struct ibft_ipaddr isns_server;
136
+	/** SLP server */
137
+	struct ibft_ipaddr slp_server;
138
+	/** Primary and secondary Radius servers */
139
+	struct ibft_ipaddr radius[2];
140
+	/** Initiator name */
141
+	struct ibft_string initiator_name;
142
+} __attribute__ (( packed ));
143
+
144
+/** Structure ID for Initiator section */
145
+#define IBFT_STRUCTURE_ID_INITIATOR 0x02
146
+
147
+/** Initiator block valid */
148
+#define IBFT_FL_INITIATOR_BLOCK_VALID 0x01
149
+
150
+/** Initiator firmware boot selected */
151
+#define IBFT_FL_INITIATOR_FIRMWARE_BOOT_SELECTED 0x02
152
+
153
+/**
154
+ * iBFT NIC structure
155
+ *
156
+ */
157
+struct ibft_nic {
158
+	/** Common header */
159
+	struct ibft_header header;
160
+	/** IP address */
161
+	struct ibft_ipaddr ip_address;
162
+	/** Subnet mask
163
+	 *
164
+	 * This is the length of the subnet mask in bits (e.g. /24).
165
+	 */
166
+	uint8_t subnet_mask_prefix;
167
+	/** Origin */
168
+	uint8_t origin;
169
+	/** Default gateway */
170
+	struct ibft_ipaddr gateway;
171
+	/** Primary and secondary DNS servers */
172
+	struct ibft_ipaddr dns[2];
173
+	/** DHCP server */
174
+	struct ibft_ipaddr dhcp;
175
+	/** VLAN tag */
176
+	uint16_t vlan;
177
+	/** MAC address */
178
+	uint8_t mac_address[6];
179
+	/** PCI bus:dev:fn */
180
+	uint16_t pci_bus_dev_func;
181
+	/** Hostname */
182
+	struct ibft_string hostname;
183
+} __attribute__ (( packed ));
184
+
185
+/** Structure ID for NIC section */
186
+#define IBFT_STRUCTURE_ID_NIC 0x03
187
+
188
+/** NIC block valid */
189
+#define IBFT_FL_NIC_BLOCK_VALID 0x01
190
+
191
+/** NIC firmware boot selected */
192
+#define IBFT_FL_NIC_FIRMWARE_BOOT_SELECTED 0x02
193
+
194
+/** NIC global / link local */
195
+#define IBFT_FL_NIC_GLOBAL 0x04
196
+
197
+/**
198
+ * iBFT Target structure
199
+ *
200
+ */
201
+struct ibft_target {
202
+	/** Common header */
203
+	struct ibft_header header;
204
+	/** IP address */
205
+	struct ibft_ipaddr ip_address;
206
+	/** TCP port */
207
+	uint16_t socket;
208
+	/** Boot LUN */
209
+	uint64_t boot_lun;
210
+	/** CHAP type
211
+	 *
212
+	 * This is an IBFT_CHAP_XXX constant.
213
+	 */
214
+	uint8_t chap_type;
215
+	/** NIC association */
216
+	uint8_t nic_association;
217
+	/** Target name */
218
+	struct ibft_string target_name;
219
+	/** CHAP name */
220
+	struct ibft_string chap_name;
221
+	/** CHAP secret */
222
+	struct ibft_string chap_secret;
223
+	/** Reverse CHAP name */
224
+	struct ibft_string reverse_chap_name;
225
+	/** Reverse CHAP secret */
226
+	struct ibft_string reverse_chap_secret;
227
+} __attribute__ (( packed ));
228
+
229
+/** Structure ID for Target section */
230
+#define IBFT_STRUCTURE_ID_TARGET 0x04
231
+
232
+/** Target block valid */
233
+#define IBFT_FL_TARGET_BLOCK_VALID 0x01
234
+
235
+/** Target firmware boot selected */
236
+#define IBFT_FL_TARGET_FIRMWARE_BOOT_SELECTED 0x02
237
+
238
+/** Target use Radius CHAP */
239
+#define IBFT_FL_TARGET_USE_CHAP 0x04
240
+
241
+/** Target use Radius rCHAP */
242
+#define IBFT_FL_TARGET_USE_RCHAP 0x08
243
+
244
+/* Values for chap_type */
245
+#define IBFT_CHAP_NONE		0	/**< No CHAP authentication */
246
+#define IBFT_CHAP_ONE_WAY	1	/**< One-way CHAP */
247
+#define IBFT_CHAP_MUTUAL	2	/**< Mutual CHAP */
248
+
249
+/**
250
+ * iSCSI Boot Firmware Table (iBFT)
251
+ */
252
+struct ibft_table {
253
+	/** ACPI header */
254
+	struct acpi_description_header acpi;
255
+	/** Reserved */
256
+	uint8_t reserved[12];
257
+	/** Control structure */
258
+	struct ibft_control control;
259
+} __attribute__ (( packed ));
260
+
261
+/**
262
+ * iSCSI string block descriptor
263
+ *
264
+ * This is an internal structure that we use to keep track of the
265
+ * allocation of string data.
266
+ */
267
+struct ibft_string_block {
268
+	/** The iBFT containing these strings */
269
+	struct ibft_table *table;
270
+	/** Offset of first free byte within iBFT */
271
+	unsigned int offset;
272
+};
273
+
274
+/** Amount of space reserved for strings in a gPXE iBFT */
275
+#define IBFT_STRINGS_SIZE 384
276
+
277
+/**
278
+ * An iBFT created by gPXE
279
+ *
280
+ */
281
+struct gpxe_ibft {
282
+	/** The fixed section */
283
+	struct ibft_table table;
284
+	/** The Initiator section */
285
+	struct ibft_initiator initiator __attribute__ (( aligned ( 16 ) ));
286
+	/** The NIC section */
287
+	struct ibft_nic nic __attribute__ (( aligned ( 16 ) ));
288
+	/** The Target section */
289
+	struct ibft_target target __attribute__ (( aligned ( 16 ) ));
290
+	/** Strings block */
291
+	char strings[IBFT_STRINGS_SIZE];
292
+} __attribute__ (( packed, aligned ( 16 ) ));
293
+
294
+struct net_device;
295
+struct iscsi_session;
296
+
297
+extern int ibft_fill_data ( struct net_device *netdev,
298
+			    struct iscsi_session *iscsi );
5 299
 
6
-static inline int ibft_fill_data ( struct net_device *netdev __unused,
7
-				   struct iscsi_session *iscsi __unused ) {
8
-	return 0;
9
-}
10
- 
11 300
 #endif /* _GPXE_IBFT_H */

Загрузка…
Отмена
Сохранить