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
This commit is contained in:
Коммит
d974f09ea4
|
@ -21,3 +21,13 @@ Contact: Konrad Rzeszutek <ketuzsezr@darnok.org>
|
|||
Description: The /sys/firmware/ibft/ethernetX directory will contain
|
||||
files that expose the iSCSI Boot Firmware Table NIC data.
|
||||
Usually this contains the IP address, MAC, and gateway of the NIC.
|
||||
|
||||
What: /sys/firmware/ibft/acpi_header
|
||||
Date: March 2016
|
||||
Contact: David Bond <dbond@suse.com>
|
||||
Description: The /sys/firmware/ibft/acpi_header directory will contain files
|
||||
that expose the SIGNATURE, OEM_ID, and OEM_TABLE_ID fields of the
|
||||
acpi table header of the iBFT structure. This will allow for
|
||||
identification of the creator of the table which is useful in
|
||||
determining quirks associated with some adapters when used in
|
||||
hardware vs software iscsi initiator mode.
|
||||
|
|
|
@ -418,6 +418,31 @@ static ssize_t ibft_attr_show_target(void *data, int type, char *buf)
|
|||
return str - buf;
|
||||
}
|
||||
|
||||
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:
|
||||
str += sprintf_string(str, ACPI_NAME_SIZE,
|
||||
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;
|
||||
}
|
||||
|
||||
static int __init ibft_check_device(void)
|
||||
{
|
||||
int len;
|
||||
|
@ -576,6 +601,24 @@ static umode_t __init ibft_check_initiator_for(void *data, int type)
|
|||
return rc;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void ibft_kobj_release(void *data)
|
||||
{
|
||||
kfree(data);
|
||||
|
@ -699,6 +742,8 @@ free_ibft_obj:
|
|||
static int __init ibft_register_kobjects(struct acpi_table_ibft *header)
|
||||
{
|
||||
struct ibft_control *control = NULL;
|
||||
struct iscsi_boot_kobj *boot_kobj;
|
||||
struct ibft_kobject *ibft_kobj;
|
||||
void *ptr, *end;
|
||||
int rc = 0;
|
||||
u16 offset;
|
||||
|
@ -726,6 +771,25 @@ static int __init ibft_register_kobjects(struct acpi_table_ibft *header)
|
|||
break;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -738,7 +802,7 @@ static void ibft_unregister(void)
|
|||
list_for_each_entry_safe(boot_kobj, tmp_kobj,
|
||||
&boot_kset->kobj_list, list) {
|
||||
ibft_kobj = boot_kobj->data;
|
||||
if (ibft_kobj->hdr->id == id_nic)
|
||||
if (ibft_kobj->hdr && ibft_kobj->hdr->id == id_nic)
|
||||
sysfs_remove_link(&boot_kobj->kobj, "device");
|
||||
};
|
||||
}
|
||||
|
|
|
@ -306,6 +306,42 @@ static struct attribute_group iscsi_boot_initiator_attr_group = {
|
|||
.is_visible = iscsi_boot_ini_attr_is_visible,
|
||||
};
|
||||
|
||||
/* iBFT ACPI Table attributes */
|
||||
iscsi_boot_rd_attr(acpitbl_signature, signature, ISCSI_BOOT_ACPITBL_SIGNATURE);
|
||||
iscsi_boot_rd_attr(acpitbl_oem_id, oem_id, ISCSI_BOOT_ACPITBL_OEM_ID);
|
||||
iscsi_boot_rd_attr(acpitbl_oem_table_id, oem_table_id,
|
||||
ISCSI_BOOT_ACPITBL_OEM_TABLE_ID);
|
||||
|
||||
static struct attribute *acpitbl_attrs[] = {
|
||||
&iscsi_boot_attr_acpitbl_signature.attr,
|
||||
&iscsi_boot_attr_acpitbl_oem_id.attr,
|
||||
&iscsi_boot_attr_acpitbl_oem_table_id.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static umode_t iscsi_boot_acpitbl_attr_is_visible(struct kobject *kobj,
|
||||
struct attribute *attr, int i)
|
||||
{
|
||||
struct iscsi_boot_kobj *boot_kobj =
|
||||
container_of(kobj, struct iscsi_boot_kobj, kobj);
|
||||
|
||||
if (attr == &iscsi_boot_attr_acpitbl_signature.attr)
|
||||
return boot_kobj->is_visible(boot_kobj->data,
|
||||
ISCSI_BOOT_ACPITBL_SIGNATURE);
|
||||
if (attr == &iscsi_boot_attr_acpitbl_oem_id.attr)
|
||||
return boot_kobj->is_visible(boot_kobj->data,
|
||||
ISCSI_BOOT_ACPITBL_OEM_ID);
|
||||
if (attr == &iscsi_boot_attr_acpitbl_oem_table_id.attr)
|
||||
return boot_kobj->is_visible(boot_kobj->data,
|
||||
ISCSI_BOOT_ACPITBL_OEM_TABLE_ID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct attribute_group iscsi_boot_acpitbl_attr_group = {
|
||||
.attrs = acpitbl_attrs,
|
||||
.is_visible = iscsi_boot_acpitbl_attr_is_visible,
|
||||
};
|
||||
|
||||
static struct iscsi_boot_kobj *
|
||||
iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,
|
||||
struct attribute_group *attr_group,
|
||||
|
@ -435,6 +471,32 @@ iscsi_boot_create_ethernet(struct iscsi_boot_kset *boot_kset, int index,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_boot_create_ethernet);
|
||||
|
||||
/**
|
||||
* iscsi_boot_create_acpitbl() - create boot acpi table sysfs dir
|
||||
* @boot_kset: boot kset
|
||||
* @index: not used
|
||||
* @data: driver specific data
|
||||
* @show: attr show function
|
||||
* @is_visible: attr visibility function
|
||||
* @release: release function
|
||||
*
|
||||
* Note: The boot sysfs lib will free the data passed in for the caller
|
||||
* when all refs to the acpitbl kobject have been released.
|
||||
*/
|
||||
struct iscsi_boot_kobj *
|
||||
iscsi_boot_create_acpitbl(struct iscsi_boot_kset *boot_kset, int index,
|
||||
void *data,
|
||||
ssize_t (*show)(void *data, int type, char *buf),
|
||||
umode_t (*is_visible)(void *data, int type),
|
||||
void (*release)(void *data))
|
||||
{
|
||||
return iscsi_boot_create_kobj(boot_kset,
|
||||
&iscsi_boot_acpitbl_attr_group,
|
||||
"acpi_header", index, data, show,
|
||||
is_visible, release);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iscsi_boot_create_acpitbl);
|
||||
|
||||
/**
|
||||
* iscsi_boot_create_kset() - creates root sysfs tree
|
||||
* @set_name: name of root dir
|
||||
|
|
|
@ -64,6 +64,12 @@ enum iscsi_boot_initiator_properties_enum {
|
|||
ISCSI_BOOT_INI_END_MARKER,
|
||||
};
|
||||
|
||||
enum iscsi_boot_acpitbl_properties_enum {
|
||||
ISCSI_BOOT_ACPITBL_SIGNATURE,
|
||||
ISCSI_BOOT_ACPITBL_OEM_ID,
|
||||
ISCSI_BOOT_ACPITBL_OEM_TABLE_ID,
|
||||
};
|
||||
|
||||
struct attribute_group;
|
||||
|
||||
struct iscsi_boot_kobj {
|
||||
|
@ -127,6 +133,13 @@ iscsi_boot_create_target(struct iscsi_boot_kset *boot_kset, int index,
|
|||
umode_t (*is_visible) (void *data, int type),
|
||||
void (*release) (void *data));
|
||||
|
||||
struct iscsi_boot_kobj *
|
||||
iscsi_boot_create_acpitbl(struct iscsi_boot_kset *boot_kset, int index,
|
||||
void *data,
|
||||
ssize_t (*show)(void *data, int type, char *buf),
|
||||
umode_t (*is_visible)(void *data, int type),
|
||||
void (*release)(void *data));
|
||||
|
||||
struct iscsi_boot_kset *iscsi_boot_create_kset(const char *set_name);
|
||||
struct iscsi_boot_kset *iscsi_boot_create_host_kset(unsigned int hostno);
|
||||
void iscsi_boot_destroy_kset(struct iscsi_boot_kset *boot_kset);
|
||||
|
|
Загрузка…
Ссылка в новой задаче