Blame view

drivers/firmware/iscsi_ibft.c 20.7 KB
d95236782   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
2
  /*
4e639fdf0   Peter Jones   ibft: Update iBFT...
3
   *  Copyright 2007-2010 Red Hat, Inc.
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
4
5
6
7
8
9
10
11
   *  by Peter Jones <pjones@redhat.com>
   *  Copyright 2008 IBM, Inc.
   *  by Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
   *  Copyright 2008
   *  by Konrad Rzeszutek <ketuzsezr@darnok.org>
   *
   * This code exposes the iSCSI Boot Format Table to userland via sysfs.
   *
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
12
13
   * Changelog:
   *
4e639fdf0   Peter Jones   ibft: Update iBFT...
14
15
16
   *  06 Jan 2010 - Peter Jones <pjones@redhat.com>
   *    New changelog entries are in the git log from now on.  Not here.
   *
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
   *  14 Mar 2008 - Konrad Rzeszutek <ketuzsezr@darnok.org>
   *    Updated comments and copyrights. (v0.4.9)
   *
   *  11 Feb 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
   *    Converted to using ibft_addr. (v0.4.8)
   *
   *   8 Feb 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
   *    Combined two functions in one: reserve_ibft_region. (v0.4.7)
   *
   *  30 Jan 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
   *   Added logic to handle IPv6 addresses. (v0.4.6)
   *
   *  25 Jan 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
   *   Added logic to handle badly not-to-spec iBFT. (v0.4.5)
   *
   *   4 Jan 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
   *   Added __init to function declarations. (v0.4.4)
   *
   *  21 Dec 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
   *   Updated kobject registration, combined unregister functions in one
   *   and code and style cleanup. (v0.4.3)
   *
   *   5 Dec 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
   *   Added end-markers to enums and re-organized kobject registration. (v0.4.2)
   *
   *   4 Dec 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
   *   Created 'device' sysfs link to the NIC and style cleanup. (v0.4.1)
   *
   *  28 Nov 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
   *   Added sysfs-ibft documentation, moved 'find_ibft' function to
   *   in its own file and added text attributes for every struct field.  (v0.4)
   *
   *  21 Nov 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
   *   Added text attributes emulating OpenFirmware /proc/device-tree naming.
   *   Removed binary /sysfs interface (v0.3)
   *
   *  29 Aug 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
   *   Added functionality in setup.c to reserve iBFT region. (v0.2)
   *
   *  27 Aug 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
   *   First version exposing iBFT data via a binary /sysfs. (v0.1)
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
   */
  
  
  #include <linux/blkdev.h>
  #include <linux/capability.h>
  #include <linux/ctype.h>
  #include <linux/device.h>
  #include <linux/err.h>
  #include <linux/init.h>
  #include <linux/iscsi_ibft.h>
  #include <linux/limits.h>
  #include <linux/module.h>
  #include <linux/pci.h>
  #include <linux/slab.h>
  #include <linux/stat.h>
  #include <linux/string.h>
  #include <linux/types.h>
4e639fdf0   Peter Jones   ibft: Update iBFT...
75
  #include <linux/acpi.h>
b33a84a38   Mike Christie   ibft: convert isc...
76
  #include <linux/iscsi_boot_sysfs.h>
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
77

4e639fdf0   Peter Jones   ibft: Update iBFT...
78
79
  #define IBFT_ISCSI_VERSION "0.5.0"
  #define IBFT_ISCSI_DATE "2010-Feb-25"
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
80

85ee7a1d3   Joe Perches   treewide: cleanup...
81
82
  MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and "
  	      "Konrad Rzeszutek <ketuzsezr@darnok.org>");
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
83
84
85
  MODULE_DESCRIPTION("sysfs interface to BIOS iBFT information");
  MODULE_LICENSE("GPL");
  MODULE_VERSION(IBFT_ISCSI_VERSION);
94bccc340   Thomas Tai   iscsi_ibft: make ...
86
87
88
  #ifndef CONFIG_ISCSI_IBFT_FIND
  struct acpi_table_ibft *ibft_addr;
  #endif
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  struct ibft_hdr {
  	u8 id;
  	u8 version;
  	u16 length;
  	u8 index;
  	u8 flags;
  } __attribute__((__packed__));
  
  struct ibft_control {
  	struct ibft_hdr hdr;
  	u16 extensions;
  	u16 initiator_off;
  	u16 nic0_off;
  	u16 tgt0_off;
  	u16 nic1_off;
  	u16 tgt1_off;
8192e60c6   Gustavo A. R. Silva   ibft: Replace zer...
105
  	u16 expansion[];
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
  } __attribute__((__packed__));
  
  struct ibft_initiator {
  	struct ibft_hdr hdr;
  	char isns_server[16];
  	char slp_server[16];
  	char pri_radius_server[16];
  	char sec_radius_server[16];
  	u16 initiator_name_len;
  	u16 initiator_name_off;
  } __attribute__((__packed__));
  
  struct ibft_nic {
  	struct ibft_hdr hdr;
  	char ip_addr[16];
  	u8 subnet_mask_prefix;
  	u8 origin;
  	char gateway[16];
  	char primary_dns[16];
  	char secondary_dns[16];
  	char dhcp[16];
  	u16 vlan;
  	char mac[6];
  	u16 pci_bdf;
  	u16 hostname_len;
  	u16 hostname_off;
  } __attribute__((__packed__));
  
  struct ibft_tgt {
  	struct ibft_hdr hdr;
  	char ip_addr[16];
  	u16 port;
  	char lun[8];
  	u8 chap_type;
  	u8 nic_assoc;
  	u16 tgt_name_len;
  	u16 tgt_name_off;
  	u16 chap_name_len;
  	u16 chap_name_off;
  	u16 chap_secret_len;
  	u16 chap_secret_off;
  	u16 rev_chap_name_len;
  	u16 rev_chap_name_off;
  	u16 rev_chap_secret_len;
  	u16 rev_chap_secret_off;
  } __attribute__((__packed__));
  
  /*
   * The kobject different types and its names.
   *
  */
  enum ibft_id {
  	id_reserved = 0, /* We don't support. */
  	id_control = 1, /* Should show up only once and is not exported. */
  	id_initiator = 2,
  	id_nic = 3,
  	id_target = 4,
  	id_extensions = 5, /* We don't support. */
  	id_end_marker,
  };
  
  /*
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
168
169
170
171
   * The kobject and attribute structures.
   */
  
  struct ibft_kobject {
4e639fdf0   Peter Jones   ibft: Update iBFT...
172
  	struct acpi_table_ibft *header;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
173
174
175
176
177
178
  	union {
  		struct ibft_initiator *initiator;
  		struct ibft_nic *nic;
  		struct ibft_tgt *tgt;
  		struct ibft_hdr *hdr;
  	};
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
179
  };
b33a84a38   Mike Christie   ibft: convert isc...
180
  static struct iscsi_boot_kset *boot_kset;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
181

e6050b61d   Chris Leech   iscsi_ibft: filte...
182
  /* fully null address */
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
183
  static const char nulls[16];
e6050b61d   Chris Leech   iscsi_ibft: filte...
184
185
186
187
188
189
190
191
192
193
  /* IPv4-mapped IPv6 ::ffff:0.0.0.0 */
  static const char mapped_nulls[16] = { 0x00, 0x00, 0x00, 0x00,
                                         0x00, 0x00, 0x00, 0x00,
                                         0x00, 0x00, 0xff, 0xff,
                                         0x00, 0x00, 0x00, 0x00 };
  
  static int address_not_null(u8 *ip)
  {
  	return (memcmp(ip, nulls, 16) && memcmp(ip, mapped_nulls, 16));
  }
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
194
195
196
197
198
199
200
201
202
203
204
205
206
  /*
   * Helper functions to parse data properly.
   */
  static ssize_t sprintf_ipaddr(char *buf, u8 *ip)
  {
  	char *str = buf;
  
  	if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0 &&
  	    ip[4] == 0 && ip[5] == 0 && ip[6] == 0 && ip[7] == 0 &&
  	    ip[8] == 0 && ip[9] == 0 && ip[10] == 0xff && ip[11] == 0xff) {
  		/*
  		 * IPV4
  		 */
63779436a   Harvey Harrison   drivers: replace ...
207
  		str += sprintf(buf, "%pI4", ip + 12);
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
208
209
210
211
  	} else {
  		/*
  		 * IPv6
  		 */
5b095d989   Harvey Harrison   net: replace %p6 ...
212
  		str += sprintf(str, "%pI6", ip);
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
  	}
  	str += sprintf(str, "
  ");
  	return str - buf;
  }
  
  static ssize_t sprintf_string(char *str, int len, char *buf)
  {
  	return sprintf(str, "%.*s
  ", len, buf);
  }
  
  /*
   * Helper function to verify the IBFT header.
   */
  static int ibft_verify_hdr(char *t, struct ibft_hdr *hdr, int id, int length)
  {
  	if (hdr->id != id) {
b33a84a38   Mike Christie   ibft: convert isc...
231
  		printk(KERN_ERR "iBFT error: We expected the %s " \
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
232
  				"field header.id to have %d but " \
b33a84a38   Mike Christie   ibft: convert isc...
233
234
  				"found %d instead!
  ", t, id, hdr->id);
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
235
236
  		return -ENODEV;
  	}
c08406033   Lubomir Rintel   iscsi_ibft: Don't...
237
  	if (length && hdr->length != length) {
b33a84a38   Mike Christie   ibft: convert isc...
238
  		printk(KERN_ERR "iBFT error: We expected the %s " \
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
239
  				"field header.length to have %d but " \
b33a84a38   Mike Christie   ibft: convert isc...
240
241
  				"found %d instead!
  ", t, length, hdr->length);
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
242
243
244
245
246
  		return -ENODEV;
  	}
  
  	return 0;
  }
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
247
248
249
  /*
   *  Routines for parsing the iBFT data to be human readable.
   */
b33a84a38   Mike Christie   ibft: convert isc...
250
  static ssize_t ibft_attr_show_initiator(void *data, int type, char *buf)
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
251
  {
b33a84a38   Mike Christie   ibft: convert isc...
252
  	struct ibft_kobject *entry = data;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
253
254
255
256
257
258
  	struct ibft_initiator *initiator = entry->initiator;
  	void *ibft_loc = entry->header;
  	char *str = buf;
  
  	if (!initiator)
  		return 0;
b33a84a38   Mike Christie   ibft: convert isc...
259
260
  	switch (type) {
  	case ISCSI_BOOT_INI_INDEX:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
261
262
263
  		str += sprintf(str, "%d
  ", initiator->hdr.index);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
264
  	case ISCSI_BOOT_INI_FLAGS:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
265
266
267
  		str += sprintf(str, "%d
  ", initiator->hdr.flags);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
268
  	case ISCSI_BOOT_INI_ISNS_SERVER:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
269
270
  		str += sprintf_ipaddr(str, initiator->isns_server);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
271
  	case ISCSI_BOOT_INI_SLP_SERVER:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
272
273
  		str += sprintf_ipaddr(str, initiator->slp_server);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
274
  	case ISCSI_BOOT_INI_PRI_RADIUS_SERVER:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
275
276
  		str += sprintf_ipaddr(str, initiator->pri_radius_server);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
277
  	case ISCSI_BOOT_INI_SEC_RADIUS_SERVER:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
278
279
  		str += sprintf_ipaddr(str, initiator->sec_radius_server);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
280
  	case ISCSI_BOOT_INI_INITIATOR_NAME:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
281
282
283
284
285
286
287
288
289
290
  		str += sprintf_string(str, initiator->initiator_name_len,
  				      (char *)ibft_loc +
  				      initiator->initiator_name_off);
  		break;
  	default:
  		break;
  	}
  
  	return str - buf;
  }
b33a84a38   Mike Christie   ibft: convert isc...
291
  static ssize_t ibft_attr_show_nic(void *data, int type, char *buf)
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
292
  {
b33a84a38   Mike Christie   ibft: convert isc...
293
  	struct ibft_kobject *entry = data;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
294
295
296
  	struct ibft_nic *nic = entry->nic;
  	void *ibft_loc = entry->header;
  	char *str = buf;
00e7825b9   Joe Perches   drivers/firmware/...
297
  	__be32 val;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
298
299
300
  
  	if (!nic)
  		return 0;
b33a84a38   Mike Christie   ibft: convert isc...
301
302
  	switch (type) {
  	case ISCSI_BOOT_ETH_INDEX:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
303
304
305
  		str += sprintf(str, "%d
  ", nic->hdr.index);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
306
  	case ISCSI_BOOT_ETH_FLAGS:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
307
308
309
  		str += sprintf(str, "%d
  ", nic->hdr.flags);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
310
  	case ISCSI_BOOT_ETH_IP_ADDR:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
311
312
  		str += sprintf_ipaddr(str, nic->ip_addr);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
313
  	case ISCSI_BOOT_ETH_SUBNET_MASK:
00e7825b9   Joe Perches   drivers/firmware/...
314
315
  		val = cpu_to_be32(~((1 << (32-nic->subnet_mask_prefix))-1));
  		str += sprintf(str, "%pI4", &val);
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
316
  		break;
9a99425f0   Hannes Reinecke   iscsi_ibft: Add p...
317
318
319
320
  	case ISCSI_BOOT_ETH_PREFIX_LEN:
  		str += sprintf(str, "%d
  ", nic->subnet_mask_prefix);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
321
  	case ISCSI_BOOT_ETH_ORIGIN:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
322
323
324
  		str += sprintf(str, "%d
  ", nic->origin);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
325
  	case ISCSI_BOOT_ETH_GATEWAY:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
326
327
  		str += sprintf_ipaddr(str, nic->gateway);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
328
  	case ISCSI_BOOT_ETH_PRIMARY_DNS:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
329
330
  		str += sprintf_ipaddr(str, nic->primary_dns);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
331
  	case ISCSI_BOOT_ETH_SECONDARY_DNS:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
332
333
  		str += sprintf_ipaddr(str, nic->secondary_dns);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
334
  	case ISCSI_BOOT_ETH_DHCP:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
335
336
  		str += sprintf_ipaddr(str, nic->dhcp);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
337
  	case ISCSI_BOOT_ETH_VLAN:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
338
339
340
  		str += sprintf(str, "%d
  ", nic->vlan);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
341
  	case ISCSI_BOOT_ETH_MAC:
2c3529485   hartleys   drivers/firmware/...
342
343
  		str += sprintf(str, "%pM
  ", nic->mac);
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
344
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
345
  	case ISCSI_BOOT_ETH_HOSTNAME:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
346
347
348
349
350
351
352
353
354
  		str += sprintf_string(str, nic->hostname_len,
  				      (char *)ibft_loc + nic->hostname_off);
  		break;
  	default:
  		break;
  	}
  
  	return str - buf;
  };
b33a84a38   Mike Christie   ibft: convert isc...
355
  static ssize_t ibft_attr_show_target(void *data, int type, char *buf)
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
356
  {
b33a84a38   Mike Christie   ibft: convert isc...
357
  	struct ibft_kobject *entry = data;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
358
359
360
361
362
363
364
  	struct ibft_tgt *tgt = entry->tgt;
  	void *ibft_loc = entry->header;
  	char *str = buf;
  	int i;
  
  	if (!tgt)
  		return 0;
b33a84a38   Mike Christie   ibft: convert isc...
365
366
  	switch (type) {
  	case ISCSI_BOOT_TGT_INDEX:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
367
368
369
  		str += sprintf(str, "%d
  ", tgt->hdr.index);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
370
  	case ISCSI_BOOT_TGT_FLAGS:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
371
372
373
  		str += sprintf(str, "%d
  ", tgt->hdr.flags);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
374
  	case ISCSI_BOOT_TGT_IP_ADDR:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
375
376
  		str += sprintf_ipaddr(str, tgt->ip_addr);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
377
  	case ISCSI_BOOT_TGT_PORT:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
378
379
380
  		str += sprintf(str, "%d
  ", tgt->port);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
381
  	case ISCSI_BOOT_TGT_LUN:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
382
383
384
385
386
  		for (i = 0; i < 8; i++)
  			str += sprintf(str, "%x", (u8)tgt->lun[i]);
  		str += sprintf(str, "
  ");
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
387
  	case ISCSI_BOOT_TGT_NIC_ASSOC:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
388
389
390
  		str += sprintf(str, "%d
  ", tgt->nic_assoc);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
391
  	case ISCSI_BOOT_TGT_CHAP_TYPE:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
392
393
394
  		str += sprintf(str, "%d
  ", tgt->chap_type);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
395
  	case ISCSI_BOOT_TGT_NAME:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
396
397
398
  		str += sprintf_string(str, tgt->tgt_name_len,
  				      (char *)ibft_loc + tgt->tgt_name_off);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
399
  	case ISCSI_BOOT_TGT_CHAP_NAME:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
400
401
402
  		str += sprintf_string(str, tgt->chap_name_len,
  				      (char *)ibft_loc + tgt->chap_name_off);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
403
  	case ISCSI_BOOT_TGT_CHAP_SECRET:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
404
405
406
  		str += sprintf_string(str, tgt->chap_secret_len,
  				      (char *)ibft_loc + tgt->chap_secret_off);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
407
  	case ISCSI_BOOT_TGT_REV_CHAP_NAME:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
408
409
410
411
  		str += sprintf_string(str, tgt->rev_chap_name_len,
  				      (char *)ibft_loc +
  				      tgt->rev_chap_name_off);
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
412
  	case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
413
414
415
416
417
418
419
420
421
422
  		str += sprintf_string(str, tgt->rev_chap_secret_len,
  				      (char *)ibft_loc +
  				      tgt->rev_chap_secret_off);
  		break;
  	default:
  		break;
  	}
  
  	return str - buf;
  }
b3c8eb503   David Bond   ibft: Expose iBFT...
423
424
425
426
427
428
429
  static ssize_t ibft_attr_show_acpitbl(void *data, int type, char *buf)
  {
  	struct ibft_kobject *entry = data;
  	char *str = buf;
  
  	switch (type) {
  	case ISCSI_BOOT_ACPITBL_SIGNATURE:
327867556   Bob Moore   ACPICA: Rename na...
430
  		str += sprintf_string(str, ACPI_NAMESEG_SIZE,
b3c8eb503   David Bond   ibft: Expose iBFT...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
  				      entry->header->header.signature);
  		break;
  	case ISCSI_BOOT_ACPITBL_OEM_ID:
  		str += sprintf_string(str, ACPI_OEM_ID_SIZE,
  				      entry->header->header.oem_id);
  		break;
  	case ISCSI_BOOT_ACPITBL_OEM_TABLE_ID:
  		str += sprintf_string(str, ACPI_OEM_TABLE_ID_SIZE,
  				      entry->header->header.oem_table_id);
  		break;
  	default:
  		break;
  	}
  
  	return str - buf;
  }
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
447
448
449
450
451
  static int __init ibft_check_device(void)
  {
  	int len;
  	u8 *pos;
  	u8 csum = 0;
4e639fdf0   Peter Jones   ibft: Update iBFT...
452
  	len = ibft_addr->header.length;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
453
454
  
  	/* Sanity checking of iBFT. */
4e639fdf0   Peter Jones   ibft: Update iBFT...
455
  	if (ibft_addr->header.revision != 1) {
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
456
  		printk(KERN_ERR "iBFT module supports only revision 1, " \
4e639fdf0   Peter Jones   ibft: Update iBFT...
457
458
459
  				"while this is %d.
  ",
  				ibft_addr->header.revision);
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
  		return -ENOENT;
  	}
  	for (pos = (u8 *)ibft_addr; pos < (u8 *)ibft_addr + len; pos++)
  		csum += *pos;
  
  	if (csum) {
  		printk(KERN_ERR "iBFT has incorrect checksum (0x%x)!
  ", csum);
  		return -ENOENT;
  	}
  
  	return 0;
  }
  
  /*
b33a84a38   Mike Christie   ibft: convert isc...
475
476
477
   * Helper routiners to check to determine if the entry is valid
   * in the proper iBFT structure.
   */
587a1f165   Al Viro   switch ->is_visib...
478
  static umode_t ibft_check_nic_for(void *data, int type)
b33a84a38   Mike Christie   ibft: convert isc...
479
480
481
  {
  	struct ibft_kobject *entry = data;
  	struct ibft_nic *nic = entry->nic;
587a1f165   Al Viro   switch ->is_visib...
482
  	umode_t rc = 0;
b33a84a38   Mike Christie   ibft: convert isc...
483
484
485
486
487
488
489
  
  	switch (type) {
  	case ISCSI_BOOT_ETH_INDEX:
  	case ISCSI_BOOT_ETH_FLAGS:
  		rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_ETH_IP_ADDR:
e6050b61d   Chris Leech   iscsi_ibft: filte...
490
  		if (address_not_null(nic->ip_addr))
b33a84a38   Mike Christie   ibft: convert isc...
491
492
  			rc = S_IRUGO;
  		break;
9a99425f0   Hannes Reinecke   iscsi_ibft: Add p...
493
  	case ISCSI_BOOT_ETH_PREFIX_LEN:
b33a84a38   Mike Christie   ibft: convert isc...
494
495
496
497
498
499
500
501
  	case ISCSI_BOOT_ETH_SUBNET_MASK:
  		if (nic->subnet_mask_prefix)
  			rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_ETH_ORIGIN:
  		rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_ETH_GATEWAY:
e6050b61d   Chris Leech   iscsi_ibft: filte...
502
  		if (address_not_null(nic->gateway))
b33a84a38   Mike Christie   ibft: convert isc...
503
504
505
  			rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_ETH_PRIMARY_DNS:
e6050b61d   Chris Leech   iscsi_ibft: filte...
506
  		if (address_not_null(nic->primary_dns))
b33a84a38   Mike Christie   ibft: convert isc...
507
508
509
  			rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_ETH_SECONDARY_DNS:
e6050b61d   Chris Leech   iscsi_ibft: filte...
510
  		if (address_not_null(nic->secondary_dns))
b33a84a38   Mike Christie   ibft: convert isc...
511
512
513
  			rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_ETH_DHCP:
e6050b61d   Chris Leech   iscsi_ibft: filte...
514
  		if (address_not_null(nic->dhcp))
b33a84a38   Mike Christie   ibft: convert isc...
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
  			rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_ETH_VLAN:
  	case ISCSI_BOOT_ETH_MAC:
  		rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_ETH_HOSTNAME:
  		if (nic->hostname_off)
  			rc = S_IRUGO;
  		break;
  	default:
  		break;
  	}
  
  	return rc;
  }
587a1f165   Al Viro   switch ->is_visib...
531
  static umode_t __init ibft_check_tgt_for(void *data, int type)
b33a84a38   Mike Christie   ibft: convert isc...
532
533
534
  {
  	struct ibft_kobject *entry = data;
  	struct ibft_tgt *tgt = entry->tgt;
587a1f165   Al Viro   switch ->is_visib...
535
  	umode_t rc = 0;
b33a84a38   Mike Christie   ibft: convert isc...
536
537
538
539
540
541
542
543
544
545
  
  	switch (type) {
  	case ISCSI_BOOT_TGT_INDEX:
  	case ISCSI_BOOT_TGT_FLAGS:
  	case ISCSI_BOOT_TGT_IP_ADDR:
  	case ISCSI_BOOT_TGT_PORT:
  	case ISCSI_BOOT_TGT_LUN:
  	case ISCSI_BOOT_TGT_NIC_ASSOC:
  	case ISCSI_BOOT_TGT_CHAP_TYPE:
  		rc = S_IRUGO;
df997abee   Gustavo A. R. Silva   iscsi_ibft: Fix m...
546
  		break;
b33a84a38   Mike Christie   ibft: convert isc...
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
  	case ISCSI_BOOT_TGT_NAME:
  		if (tgt->tgt_name_len)
  			rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_TGT_CHAP_NAME:
  	case ISCSI_BOOT_TGT_CHAP_SECRET:
  		if (tgt->chap_name_len)
  			rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_TGT_REV_CHAP_NAME:
  	case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
  		if (tgt->rev_chap_name_len)
  			rc = S_IRUGO;
  		break;
  	default:
  		break;
  	}
  
  	return rc;
  }
587a1f165   Al Viro   switch ->is_visib...
567
  static umode_t __init ibft_check_initiator_for(void *data, int type)
b33a84a38   Mike Christie   ibft: convert isc...
568
569
570
  {
  	struct ibft_kobject *entry = data;
  	struct ibft_initiator *init = entry->initiator;
587a1f165   Al Viro   switch ->is_visib...
571
  	umode_t rc = 0;
b33a84a38   Mike Christie   ibft: convert isc...
572
573
574
575
576
577
578
  
  	switch (type) {
  	case ISCSI_BOOT_INI_INDEX:
  	case ISCSI_BOOT_INI_FLAGS:
  		rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_INI_ISNS_SERVER:
e6050b61d   Chris Leech   iscsi_ibft: filte...
579
  		if (address_not_null(init->isns_server))
b33a84a38   Mike Christie   ibft: convert isc...
580
581
582
  			rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_INI_SLP_SERVER:
e6050b61d   Chris Leech   iscsi_ibft: filte...
583
  		if (address_not_null(init->slp_server))
b33a84a38   Mike Christie   ibft: convert isc...
584
585
586
  			rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_INI_PRI_RADIUS_SERVER:
e6050b61d   Chris Leech   iscsi_ibft: filte...
587
  		if (address_not_null(init->pri_radius_server))
b33a84a38   Mike Christie   ibft: convert isc...
588
589
590
  			rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_INI_SEC_RADIUS_SERVER:
e6050b61d   Chris Leech   iscsi_ibft: filte...
591
  		if (address_not_null(init->sec_radius_server))
b33a84a38   Mike Christie   ibft: convert isc...
592
593
594
595
596
597
598
599
600
601
602
603
  			rc = S_IRUGO;
  		break;
  	case ISCSI_BOOT_INI_INITIATOR_NAME:
  		if (init->initiator_name_len)
  			rc = S_IRUGO;
  		break;
  	default:
  		break;
  	}
  
  	return rc;
  }
b3c8eb503   David Bond   ibft: Expose iBFT...
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
  static umode_t __init ibft_check_acpitbl_for(void *data, int type)
  {
  
  	umode_t rc = 0;
  
  	switch (type) {
  	case ISCSI_BOOT_ACPITBL_SIGNATURE:
  	case ISCSI_BOOT_ACPITBL_OEM_ID:
  	case ISCSI_BOOT_ACPITBL_OEM_TABLE_ID:
  		rc = S_IRUGO;
  		break;
  	default:
  		break;
  	}
  
  	return rc;
  }
f457a46f1   Mike Christie   [SCSI] iscsi_ibft...
621
622
623
624
  static void ibft_kobj_release(void *data)
  {
  	kfree(data);
  }
b33a84a38   Mike Christie   ibft: convert isc...
625
  /*
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
626
627
   * Helper function for ibft_register_kobjects.
   */
4e639fdf0   Peter Jones   ibft: Update iBFT...
628
  static int __init ibft_create_kobject(struct acpi_table_ibft *header,
b33a84a38   Mike Christie   ibft: convert isc...
629
  				      struct ibft_hdr *hdr)
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
630
  {
b33a84a38   Mike Christie   ibft: convert isc...
631
  	struct iscsi_boot_kobj *boot_kobj = NULL;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
  	struct ibft_kobject *ibft_kobj = NULL;
  	struct ibft_nic *nic = (struct ibft_nic *)hdr;
  	struct pci_dev *pci_dev;
  	int rc = 0;
  
  	ibft_kobj = kzalloc(sizeof(*ibft_kobj), GFP_KERNEL);
  	if (!ibft_kobj)
  		return -ENOMEM;
  
  	ibft_kobj->header = header;
  	ibft_kobj->hdr = hdr;
  
  	switch (hdr->id) {
  	case id_initiator:
  		rc = ibft_verify_hdr("initiator", hdr, id_initiator,
  				     sizeof(*ibft_kobj->initiator));
b33a84a38   Mike Christie   ibft: convert isc...
648
649
650
651
652
653
  		if (rc)
  			break;
  
  		boot_kobj = iscsi_boot_create_initiator(boot_kset, hdr->index,
  						ibft_kobj,
  						ibft_attr_show_initiator,
f457a46f1   Mike Christie   [SCSI] iscsi_ibft...
654
655
  						ibft_check_initiator_for,
  						ibft_kobj_release);
b33a84a38   Mike Christie   ibft: convert isc...
656
657
658
659
  		if (!boot_kobj) {
  			rc = -ENOMEM;
  			goto free_ibft_obj;
  		}
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
660
661
662
663
  		break;
  	case id_nic:
  		rc = ibft_verify_hdr("ethernet", hdr, id_nic,
  				     sizeof(*ibft_kobj->nic));
b33a84a38   Mike Christie   ibft: convert isc...
664
665
666
667
668
669
  		if (rc)
  			break;
  
  		boot_kobj = iscsi_boot_create_ethernet(boot_kset, hdr->index,
  						       ibft_kobj,
  						       ibft_attr_show_nic,
f457a46f1   Mike Christie   [SCSI] iscsi_ibft...
670
671
  						       ibft_check_nic_for,
  						       ibft_kobj_release);
b33a84a38   Mike Christie   ibft: convert isc...
672
673
674
675
  		if (!boot_kobj) {
  			rc = -ENOMEM;
  			goto free_ibft_obj;
  		}
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
676
677
678
679
  		break;
  	case id_target:
  		rc = ibft_verify_hdr("target", hdr, id_target,
  				     sizeof(*ibft_kobj->tgt));
b33a84a38   Mike Christie   ibft: convert isc...
680
681
682
683
684
685
  		if (rc)
  			break;
  
  		boot_kobj = iscsi_boot_create_target(boot_kset, hdr->index,
  						     ibft_kobj,
  						     ibft_attr_show_target,
f457a46f1   Mike Christie   [SCSI] iscsi_ibft...
686
687
  						     ibft_check_tgt_for,
  						     ibft_kobj_release);
b33a84a38   Mike Christie   ibft: convert isc...
688
689
690
691
  		if (!boot_kobj) {
  			rc = -ENOMEM;
  			goto free_ibft_obj;
  		}
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
692
693
694
695
696
697
698
699
700
701
702
  		break;
  	case id_reserved:
  	case id_control:
  	case id_extensions:
  		/* Fields which we don't support. Ignore them */
  		rc = 1;
  		break;
  	default:
  		printk(KERN_ERR "iBFT has unknown structure type (%d). " \
  				"Report this bug to %.6s!
  ", hdr->id,
4e639fdf0   Peter Jones   ibft: Update iBFT...
703
  				header->header.oem_id);
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
704
705
706
707
708
709
  		rc = 1;
  		break;
  	}
  
  	if (rc) {
  		/* Skip adding this kobject, but exit with non-fatal error. */
b33a84a38   Mike Christie   ibft: convert isc...
710
711
  		rc = 0;
  		goto free_ibft_obj;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
712
  	}
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
713
714
715
716
717
718
719
  	if (hdr->id == id_nic) {
  		/*
  		* We don't search for the device in other domains than
  		* zero. This is because on x86 platforms the BIOS
  		* executes only devices which are in domain 0. Furthermore, the
  		* iBFT spec doesn't have a domain id field :-(
  		*/
cb5264be3   Sinan Kaya   ibft: Deprecate p...
720
721
722
  		pci_dev = pci_get_domain_bus_and_slot(0,
  						(nic->pci_bdf & 0xff00) >> 8,
  						(nic->pci_bdf & 0xff));
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
723
  		if (pci_dev) {
b33a84a38   Mike Christie   ibft: convert isc...
724
  			rc = sysfs_create_link(&boot_kobj->kobj,
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
725
726
727
728
  					       &pci_dev->dev.kobj, "device");
  			pci_dev_put(pci_dev);
  		}
  	}
b33a84a38   Mike Christie   ibft: convert isc...
729
  	return 0;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
730

b33a84a38   Mike Christie   ibft: convert isc...
731
732
  free_ibft_obj:
  	kfree(ibft_kobj);
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
733
  	return rc;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
734
735
736
737
738
739
740
  }
  
  /*
   * Scan the IBFT table structure for the NIC and Target fields. When
   * found add them on the passed-in list. We do not support the other
   * fields at this point, so they are skipped.
   */
b33a84a38   Mike Christie   ibft: convert isc...
741
  static int __init ibft_register_kobjects(struct acpi_table_ibft *header)
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
742
743
  {
  	struct ibft_control *control = NULL;
b3c8eb503   David Bond   ibft: Expose iBFT...
744
745
  	struct iscsi_boot_kobj *boot_kobj;
  	struct ibft_kobject *ibft_kobj;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
746
747
748
749
750
751
752
  	void *ptr, *end;
  	int rc = 0;
  	u16 offset;
  	u16 eot_offset;
  
  	control = (void *)header + sizeof(*header);
  	end = (void *)control + control->hdr.length;
4e639fdf0   Peter Jones   ibft: Update iBFT...
753
  	eot_offset = (void *)header + header->header.length - (void *)control;
c08406033   Lubomir Rintel   iscsi_ibft: Don't...
754
  	rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control, 0);
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
755
756
757
  
  	/* iBFT table safety checking */
  	rc |= ((control->hdr.index) ? -ENODEV : 0);
c08406033   Lubomir Rintel   iscsi_ibft: Don't...
758
  	rc |= ((control->hdr.length < sizeof(*control)) ? -ENODEV : 0);
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
759
760
761
762
763
  	if (rc) {
  		printk(KERN_ERR "iBFT error: Control header is invalid!
  ");
  		return rc;
  	}
c08406033   Lubomir Rintel   iscsi_ibft: Don't...
764
  	for (ptr = &control->initiator_off; ptr + sizeof(u16) <= end; ptr += sizeof(u16)) {
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
765
  		offset = *(u16 *)ptr;
4e639fdf0   Peter Jones   ibft: Update iBFT...
766
767
  		if (offset && offset < header->header.length &&
  						offset < eot_offset) {
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
768
  			rc = ibft_create_kobject(header,
b33a84a38   Mike Christie   ibft: convert isc...
769
  						 (void *)header + offset);
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
770
771
772
773
  			if (rc)
  				break;
  		}
  	}
b3c8eb503   David Bond   ibft: Expose iBFT...
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
  	if (rc)
  		return rc;
  
  	ibft_kobj = kzalloc(sizeof(*ibft_kobj), GFP_KERNEL);
  	if (!ibft_kobj)
  		return -ENOMEM;
  
  	ibft_kobj->header = header;
  	ibft_kobj->hdr = NULL; /*for ibft_unregister*/
  
  	boot_kobj = iscsi_boot_create_acpitbl(boot_kset, 0,
  					ibft_kobj,
  					ibft_attr_show_acpitbl,
  					ibft_check_acpitbl_for,
  					ibft_kobj_release);
  	if (!boot_kobj)  {
  		kfree(ibft_kobj);
  		rc = -ENOMEM;
  	}
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
793
794
795
  
  	return rc;
  }
b33a84a38   Mike Christie   ibft: convert isc...
796
  static void ibft_unregister(void)
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
797
  {
b33a84a38   Mike Christie   ibft: convert isc...
798
799
800
801
802
803
  	struct iscsi_boot_kobj *boot_kobj, *tmp_kobj;
  	struct ibft_kobject *ibft_kobj;
  
  	list_for_each_entry_safe(boot_kobj, tmp_kobj,
  				 &boot_kset->kobj_list, list) {
  		ibft_kobj = boot_kobj->data;
b3c8eb503   David Bond   ibft: Expose iBFT...
804
  		if (ibft_kobj->hdr && ibft_kobj->hdr->id == id_nic)
b33a84a38   Mike Christie   ibft: convert isc...
805
  			sysfs_remove_link(&boot_kobj->kobj, "device");
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
806
  	};
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
807
  }
b33a84a38   Mike Christie   ibft: convert isc...
808
  static void ibft_cleanup(void)
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
809
  {
a12415ff5   Konrad Rzeszutek Wilk   ibft: Kernel oops...
810
811
812
813
  	if (boot_kset) {
  		ibft_unregister();
  		iscsi_boot_destroy_kset(boot_kset);
  	}
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
814
  }
b33a84a38   Mike Christie   ibft: convert isc...
815
  static void __exit ibft_exit(void)
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
816
  {
b33a84a38   Mike Christie   ibft: convert isc...
817
  	ibft_cleanup();
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
818
  }
935a9fee5   Yinghai Lu   ibft: Fix finding...
819
820
821
822
823
824
825
826
827
828
  #ifdef CONFIG_ACPI
  static const struct {
  	char *sign;
  } ibft_signs[] = {
  	/*
  	 * One spec says "IBFT", the other says "iBFT". We have to check
  	 * for both.
  	 */
  	{ ACPI_SIG_IBFT },
  	{ "iBFT" },
629c27aa0   Vikas Chaudhary   iscsi_ibft: Fix f...
829
  	{ "BIFT" },	/* Broadcom iSCSI Offload */
935a9fee5   Yinghai Lu   ibft: Fix finding...
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
  };
  
  static void __init acpi_find_ibft_region(void)
  {
  	int i;
  	struct acpi_table_header *table = NULL;
  
  	if (acpi_disabled)
  		return;
  
  	for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
  		acpi_get_table(ibft_signs[i].sign, 0, &table);
  		ibft_addr = (struct acpi_table_ibft *)table;
  	}
  }
  #else
  static void __init acpi_find_ibft_region(void)
  {
  }
  #endif
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
850
851
852
853
854
855
  /*
   * ibft_init() - creates sysfs tree entries for the iBFT data.
   */
  static int __init ibft_init(void)
  {
  	int rc = 0;
935a9fee5   Yinghai Lu   ibft: Fix finding...
856
857
858
859
860
861
862
  	/*
  	   As on UEFI systems the setup_arch()/find_ibft_region()
  	   is called before ACPI tables are parsed and it only does
  	   legacy finding.
  	*/
  	if (!ibft_addr)
  		acpi_find_ibft_region();
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
863
  	if (ibft_addr) {
935a9fee5   Yinghai Lu   ibft: Fix finding...
864
865
  		pr_info("iBFT detected.
  ");
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
866
867
868
  
  		rc = ibft_check_device();
  		if (rc)
b33a84a38   Mike Christie   ibft: convert isc...
869
  			return rc;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
870

b33a84a38   Mike Christie   ibft: convert isc...
871
872
873
  		boot_kset = iscsi_boot_create_kset("ibft");
  		if (!boot_kset)
  			return -ENOMEM;
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
874

b33a84a38   Mike Christie   ibft: convert isc...
875
876
  		/* Scan the IBFT for data and register the kobjects. */
  		rc = ibft_register_kobjects(ibft_addr);
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
877
878
879
880
881
882
883
884
885
  		if (rc)
  			goto out_free;
  	} else
  		printk(KERN_INFO "No iBFT detected.
  ");
  
  	return 0;
  
  out_free:
b33a84a38   Mike Christie   ibft: convert isc...
886
  	ibft_cleanup();
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
887
888
  	return rc;
  }
138fe4e06   Konrad Rzeszutek   Firmware: add iSC...
889
890
  module_init(ibft_init);
  module_exit(ibft_exit);