aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-18 18:30:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-18 18:30:04 -0400
commitd974f09ea4970d0299a8267111312b80adbd20e6 (patch)
tree2b8874872d0fb1fd5e1f5addc343ec29cc98b3cd
parent4a5219edcdae52bfb5eea0dfc2a7bd575961dad7 (diff)
parentb3c8eb50383178f3a4dcf1dc867001156da6473d (diff)
Merge branch 'stable/for-linus-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/ibft
Pull iscsi_ibft updates from Konrad Rzeszutek Wilk: "The pull has two features - both of them expand the SysFS entries: - 'prefix-len' - which is subnet_mask_prefix of the iBFT header. - 'acpi_header' dir with: 'iBFT', OEM-ID (whatever it extracts from the iBFT header) and OEM_TABLE_ID (also whatever it extracts from the iBFT header). This is to help NIC drivers to figure out during bootup how to deal with BIOS created iBFT tables (like by TianoCore UEFI implemenation)" * 'stable/for-linus-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/ibft: ibft: Expose iBFT acpi header via sysfs iscsi_ibft: Add prefix-len attr and display netmask
-rw-r--r--Documentation/ABI/testing/sysfs-ibft10
-rw-r--r--drivers/firmware/iscsi_ibft.c66
-rw-r--r--drivers/scsi/iscsi_boot_sysfs.c62
-rw-r--r--include/linux/iscsi_boot_sysfs.h13
4 files changed, 150 insertions, 1 deletions
diff --git a/Documentation/ABI/testing/sysfs-ibft b/Documentation/ABI/testing/sysfs-ibft
index cac3930bdb04..7d6725fe6143 100644
--- a/Documentation/ABI/testing/sysfs-ibft
+++ b/Documentation/ABI/testing/sysfs-ibft
@@ -21,3 +21,13 @@ Contact: Konrad Rzeszutek <ketuzsezr@darnok.org>
21Description: The /sys/firmware/ibft/ethernetX directory will contain 21Description: The /sys/firmware/ibft/ethernetX directory will contain
22 files that expose the iSCSI Boot Firmware Table NIC data. 22 files that expose the iSCSI Boot Firmware Table NIC data.
23 Usually this contains the IP address, MAC, and gateway of the NIC. 23 Usually this contains the IP address, MAC, and gateway of the NIC.
24
25What: /sys/firmware/ibft/acpi_header
26Date: March 2016
27Contact: David Bond <dbond@suse.com>
28Description: The /sys/firmware/ibft/acpi_header directory will contain files
29 that expose the SIGNATURE, OEM_ID, and OEM_TABLE_ID fields of the
30 acpi table header of the iBFT structure. This will allow for
31 identification of the creator of the table which is useful in
32 determining quirks associated with some adapters when used in
33 hardware vs software iscsi initiator mode.
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index 81037e5fe301..14042a64bdd5 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -418,6 +418,31 @@ static ssize_t ibft_attr_show_target(void *data, int type, char *buf)
418 return str - buf; 418 return str - buf;
419} 419}
420 420
421static ssize_t ibft_attr_show_acpitbl(void *data, int type, char *buf)
422{
423 struct ibft_kobject *entry = data;
424 char *str = buf;
425
426 switch (type) {
427 case ISCSI_BOOT_ACPITBL_SIGNATURE:
428 str += sprintf_string(str, ACPI_NAME_SIZE,
429 entry->header->header.signature);
430 break;
431 case ISCSI_BOOT_ACPITBL_OEM_ID:
432 str += sprintf_string(str, ACPI_OEM_ID_SIZE,
433 entry->header->header.oem_id);
434 break;
435 case ISCSI_BOOT_ACPITBL_OEM_TABLE_ID:
436 str += sprintf_string(str, ACPI_OEM_TABLE_ID_SIZE,
437 entry->header->header.oem_table_id);
438 break;
439 default:
440 break;
441 }
442
443 return str - buf;
444}
445
421static int __init ibft_check_device(void) 446static int __init ibft_check_device(void)
422{ 447{
423 int len; 448 int len;
@@ -576,6 +601,24 @@ static umode_t __init ibft_check_initiator_for(void *data, int type)
576 return rc; 601 return rc;
577} 602}
578 603
604static umode_t __init ibft_check_acpitbl_for(void *data, int type)
605{
606
607 umode_t rc = 0;
608
609 switch (type) {
610 case ISCSI_BOOT_ACPITBL_SIGNATURE:
611 case ISCSI_BOOT_ACPITBL_OEM_ID:
612 case ISCSI_BOOT_ACPITBL_OEM_TABLE_ID:
613 rc = S_IRUGO;
614 break;
615 default:
616 break;
617 }
618
619 return rc;
620}
621
579static void ibft_kobj_release(void *data) 622static void ibft_kobj_release(void *data)
580{ 623{
581 kfree(data); 624 kfree(data);
@@ -699,6 +742,8 @@ free_ibft_obj:
699static int __init ibft_register_kobjects(struct acpi_table_ibft *header) 742static int __init ibft_register_kobjects(struct acpi_table_ibft *header)
700{ 743{
701 struct ibft_control *control = NULL; 744 struct ibft_control *control = NULL;
745 struct iscsi_boot_kobj *boot_kobj;
746 struct ibft_kobject *ibft_kobj;
702 void *ptr, *end; 747 void *ptr, *end;
703 int rc = 0; 748 int rc = 0;
704 u16 offset; 749 u16 offset;
@@ -726,6 +771,25 @@ static int __init ibft_register_kobjects(struct acpi_table_ibft *header)
726 break; 771 break;
727 } 772 }
728 } 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 }
729 793
730 return rc; 794 return rc;
731} 795}
@@ -738,7 +802,7 @@ static void ibft_unregister(void)
738 list_for_each_entry_safe(boot_kobj, tmp_kobj, 802 list_for_each_entry_safe(boot_kobj, tmp_kobj,
739 &boot_kset->kobj_list, list) { 803 &boot_kset->kobj_list, list) {
740 ibft_kobj = boot_kobj->data; 804 ibft_kobj = boot_kobj->data;
741 if (ibft_kobj->hdr->id == id_nic) 805 if (ibft_kobj->hdr && ibft_kobj->hdr->id == id_nic)
742 sysfs_remove_link(&boot_kobj->kobj, "device"); 806 sysfs_remove_link(&boot_kobj->kobj, "device");
743 }; 807 };
744} 808}
diff --git a/drivers/scsi/iscsi_boot_sysfs.c b/drivers/scsi/iscsi_boot_sysfs.c
index 8f0ea97cf31f..d453667612f8 100644
--- a/drivers/scsi/iscsi_boot_sysfs.c
+++ b/drivers/scsi/iscsi_boot_sysfs.c
@@ -306,6 +306,42 @@ static struct attribute_group iscsi_boot_initiator_attr_group = {
306 .is_visible = iscsi_boot_ini_attr_is_visible, 306 .is_visible = iscsi_boot_ini_attr_is_visible,
307}; 307};
308 308
309/* iBFT ACPI Table attributes */
310iscsi_boot_rd_attr(acpitbl_signature, signature, ISCSI_BOOT_ACPITBL_SIGNATURE);
311iscsi_boot_rd_attr(acpitbl_oem_id, oem_id, ISCSI_BOOT_ACPITBL_OEM_ID);
312iscsi_boot_rd_attr(acpitbl_oem_table_id, oem_table_id,
313 ISCSI_BOOT_ACPITBL_OEM_TABLE_ID);
314
315static struct attribute *acpitbl_attrs[] = {
316 &iscsi_boot_attr_acpitbl_signature.attr,
317 &iscsi_boot_attr_acpitbl_oem_id.attr,
318 &iscsi_boot_attr_acpitbl_oem_table_id.attr,
319 NULL
320};
321
322static umode_t iscsi_boot_acpitbl_attr_is_visible(struct kobject *kobj,
323 struct attribute *attr, int i)
324{
325 struct iscsi_boot_kobj *boot_kobj =
326 container_of(kobj, struct iscsi_boot_kobj, kobj);
327
328 if (attr == &iscsi_boot_attr_acpitbl_signature.attr)
329 return boot_kobj->is_visible(boot_kobj->data,
330 ISCSI_BOOT_ACPITBL_SIGNATURE);
331 if (attr == &iscsi_boot_attr_acpitbl_oem_id.attr)
332 return boot_kobj->is_visible(boot_kobj->data,
333 ISCSI_BOOT_ACPITBL_OEM_ID);
334 if (attr == &iscsi_boot_attr_acpitbl_oem_table_id.attr)
335 return boot_kobj->is_visible(boot_kobj->data,
336 ISCSI_BOOT_ACPITBL_OEM_TABLE_ID);
337 return 0;
338}
339
340static struct attribute_group iscsi_boot_acpitbl_attr_group = {
341 .attrs = acpitbl_attrs,
342 .is_visible = iscsi_boot_acpitbl_attr_is_visible,
343};
344
309static struct iscsi_boot_kobj * 345static struct iscsi_boot_kobj *
310iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset, 346iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,
311 struct attribute_group *attr_group, 347 struct attribute_group *attr_group,
@@ -436,6 +472,32 @@ iscsi_boot_create_ethernet(struct iscsi_boot_kset *boot_kset, int index,
436EXPORT_SYMBOL_GPL(iscsi_boot_create_ethernet); 472EXPORT_SYMBOL_GPL(iscsi_boot_create_ethernet);
437 473
438/** 474/**
475 * iscsi_boot_create_acpitbl() - create boot acpi table sysfs dir
476 * @boot_kset: boot kset
477 * @index: not used
478 * @data: driver specific data
479 * @show: attr show function
480 * @is_visible: attr visibility function
481 * @release: release function
482 *
483 * Note: The boot sysfs lib will free the data passed in for the caller
484 * when all refs to the acpitbl kobject have been released.
485 */
486struct iscsi_boot_kobj *
487iscsi_boot_create_acpitbl(struct iscsi_boot_kset *boot_kset, int index,
488 void *data,
489 ssize_t (*show)(void *data, int type, char *buf),
490 umode_t (*is_visible)(void *data, int type),
491 void (*release)(void *data))
492{
493 return iscsi_boot_create_kobj(boot_kset,
494 &iscsi_boot_acpitbl_attr_group,
495 "acpi_header", index, data, show,
496 is_visible, release);
497}
498EXPORT_SYMBOL_GPL(iscsi_boot_create_acpitbl);
499
500/**
439 * iscsi_boot_create_kset() - creates root sysfs tree 501 * iscsi_boot_create_kset() - creates root sysfs tree
440 * @set_name: name of root dir 502 * @set_name: name of root dir
441 */ 503 */
diff --git a/include/linux/iscsi_boot_sysfs.h b/include/linux/iscsi_boot_sysfs.h
index 548d55395488..10923d730486 100644
--- a/include/linux/iscsi_boot_sysfs.h
+++ b/include/linux/iscsi_boot_sysfs.h
@@ -64,6 +64,12 @@ enum iscsi_boot_initiator_properties_enum {
64 ISCSI_BOOT_INI_END_MARKER, 64 ISCSI_BOOT_INI_END_MARKER,
65}; 65};
66 66
67enum iscsi_boot_acpitbl_properties_enum {
68 ISCSI_BOOT_ACPITBL_SIGNATURE,
69 ISCSI_BOOT_ACPITBL_OEM_ID,
70 ISCSI_BOOT_ACPITBL_OEM_TABLE_ID,
71};
72
67struct attribute_group; 73struct attribute_group;
68 74
69struct iscsi_boot_kobj { 75struct iscsi_boot_kobj {
@@ -127,6 +133,13 @@ iscsi_boot_create_target(struct iscsi_boot_kset *boot_kset, int index,
127 umode_t (*is_visible) (void *data, int type), 133 umode_t (*is_visible) (void *data, int type),
128 void (*release) (void *data)); 134 void (*release) (void *data));
129 135
136struct iscsi_boot_kobj *
137iscsi_boot_create_acpitbl(struct iscsi_boot_kset *boot_kset, int index,
138 void *data,
139 ssize_t (*show)(void *data, int type, char *buf),
140 umode_t (*is_visible)(void *data, int type),
141 void (*release)(void *data));
142
130struct iscsi_boot_kset *iscsi_boot_create_kset(const char *set_name); 143struct iscsi_boot_kset *iscsi_boot_create_kset(const char *set_name);
131struct iscsi_boot_kset *iscsi_boot_create_host_kset(unsigned int hostno); 144struct iscsi_boot_kset *iscsi_boot_create_host_kset(unsigned int hostno);
132void iscsi_boot_destroy_kset(struct iscsi_boot_kset *boot_kset); 145void iscsi_boot_destroy_kset(struct iscsi_boot_kset *boot_kset);