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