diff options
Diffstat (limited to 'drivers/firmware/iscsi_ibft.c')
| -rw-r--r-- | drivers/firmware/iscsi_ibft.c | 73 | 
1 files changed, 60 insertions, 13 deletions
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index 6148a1c6789..071c2c969ee 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c @@ -87,8 +87,8 @@  #define IBFT_ISCSI_VERSION "0.5.0"  #define IBFT_ISCSI_DATE "2010-Feb-25" -MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and \ -Konrad Rzeszutek <ketuzsezr@darnok.org>"); +MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and " +	      "Konrad Rzeszutek <ketuzsezr@darnok.org>");  MODULE_DESCRIPTION("sysfs interface to BIOS iBFT information");  MODULE_LICENSE("GPL");  MODULE_VERSION(IBFT_ISCSI_VERSION); @@ -433,11 +433,11 @@ static int __init ibft_check_device(void)   * Helper routiners to check to determine if the entry is valid   * in the proper iBFT structure.   */ -static mode_t ibft_check_nic_for(void *data, int type) +static umode_t ibft_check_nic_for(void *data, int type)  {  	struct ibft_kobject *entry = data;  	struct ibft_nic *nic = entry->nic; -	mode_t rc = 0; +	umode_t rc = 0;  	switch (type) {  	case ISCSI_BOOT_ETH_INDEX: @@ -488,11 +488,11 @@ static mode_t ibft_check_nic_for(void *data, int type)  	return rc;  } -static mode_t __init ibft_check_tgt_for(void *data, int type) +static umode_t __init ibft_check_tgt_for(void *data, int type)  {  	struct ibft_kobject *entry = data;  	struct ibft_tgt *tgt = entry->tgt; -	mode_t rc = 0; +	umode_t rc = 0;  	switch (type) {  	case ISCSI_BOOT_TGT_INDEX: @@ -524,11 +524,11 @@ static mode_t __init ibft_check_tgt_for(void *data, int type)  	return rc;  } -static mode_t __init ibft_check_initiator_for(void *data, int type) +static umode_t __init ibft_check_initiator_for(void *data, int type)  {  	struct ibft_kobject *entry = data;  	struct ibft_initiator *init = entry->initiator; -	mode_t rc = 0; +	umode_t rc = 0;  	switch (type) {  	case ISCSI_BOOT_INI_INDEX: @@ -566,6 +566,11 @@ static mode_t __init ibft_check_initiator_for(void *data, int type)  	return rc;  } +static void ibft_kobj_release(void *data) +{ +	kfree(data); +} +  /*   * Helper function for ibft_register_kobjects.   */ @@ -595,7 +600,8 @@ static int __init ibft_create_kobject(struct acpi_table_ibft *header,  		boot_kobj = iscsi_boot_create_initiator(boot_kset, hdr->index,  						ibft_kobj,  						ibft_attr_show_initiator, -						ibft_check_initiator_for); +						ibft_check_initiator_for, +						ibft_kobj_release);  		if (!boot_kobj) {  			rc = -ENOMEM;  			goto free_ibft_obj; @@ -610,7 +616,8 @@ static int __init ibft_create_kobject(struct acpi_table_ibft *header,  		boot_kobj = iscsi_boot_create_ethernet(boot_kset, hdr->index,  						       ibft_kobj,  						       ibft_attr_show_nic, -						       ibft_check_nic_for); +						       ibft_check_nic_for, +						       ibft_kobj_release);  		if (!boot_kobj) {  			rc = -ENOMEM;  			goto free_ibft_obj; @@ -625,7 +632,8 @@ static int __init ibft_create_kobject(struct acpi_table_ibft *header,  		boot_kobj = iscsi_boot_create_target(boot_kset, hdr->index,  						     ibft_kobj,  						     ibft_attr_show_target, -						     ibft_check_tgt_for); +						     ibft_check_tgt_for, +						     ibft_kobj_release);  		if (!boot_kobj) {  			rc = -ENOMEM;  			goto free_ibft_obj; @@ -738,6 +746,38 @@ static void __exit ibft_exit(void)  	ibft_cleanup();  } +#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" }, +	{ "BIFT" },	/* Broadcom iSCSI Offload */ +}; + +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 +  /*   * ibft_init() - creates sysfs tree entries for the iBFT data.   */ @@ -745,9 +785,16 @@ static int __init ibft_init(void)  {  	int rc = 0; +	/* +	   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(); +  	if (ibft_addr) { -		printk(KERN_INFO "iBFT detected at 0x%llx.\n", -		       (u64)isa_virt_to_bus(ibft_addr)); +		pr_info("iBFT detected.\n");  		rc = ibft_check_device();  		if (rc)  | 
