612a59e213df0532971dcaff1461ff9f80770cae
[linux-2.6-microblaze.git] / drivers / firmware / iscsi_ibft.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  Copyright 2007-2010 Red Hat, Inc.
4  *  by Peter Jones <pjones@redhat.com>
5  *  Copyright 2008 IBM, Inc.
6  *  by Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
7  *  Copyright 2008
8  *  by Konrad Rzeszutek <ketuzsezr@darnok.org>
9  *
10  * This code exposes the iSCSI Boot Format Table to userland via sysfs.
11  *
12  * Changelog:
13  *
14  *  06 Jan 2010 - Peter Jones <pjones@redhat.com>
15  *    New changelog entries are in the git log from now on.  Not here.
16  *
17  *  14 Mar 2008 - Konrad Rzeszutek <ketuzsezr@darnok.org>
18  *    Updated comments and copyrights. (v0.4.9)
19  *
20  *  11 Feb 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
21  *    Converted to using ibft_addr. (v0.4.8)
22  *
23  *   8 Feb 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
24  *    Combined two functions in one: reserve_ibft_region. (v0.4.7)
25  *
26  *  30 Jan 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
27  *   Added logic to handle IPv6 addresses. (v0.4.6)
28  *
29  *  25 Jan 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
30  *   Added logic to handle badly not-to-spec iBFT. (v0.4.5)
31  *
32  *   4 Jan 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
33  *   Added __init to function declarations. (v0.4.4)
34  *
35  *  21 Dec 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
36  *   Updated kobject registration, combined unregister functions in one
37  *   and code and style cleanup. (v0.4.3)
38  *
39  *   5 Dec 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
40  *   Added end-markers to enums and re-organized kobject registration. (v0.4.2)
41  *
42  *   4 Dec 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
43  *   Created 'device' sysfs link to the NIC and style cleanup. (v0.4.1)
44  *
45  *  28 Nov 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
46  *   Added sysfs-ibft documentation, moved 'find_ibft' function to
47  *   in its own file and added text attributes for every struct field.  (v0.4)
48  *
49  *  21 Nov 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
50  *   Added text attributes emulating OpenFirmware /proc/device-tree naming.
51  *   Removed binary /sysfs interface (v0.3)
52  *
53  *  29 Aug 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
54  *   Added functionality in setup.c to reserve iBFT region. (v0.2)
55  *
56  *  27 Aug 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
57  *   First version exposing iBFT data via a binary /sysfs. (v0.1)
58  */
59
60
61 #include <linux/blkdev.h>
62 #include <linux/capability.h>
63 #include <linux/ctype.h>
64 #include <linux/device.h>
65 #include <linux/err.h>
66 #include <linux/init.h>
67 #include <linux/iscsi_ibft.h>
68 #include <linux/limits.h>
69 #include <linux/module.h>
70 #include <linux/pci.h>
71 #include <linux/slab.h>
72 #include <linux/stat.h>
73 #include <linux/string.h>
74 #include <linux/types.h>
75 #include <linux/acpi.h>
76 #include <linux/iscsi_boot_sysfs.h>
77
78 #define IBFT_ISCSI_VERSION "0.5.0"
79 #define IBFT_ISCSI_DATE "2010-Feb-25"
80
81 MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and "
82               "Konrad Rzeszutek <ketuzsezr@darnok.org>");
83 MODULE_DESCRIPTION("sysfs interface to BIOS iBFT information");
84 MODULE_LICENSE("GPL");
85 MODULE_VERSION(IBFT_ISCSI_VERSION);
86
87 static struct acpi_table_ibft *ibft_addr;
88
89 #ifndef CONFIG_ISCSI_IBFT_FIND
90 phys_addr_t ibft_phys_addr;
91 #endif
92
93 struct ibft_hdr {
94         u8 id;
95         u8 version;
96         u16 length;
97         u8 index;
98         u8 flags;
99 } __attribute__((__packed__));
100
101 struct ibft_control {
102         struct ibft_hdr hdr;
103         u16 extensions;
104         u16 initiator_off;
105         u16 nic0_off;
106         u16 tgt0_off;
107         u16 nic1_off;
108         u16 tgt1_off;
109         u16 expansion[];
110 } __attribute__((__packed__));
111
112 struct ibft_initiator {
113         struct ibft_hdr hdr;
114         char isns_server[16];
115         char slp_server[16];
116         char pri_radius_server[16];
117         char sec_radius_server[16];
118         u16 initiator_name_len;
119         u16 initiator_name_off;
120 } __attribute__((__packed__));
121
122 struct ibft_nic {
123         struct ibft_hdr hdr;
124         char ip_addr[16];
125         u8 subnet_mask_prefix;
126         u8 origin;
127         char gateway[16];
128         char primary_dns[16];
129         char secondary_dns[16];
130         char dhcp[16];
131         u16 vlan;
132         char mac[6];
133         u16 pci_bdf;
134         u16 hostname_len;
135         u16 hostname_off;
136 } __attribute__((__packed__));
137
138 struct ibft_tgt {
139         struct ibft_hdr hdr;
140         char ip_addr[16];
141         u16 port;
142         char lun[8];
143         u8 chap_type;
144         u8 nic_assoc;
145         u16 tgt_name_len;
146         u16 tgt_name_off;
147         u16 chap_name_len;
148         u16 chap_name_off;
149         u16 chap_secret_len;
150         u16 chap_secret_off;
151         u16 rev_chap_name_len;
152         u16 rev_chap_name_off;
153         u16 rev_chap_secret_len;
154         u16 rev_chap_secret_off;
155 } __attribute__((__packed__));
156
157 /*
158  * The kobject different types and its names.
159  *
160 */
161 enum ibft_id {
162         id_reserved = 0, /* We don't support. */
163         id_control = 1, /* Should show up only once and is not exported. */
164         id_initiator = 2,
165         id_nic = 3,
166         id_target = 4,
167         id_extensions = 5, /* We don't support. */
168         id_end_marker,
169 };
170
171 /*
172  * The kobject and attribute structures.
173  */
174
175 struct ibft_kobject {
176         struct acpi_table_ibft *header;
177         union {
178                 struct ibft_initiator *initiator;
179                 struct ibft_nic *nic;
180                 struct ibft_tgt *tgt;
181                 struct ibft_hdr *hdr;
182         };
183 };
184
185 static struct iscsi_boot_kset *boot_kset;
186
187 /* fully null address */
188 static const char nulls[16];
189
190 /* IPv4-mapped IPv6 ::ffff:0.0.0.0 */
191 static const char mapped_nulls[16] = { 0x00, 0x00, 0x00, 0x00,
192                                        0x00, 0x00, 0x00, 0x00,
193                                        0x00, 0x00, 0xff, 0xff,
194                                        0x00, 0x00, 0x00, 0x00 };
195
196 static int address_not_null(u8 *ip)
197 {
198         return (memcmp(ip, nulls, 16) && memcmp(ip, mapped_nulls, 16));
199 }
200
201 /*
202  * Helper functions to parse data properly.
203  */
204 static ssize_t sprintf_ipaddr(char *buf, u8 *ip)
205 {
206         char *str = buf;
207
208         if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0 &&
209             ip[4] == 0 && ip[5] == 0 && ip[6] == 0 && ip[7] == 0 &&
210             ip[8] == 0 && ip[9] == 0 && ip[10] == 0xff && ip[11] == 0xff) {
211                 /*
212                  * IPV4
213                  */
214                 str += sprintf(buf, "%pI4", ip + 12);
215         } else {
216                 /*
217                  * IPv6
218                  */
219                 str += sprintf(str, "%pI6", ip);
220         }
221         str += sprintf(str, "\n");
222         return str - buf;
223 }
224
225 static ssize_t sprintf_string(char *str, int len, char *buf)
226 {
227         return sprintf(str, "%.*s\n", len, buf);
228 }
229
230 /*
231  * Helper function to verify the IBFT header.
232  */
233 static int ibft_verify_hdr(char *t, struct ibft_hdr *hdr, int id, int length)
234 {
235         if (hdr->id != id) {
236                 printk(KERN_ERR "iBFT error: We expected the %s " \
237                                 "field header.id to have %d but " \
238                                 "found %d instead!\n", t, id, hdr->id);
239                 return -ENODEV;
240         }
241         if (length && hdr->length != length) {
242                 printk(KERN_ERR "iBFT error: We expected the %s " \
243                                 "field header.length to have %d but " \
244                                 "found %d instead!\n", t, length, hdr->length);
245                 return -ENODEV;
246         }
247
248         return 0;
249 }
250
251 /*
252  *  Routines for parsing the iBFT data to be human readable.
253  */
254 static ssize_t ibft_attr_show_initiator(void *data, int type, char *buf)
255 {
256         struct ibft_kobject *entry = data;
257         struct ibft_initiator *initiator = entry->initiator;
258         void *ibft_loc = entry->header;
259         char *str = buf;
260
261         if (!initiator)
262                 return 0;
263
264         switch (type) {
265         case ISCSI_BOOT_INI_INDEX:
266                 str += sprintf(str, "%d\n", initiator->hdr.index);
267                 break;
268         case ISCSI_BOOT_INI_FLAGS:
269                 str += sprintf(str, "%d\n", initiator->hdr.flags);
270                 break;
271         case ISCSI_BOOT_INI_ISNS_SERVER:
272                 str += sprintf_ipaddr(str, initiator->isns_server);
273                 break;
274         case ISCSI_BOOT_INI_SLP_SERVER:
275                 str += sprintf_ipaddr(str, initiator->slp_server);
276                 break;
277         case ISCSI_BOOT_INI_PRI_RADIUS_SERVER:
278                 str += sprintf_ipaddr(str, initiator->pri_radius_server);
279                 break;
280         case ISCSI_BOOT_INI_SEC_RADIUS_SERVER:
281                 str += sprintf_ipaddr(str, initiator->sec_radius_server);
282                 break;
283         case ISCSI_BOOT_INI_INITIATOR_NAME:
284                 str += sprintf_string(str, initiator->initiator_name_len,
285                                       (char *)ibft_loc +
286                                       initiator->initiator_name_off);
287                 break;
288         default:
289                 break;
290         }
291
292         return str - buf;
293 }
294
295 static ssize_t ibft_attr_show_nic(void *data, int type, char *buf)
296 {
297         struct ibft_kobject *entry = data;
298         struct ibft_nic *nic = entry->nic;
299         void *ibft_loc = entry->header;
300         char *str = buf;
301         __be32 val;
302
303         if (!nic)
304                 return 0;
305
306         switch (type) {
307         case ISCSI_BOOT_ETH_INDEX:
308                 str += sprintf(str, "%d\n", nic->hdr.index);
309                 break;
310         case ISCSI_BOOT_ETH_FLAGS:
311                 str += sprintf(str, "%d\n", nic->hdr.flags);
312                 break;
313         case ISCSI_BOOT_ETH_IP_ADDR:
314                 str += sprintf_ipaddr(str, nic->ip_addr);
315                 break;
316         case ISCSI_BOOT_ETH_SUBNET_MASK:
317                 val = cpu_to_be32(~((1 << (32-nic->subnet_mask_prefix))-1));
318                 str += sprintf(str, "%pI4", &val);
319                 break;
320         case ISCSI_BOOT_ETH_PREFIX_LEN:
321                 str += sprintf(str, "%d\n", nic->subnet_mask_prefix);
322                 break;
323         case ISCSI_BOOT_ETH_ORIGIN:
324                 str += sprintf(str, "%d\n", nic->origin);
325                 break;
326         case ISCSI_BOOT_ETH_GATEWAY:
327                 str += sprintf_ipaddr(str, nic->gateway);
328                 break;
329         case ISCSI_BOOT_ETH_PRIMARY_DNS:
330                 str += sprintf_ipaddr(str, nic->primary_dns);
331                 break;
332         case ISCSI_BOOT_ETH_SECONDARY_DNS:
333                 str += sprintf_ipaddr(str, nic->secondary_dns);
334                 break;
335         case ISCSI_BOOT_ETH_DHCP:
336                 str += sprintf_ipaddr(str, nic->dhcp);
337                 break;
338         case ISCSI_BOOT_ETH_VLAN:
339                 str += sprintf(str, "%d\n", nic->vlan);
340                 break;
341         case ISCSI_BOOT_ETH_MAC:
342                 str += sprintf(str, "%pM\n", nic->mac);
343                 break;
344         case ISCSI_BOOT_ETH_HOSTNAME:
345                 str += sprintf_string(str, nic->hostname_len,
346                                       (char *)ibft_loc + nic->hostname_off);
347                 break;
348         default:
349                 break;
350         }
351
352         return str - buf;
353 };
354
355 static ssize_t ibft_attr_show_target(void *data, int type, char *buf)
356 {
357         struct ibft_kobject *entry = data;
358         struct ibft_tgt *tgt = entry->tgt;
359         void *ibft_loc = entry->header;
360         char *str = buf;
361         int i;
362
363         if (!tgt)
364                 return 0;
365
366         switch (type) {
367         case ISCSI_BOOT_TGT_INDEX:
368                 str += sprintf(str, "%d\n", tgt->hdr.index);
369                 break;
370         case ISCSI_BOOT_TGT_FLAGS:
371                 str += sprintf(str, "%d\n", tgt->hdr.flags);
372                 break;
373         case ISCSI_BOOT_TGT_IP_ADDR:
374                 str += sprintf_ipaddr(str, tgt->ip_addr);
375                 break;
376         case ISCSI_BOOT_TGT_PORT:
377                 str += sprintf(str, "%d\n", tgt->port);
378                 break;
379         case ISCSI_BOOT_TGT_LUN:
380                 for (i = 0; i < 8; i++)
381                         str += sprintf(str, "%x", (u8)tgt->lun[i]);
382                 str += sprintf(str, "\n");
383                 break;
384         case ISCSI_BOOT_TGT_NIC_ASSOC:
385                 str += sprintf(str, "%d\n", tgt->nic_assoc);
386                 break;
387         case ISCSI_BOOT_TGT_CHAP_TYPE:
388                 str += sprintf(str, "%d\n", tgt->chap_type);
389                 break;
390         case ISCSI_BOOT_TGT_NAME:
391                 str += sprintf_string(str, tgt->tgt_name_len,
392                                       (char *)ibft_loc + tgt->tgt_name_off);
393                 break;
394         case ISCSI_BOOT_TGT_CHAP_NAME:
395                 str += sprintf_string(str, tgt->chap_name_len,
396                                       (char *)ibft_loc + tgt->chap_name_off);
397                 break;
398         case ISCSI_BOOT_TGT_CHAP_SECRET:
399                 str += sprintf_string(str, tgt->chap_secret_len,
400                                       (char *)ibft_loc + tgt->chap_secret_off);
401                 break;
402         case ISCSI_BOOT_TGT_REV_CHAP_NAME:
403                 str += sprintf_string(str, tgt->rev_chap_name_len,
404                                       (char *)ibft_loc +
405                                       tgt->rev_chap_name_off);
406                 break;
407         case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
408                 str += sprintf_string(str, tgt->rev_chap_secret_len,
409                                       (char *)ibft_loc +
410                                       tgt->rev_chap_secret_off);
411                 break;
412         default:
413                 break;
414         }
415
416         return str - buf;
417 }
418
419 static ssize_t ibft_attr_show_acpitbl(void *data, int type, char *buf)
420 {
421         struct ibft_kobject *entry = data;
422         char *str = buf;
423
424         switch (type) {
425         case ISCSI_BOOT_ACPITBL_SIGNATURE:
426                 str += sprintf_string(str, ACPI_NAMESEG_SIZE,
427                                       entry->header->header.signature);
428                 break;
429         case ISCSI_BOOT_ACPITBL_OEM_ID:
430                 str += sprintf_string(str, ACPI_OEM_ID_SIZE,
431                                       entry->header->header.oem_id);
432                 break;
433         case ISCSI_BOOT_ACPITBL_OEM_TABLE_ID:
434                 str += sprintf_string(str, ACPI_OEM_TABLE_ID_SIZE,
435                                       entry->header->header.oem_table_id);
436                 break;
437         default:
438                 break;
439         }
440
441         return str - buf;
442 }
443
444 static int __init ibft_check_device(void)
445 {
446         int len;
447         u8 *pos;
448         u8 csum = 0;
449
450         len = ibft_addr->header.length;
451
452         /* Sanity checking of iBFT. */
453         if (ibft_addr->header.revision != 1) {
454                 printk(KERN_ERR "iBFT module supports only revision 1, " \
455                                 "while this is %d.\n",
456                                 ibft_addr->header.revision);
457                 return -ENOENT;
458         }
459         for (pos = (u8 *)ibft_addr; pos < (u8 *)ibft_addr + len; pos++)
460                 csum += *pos;
461
462         if (csum) {
463                 printk(KERN_ERR "iBFT has incorrect checksum (0x%x)!\n", csum);
464                 return -ENOENT;
465         }
466
467         return 0;
468 }
469
470 /*
471  * Helper routiners to check to determine if the entry is valid
472  * in the proper iBFT structure.
473  */
474 static umode_t ibft_check_nic_for(void *data, int type)
475 {
476         struct ibft_kobject *entry = data;
477         struct ibft_nic *nic = entry->nic;
478         umode_t rc = 0;
479
480         switch (type) {
481         case ISCSI_BOOT_ETH_INDEX:
482         case ISCSI_BOOT_ETH_FLAGS:
483                 rc = S_IRUGO;
484                 break;
485         case ISCSI_BOOT_ETH_IP_ADDR:
486                 if (address_not_null(nic->ip_addr))
487                         rc = S_IRUGO;
488                 break;
489         case ISCSI_BOOT_ETH_PREFIX_LEN:
490         case ISCSI_BOOT_ETH_SUBNET_MASK:
491                 if (nic->subnet_mask_prefix)
492                         rc = S_IRUGO;
493                 break;
494         case ISCSI_BOOT_ETH_ORIGIN:
495                 rc = S_IRUGO;
496                 break;
497         case ISCSI_BOOT_ETH_GATEWAY:
498                 if (address_not_null(nic->gateway))
499                         rc = S_IRUGO;
500                 break;
501         case ISCSI_BOOT_ETH_PRIMARY_DNS:
502                 if (address_not_null(nic->primary_dns))
503                         rc = S_IRUGO;
504                 break;
505         case ISCSI_BOOT_ETH_SECONDARY_DNS:
506                 if (address_not_null(nic->secondary_dns))
507                         rc = S_IRUGO;
508                 break;
509         case ISCSI_BOOT_ETH_DHCP:
510                 if (address_not_null(nic->dhcp))
511                         rc = S_IRUGO;
512                 break;
513         case ISCSI_BOOT_ETH_VLAN:
514         case ISCSI_BOOT_ETH_MAC:
515                 rc = S_IRUGO;
516                 break;
517         case ISCSI_BOOT_ETH_HOSTNAME:
518                 if (nic->hostname_off)
519                         rc = S_IRUGO;
520                 break;
521         default:
522                 break;
523         }
524
525         return rc;
526 }
527
528 static umode_t __init ibft_check_tgt_for(void *data, int type)
529 {
530         struct ibft_kobject *entry = data;
531         struct ibft_tgt *tgt = entry->tgt;
532         umode_t rc = 0;
533
534         switch (type) {
535         case ISCSI_BOOT_TGT_INDEX:
536         case ISCSI_BOOT_TGT_FLAGS:
537         case ISCSI_BOOT_TGT_IP_ADDR:
538         case ISCSI_BOOT_TGT_PORT:
539         case ISCSI_BOOT_TGT_LUN:
540         case ISCSI_BOOT_TGT_NIC_ASSOC:
541         case ISCSI_BOOT_TGT_CHAP_TYPE:
542                 rc = S_IRUGO;
543                 break;
544         case ISCSI_BOOT_TGT_NAME:
545                 if (tgt->tgt_name_len)
546                         rc = S_IRUGO;
547                 break;
548         case ISCSI_BOOT_TGT_CHAP_NAME:
549         case ISCSI_BOOT_TGT_CHAP_SECRET:
550                 if (tgt->chap_name_len)
551                         rc = S_IRUGO;
552                 break;
553         case ISCSI_BOOT_TGT_REV_CHAP_NAME:
554         case ISCSI_BOOT_TGT_REV_CHAP_SECRET:
555                 if (tgt->rev_chap_name_len)
556                         rc = S_IRUGO;
557                 break;
558         default:
559                 break;
560         }
561
562         return rc;
563 }
564
565 static umode_t __init ibft_check_initiator_for(void *data, int type)
566 {
567         struct ibft_kobject *entry = data;
568         struct ibft_initiator *init = entry->initiator;
569         umode_t rc = 0;
570
571         switch (type) {
572         case ISCSI_BOOT_INI_INDEX:
573         case ISCSI_BOOT_INI_FLAGS:
574                 rc = S_IRUGO;
575                 break;
576         case ISCSI_BOOT_INI_ISNS_SERVER:
577                 if (address_not_null(init->isns_server))
578                         rc = S_IRUGO;
579                 break;
580         case ISCSI_BOOT_INI_SLP_SERVER:
581                 if (address_not_null(init->slp_server))
582                         rc = S_IRUGO;
583                 break;
584         case ISCSI_BOOT_INI_PRI_RADIUS_SERVER:
585                 if (address_not_null(init->pri_radius_server))
586                         rc = S_IRUGO;
587                 break;
588         case ISCSI_BOOT_INI_SEC_RADIUS_SERVER:
589                 if (address_not_null(init->sec_radius_server))
590                         rc = S_IRUGO;
591                 break;
592         case ISCSI_BOOT_INI_INITIATOR_NAME:
593                 if (init->initiator_name_len)
594                         rc = S_IRUGO;
595                 break;
596         default:
597                 break;
598         }
599
600         return rc;
601 }
602
603 static umode_t __init ibft_check_acpitbl_for(void *data, int type)
604 {
605
606         umode_t rc = 0;
607
608         switch (type) {
609         case ISCSI_BOOT_ACPITBL_SIGNATURE:
610         case ISCSI_BOOT_ACPITBL_OEM_ID:
611         case ISCSI_BOOT_ACPITBL_OEM_TABLE_ID:
612                 rc = S_IRUGO;
613                 break;
614         default:
615                 break;
616         }
617
618         return rc;
619 }
620
621 static void ibft_kobj_release(void *data)
622 {
623         kfree(data);
624 }
625
626 /*
627  * Helper function for ibft_register_kobjects.
628  */
629 static int __init ibft_create_kobject(struct acpi_table_ibft *header,
630                                       struct ibft_hdr *hdr)
631 {
632         struct iscsi_boot_kobj *boot_kobj = NULL;
633         struct ibft_kobject *ibft_kobj = NULL;
634         struct ibft_nic *nic = (struct ibft_nic *)hdr;
635         struct pci_dev *pci_dev;
636         int rc = 0;
637
638         ibft_kobj = kzalloc(sizeof(*ibft_kobj), GFP_KERNEL);
639         if (!ibft_kobj)
640                 return -ENOMEM;
641
642         ibft_kobj->header = header;
643         ibft_kobj->hdr = hdr;
644
645         switch (hdr->id) {
646         case id_initiator:
647                 rc = ibft_verify_hdr("initiator", hdr, id_initiator,
648                                      sizeof(*ibft_kobj->initiator));
649                 if (rc)
650                         break;
651
652                 boot_kobj = iscsi_boot_create_initiator(boot_kset, hdr->index,
653                                                 ibft_kobj,
654                                                 ibft_attr_show_initiator,
655                                                 ibft_check_initiator_for,
656                                                 ibft_kobj_release);
657                 if (!boot_kobj) {
658                         rc = -ENOMEM;
659                         goto free_ibft_obj;
660                 }
661                 break;
662         case id_nic:
663                 rc = ibft_verify_hdr("ethernet", hdr, id_nic,
664                                      sizeof(*ibft_kobj->nic));
665                 if (rc)
666                         break;
667
668                 boot_kobj = iscsi_boot_create_ethernet(boot_kset, hdr->index,
669                                                        ibft_kobj,
670                                                        ibft_attr_show_nic,
671                                                        ibft_check_nic_for,
672                                                        ibft_kobj_release);
673                 if (!boot_kobj) {
674                         rc = -ENOMEM;
675                         goto free_ibft_obj;
676                 }
677                 break;
678         case id_target:
679                 rc = ibft_verify_hdr("target", hdr, id_target,
680                                      sizeof(*ibft_kobj->tgt));
681                 if (rc)
682                         break;
683
684                 boot_kobj = iscsi_boot_create_target(boot_kset, hdr->index,
685                                                      ibft_kobj,
686                                                      ibft_attr_show_target,
687                                                      ibft_check_tgt_for,
688                                                      ibft_kobj_release);
689                 if (!boot_kobj) {
690                         rc = -ENOMEM;
691                         goto free_ibft_obj;
692                 }
693                 break;
694         case id_reserved:
695         case id_control:
696         case id_extensions:
697                 /* Fields which we don't support. Ignore them */
698                 rc = 1;
699                 break;
700         default:
701                 printk(KERN_ERR "iBFT has unknown structure type (%d). " \
702                                 "Report this bug to %.6s!\n", hdr->id,
703                                 header->header.oem_id);
704                 rc = 1;
705                 break;
706         }
707
708         if (rc) {
709                 /* Skip adding this kobject, but exit with non-fatal error. */
710                 rc = 0;
711                 goto free_ibft_obj;
712         }
713
714         if (hdr->id == id_nic) {
715                 /*
716                 * We don't search for the device in other domains than
717                 * zero. This is because on x86 platforms the BIOS
718                 * executes only devices which are in domain 0. Furthermore, the
719                 * iBFT spec doesn't have a domain id field :-(
720                 */
721                 pci_dev = pci_get_domain_bus_and_slot(0,
722                                                 (nic->pci_bdf & 0xff00) >> 8,
723                                                 (nic->pci_bdf & 0xff));
724                 if (pci_dev) {
725                         rc = sysfs_create_link(&boot_kobj->kobj,
726                                                &pci_dev->dev.kobj, "device");
727                         pci_dev_put(pci_dev);
728                 }
729         }
730         return 0;
731
732 free_ibft_obj:
733         kfree(ibft_kobj);
734         return rc;
735 }
736
737 /*
738  * Scan the IBFT table structure for the NIC and Target fields. When
739  * found add them on the passed-in list. We do not support the other
740  * fields at this point, so they are skipped.
741  */
742 static int __init ibft_register_kobjects(struct acpi_table_ibft *header)
743 {
744         struct ibft_control *control = NULL;
745         struct iscsi_boot_kobj *boot_kobj;
746         struct ibft_kobject *ibft_kobj;
747         void *ptr, *end;
748         int rc = 0;
749         u16 offset;
750         u16 eot_offset;
751
752         control = (void *)header + sizeof(*header);
753         end = (void *)control + control->hdr.length;
754         eot_offset = (void *)header + header->header.length - (void *)control;
755         rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control, 0);
756
757         /* iBFT table safety checking */
758         rc |= ((control->hdr.index) ? -ENODEV : 0);
759         rc |= ((control->hdr.length < sizeof(*control)) ? -ENODEV : 0);
760         if (rc) {
761                 printk(KERN_ERR "iBFT error: Control header is invalid!\n");
762                 return rc;
763         }
764         for (ptr = &control->initiator_off; ptr + sizeof(u16) <= end; ptr += sizeof(u16)) {
765                 offset = *(u16 *)ptr;
766                 if (offset && offset < header->header.length &&
767                                                 offset < eot_offset) {
768                         rc = ibft_create_kobject(header,
769                                                  (void *)header + offset);
770                         if (rc)
771                                 break;
772                 }
773         }
774         if (rc)
775                 return rc;
776
777         ibft_kobj = kzalloc(sizeof(*ibft_kobj), GFP_KERNEL);
778         if (!ibft_kobj)
779                 return -ENOMEM;
780
781         ibft_kobj->header = header;
782         ibft_kobj->hdr = NULL; /*for ibft_unregister*/
783
784         boot_kobj = iscsi_boot_create_acpitbl(boot_kset, 0,
785                                         ibft_kobj,
786                                         ibft_attr_show_acpitbl,
787                                         ibft_check_acpitbl_for,
788                                         ibft_kobj_release);
789         if (!boot_kobj)  {
790                 kfree(ibft_kobj);
791                 rc = -ENOMEM;
792         }
793
794         return rc;
795 }
796
797 static void ibft_unregister(void)
798 {
799         struct iscsi_boot_kobj *boot_kobj, *tmp_kobj;
800         struct ibft_kobject *ibft_kobj;
801
802         list_for_each_entry_safe(boot_kobj, tmp_kobj,
803                                  &boot_kset->kobj_list, list) {
804                 ibft_kobj = boot_kobj->data;
805                 if (ibft_kobj->hdr && ibft_kobj->hdr->id == id_nic)
806                         sysfs_remove_link(&boot_kobj->kobj, "device");
807         };
808 }
809
810 static void ibft_cleanup(void)
811 {
812         if (boot_kset) {
813                 ibft_unregister();
814                 iscsi_boot_destroy_kset(boot_kset);
815         }
816 }
817
818 static void __exit ibft_exit(void)
819 {
820         ibft_cleanup();
821 }
822
823 #ifdef CONFIG_ACPI
824 static const struct {
825         char *sign;
826 } ibft_signs[] = {
827         /*
828          * One spec says "IBFT", the other says "iBFT". We have to check
829          * for both.
830          */
831         { ACPI_SIG_IBFT },
832         { "iBFT" },
833         { "BIFT" },     /* Broadcom iSCSI Offload */
834 };
835
836 static void __init acpi_find_ibft_region(void)
837 {
838         int i;
839         struct acpi_table_header *table = NULL;
840
841         if (acpi_disabled)
842                 return;
843
844         for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) {
845                 acpi_get_table(ibft_signs[i].sign, 0, &table);
846                 ibft_addr = (struct acpi_table_ibft *)table;
847         }
848 }
849 #else
850 static void __init acpi_find_ibft_region(void)
851 {
852 }
853 #endif
854
855 /*
856  * ibft_init() - creates sysfs tree entries for the iBFT data.
857  */
858 static int __init ibft_init(void)
859 {
860         int rc = 0;
861
862         /*
863            As on UEFI systems the setup_arch()/reserve_ibft_region()
864            is called before ACPI tables are parsed and it only does
865            legacy finding.
866         */
867         if (ibft_phys_addr)
868                 ibft_addr = isa_bus_to_virt(ibft_phys_addr);
869         else
870                 acpi_find_ibft_region();
871
872         if (ibft_addr) {
873                 pr_info("iBFT detected.\n");
874
875                 rc = ibft_check_device();
876                 if (rc)
877                         return rc;
878
879                 boot_kset = iscsi_boot_create_kset("ibft");
880                 if (!boot_kset)
881                         return -ENOMEM;
882
883                 /* Scan the IBFT for data and register the kobjects. */
884                 rc = ibft_register_kobjects(ibft_addr);
885                 if (rc)
886                         goto out_free;
887         } else
888                 printk(KERN_INFO "No iBFT detected.\n");
889
890         return 0;
891
892 out_free:
893         ibft_cleanup();
894         return rc;
895 }
896
897 module_init(ibft_init);
898 module_exit(ibft_exit);