iscsi_ibft.c revision 63779436ab4ad0867bcea53bf853b0004d7b895d
1138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 2138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Copyright 2007 Red Hat, Inc. 3138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * by Peter Jones <pjones@redhat.com> 4138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Copyright 2008 IBM, Inc. 5138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * by Konrad Rzeszutek <konradr@linux.vnet.ibm.com> 6138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Copyright 2008 7138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * by Konrad Rzeszutek <ketuzsezr@darnok.org> 8138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 9138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * This code exposes the iSCSI Boot Format Table to userland via sysfs. 10138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 11138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * This program is free software; you can redistribute it and/or modify 12138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * it under the terms of the GNU General Public License v2.0 as published by 13138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * the Free Software Foundation 14138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 15138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * This program is distributed in the hope that it will be useful, 16138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * but WITHOUT ANY WARRANTY; without even the implied warranty of 17138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * GNU General Public License for more details. 19138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 20138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Changelog: 21138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 22138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 14 Mar 2008 - Konrad Rzeszutek <ketuzsezr@darnok.org> 23138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Updated comments and copyrights. (v0.4.9) 24138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 25138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 11 Feb 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com> 26138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Converted to using ibft_addr. (v0.4.8) 27138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 28138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 8 Feb 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com> 29138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Combined two functions in one: reserve_ibft_region. (v0.4.7) 30138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 31138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 30 Jan 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com> 32138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Added logic to handle IPv6 addresses. (v0.4.6) 33138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 34138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 25 Jan 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com> 35138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Added logic to handle badly not-to-spec iBFT. (v0.4.5) 36138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 37138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 4 Jan 2008 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com> 38138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Added __init to function declarations. (v0.4.4) 39138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 40138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 21 Dec 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com> 41138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Updated kobject registration, combined unregister functions in one 42138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * and code and style cleanup. (v0.4.3) 43138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 44138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 5 Dec 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com> 45138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Added end-markers to enums and re-organized kobject registration. (v0.4.2) 46138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 47138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 4 Dec 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com> 48138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Created 'device' sysfs link to the NIC and style cleanup. (v0.4.1) 49138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 50138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 28 Nov 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com> 51138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Added sysfs-ibft documentation, moved 'find_ibft' function to 52138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * in its own file and added text attributes for every struct field. (v0.4) 53138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 54138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 21 Nov 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com> 55138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Added text attributes emulating OpenFirmware /proc/device-tree naming. 56138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Removed binary /sysfs interface (v0.3) 57138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 58138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 29 Aug 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com> 59138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Added functionality in setup.c to reserve iBFT region. (v0.2) 60138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 61138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 27 Aug 2007 - Konrad Rzeszutek <konradr@linux.vnet.ibm.com> 62138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * First version exposing iBFT data via a binary /sysfs. (v0.1) 63138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 64138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 65138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 66138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 67138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/blkdev.h> 68138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/capability.h> 69138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/ctype.h> 70138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/device.h> 71138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/err.h> 72138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/init.h> 73138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/iscsi_ibft.h> 74138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/limits.h> 75138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/module.h> 76138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/pci.h> 77138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/slab.h> 78138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/stat.h> 79138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/string.h> 80138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#include <linux/types.h> 81138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 82138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#define IBFT_ISCSI_VERSION "0.4.9" 83138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek#define IBFT_ISCSI_DATE "2008-Mar-14" 84138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 85138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad RzeszutekMODULE_AUTHOR("Peter Jones <pjones@redhat.com> and \ 86138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad RzeszutekKonrad Rzeszutek <ketuzsezr@darnok.org>"); 87138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad RzeszutekMODULE_DESCRIPTION("sysfs interface to BIOS iBFT information"); 88138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad RzeszutekMODULE_LICENSE("GPL"); 89138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad RzeszutekMODULE_VERSION(IBFT_ISCSI_VERSION); 90138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 91138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstruct ibft_hdr { 92138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u8 id; 93138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u8 version; 94138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 length; 95138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u8 index; 96138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u8 flags; 97138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} __attribute__((__packed__)); 98138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 99138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstruct ibft_control { 100138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_hdr hdr; 101138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 extensions; 102138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 initiator_off; 103138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 nic0_off; 104138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 tgt0_off; 105138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 nic1_off; 106138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 tgt1_off; 107138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} __attribute__((__packed__)); 108138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 109138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstruct ibft_initiator { 110138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_hdr hdr; 111138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char isns_server[16]; 112138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char slp_server[16]; 113138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char pri_radius_server[16]; 114138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char sec_radius_server[16]; 115138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 initiator_name_len; 116138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 initiator_name_off; 117138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} __attribute__((__packed__)); 118138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 119138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstruct ibft_nic { 120138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_hdr hdr; 121138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char ip_addr[16]; 122138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u8 subnet_mask_prefix; 123138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u8 origin; 124138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char gateway[16]; 125138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char primary_dns[16]; 126138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char secondary_dns[16]; 127138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char dhcp[16]; 128138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 vlan; 129138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char mac[6]; 130138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 pci_bdf; 131138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 hostname_len; 132138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 hostname_off; 133138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} __attribute__((__packed__)); 134138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 135138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstruct ibft_tgt { 136138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_hdr hdr; 137138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char ip_addr[16]; 138138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 port; 139138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char lun[8]; 140138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u8 chap_type; 141138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u8 nic_assoc; 142138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 tgt_name_len; 143138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 tgt_name_off; 144138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 chap_name_len; 145138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 chap_name_off; 146138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 chap_secret_len; 147138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 chap_secret_off; 148138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 rev_chap_name_len; 149138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 rev_chap_name_off; 150138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 rev_chap_secret_len; 151138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 rev_chap_secret_off; 152138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} __attribute__((__packed__)); 153138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 154138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 155138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * The kobject different types and its names. 156138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * 157138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek*/ 158138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekenum ibft_id { 159138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek id_reserved = 0, /* We don't support. */ 160138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek id_control = 1, /* Should show up only once and is not exported. */ 161138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek id_initiator = 2, 162138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek id_nic = 3, 163138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek id_target = 4, 164138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek id_extensions = 5, /* We don't support. */ 165138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek id_end_marker, 166138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek}; 167138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 168138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 169138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * We do not support the other types, hence the usage of NULL. 170138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * This maps to the enum ibft_id. 171138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 172138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic const char *ibft_id_names[] = 173138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek {NULL, NULL, "initiator", "ethernet%d", "target%d", NULL, NULL}; 174138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 175138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 176138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * The text attributes names for each of the kobjects. 177138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek*/ 178138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekenum ibft_eth_properties_enum { 179138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_index, 180138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_flags, 181138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_ip_addr, 182138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_subnet_mask, 183138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_origin, 184138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_gateway, 185138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_primary_dns, 186138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_secondary_dns, 187138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_dhcp, 188138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_vlan, 189138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_mac, 190138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek /* ibft_eth_pci_bdf - this is replaced by link to the device itself. */ 191138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_hostname, 192138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_end_marker, 193138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek}; 194138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 195138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic const char *ibft_eth_properties[] = 196138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek {"index", "flags", "ip-addr", "subnet-mask", "origin", "gateway", 197138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek "primary-dns", "secondary-dns", "dhcp", "vlan", "mac", "hostname", 198138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek NULL}; 199138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 200138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekenum ibft_tgt_properties_enum { 201138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_index, 202138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_flags, 203138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_ip_addr, 204138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_port, 205138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_lun, 206138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_chap_type, 207138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_nic_assoc, 208138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_name, 209138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_chap_name, 210138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_chap_secret, 211138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_rev_chap_name, 212138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_rev_chap_secret, 213138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_end_marker, 214138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek}; 215138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 216138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic const char *ibft_tgt_properties[] = 217138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek {"index", "flags", "ip-addr", "port", "lun", "chap-type", "nic-assoc", 218138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek "target-name", "chap-name", "chap-secret", "rev-chap-name", 219138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek "rev-chap-name-secret", NULL}; 220138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 221138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekenum ibft_initiator_properties_enum { 222138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_init_index, 223138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_init_flags, 224138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_init_isns_server, 225138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_init_slp_server, 226138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_init_pri_radius_server, 227138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_init_sec_radius_server, 228138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_init_initiator_name, 229138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_init_end_marker, 230138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek}; 231138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 232138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic const char *ibft_initiator_properties[] = 233138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek {"index", "flags", "isns-server", "slp-server", "pri-radius-server", 234138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek "sec-radius-server", "initiator-name", NULL}; 235138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 236138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 237138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * The kobject and attribute structures. 238138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 239138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 240138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstruct ibft_kobject { 241138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_table_header *header; 242138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek union { 243138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_initiator *initiator; 244138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_nic *nic; 245138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_tgt *tgt; 246138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_hdr *hdr; 247138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek }; 248138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct kobject kobj; 249138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct list_head node; 250138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek}; 251138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 252138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstruct ibft_attribute { 253138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct attribute attr; 254138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ssize_t (*show) (struct ibft_kobject *entry, 255138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_attribute *attr, char *buf); 256138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek union { 257138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_initiator *initiator; 258138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_nic *nic; 259138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_tgt *tgt; 260138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_hdr *hdr; 261138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek }; 262138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct kobject *kobj; 263138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek int type; /* The enum of the type. This can be any value of: 264138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_properties_enum, ibft_tgt_properties_enum, 265138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek or ibft_initiator_properties_enum. */ 266138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct list_head node; 267138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek}; 268138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 269138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic LIST_HEAD(ibft_attr_list); 270138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic LIST_HEAD(ibft_kobject_list); 271138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 272138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic const char nulls[16]; 273138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 274138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 275138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Helper functions to parse data properly. 276138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 277138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic ssize_t sprintf_ipaddr(char *buf, u8 *ip) 278138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 279138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char *str = buf; 280138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 281138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0 && 282138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ip[4] == 0 && ip[5] == 0 && ip[6] == 0 && ip[7] == 0 && 283138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ip[8] == 0 && ip[9] == 0 && ip[10] == 0xff && ip[11] == 0xff) { 284138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek /* 285138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * IPV4 286138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 28763779436ab4ad0867bcea53bf853b0004d7b895dHarvey Harrison str += sprintf(buf, "%pI4", ip + 12); 288138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } else { 289138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek /* 290138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * IPv6 291138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 2925b095d98928fdb9e3b75be20a54b7a6cbf6ca9adHarvey Harrison str += sprintf(str, "%pI6", ip); 293138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 294138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "\n"); 295138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return str - buf; 296138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 297138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 298138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic ssize_t sprintf_string(char *str, int len, char *buf) 299138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 300138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return sprintf(str, "%.*s\n", len, buf); 301138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 302138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 303138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 304138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Helper function to verify the IBFT header. 305138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 306138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic int ibft_verify_hdr(char *t, struct ibft_hdr *hdr, int id, int length) 307138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 308138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (hdr->id != id) { 309138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek printk(KERN_ERR "iBFT error: We expected the " \ 310138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek "field header.id to have %d but " \ 311138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek "found %d instead!\n", id, hdr->id); 312138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return -ENODEV; 313138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 314138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (hdr->length != length) { 315138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek printk(KERN_ERR "iBFT error: We expected the " \ 316138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek "field header.length to have %d but " \ 317138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek "found %d instead!\n", length, hdr->length); 318138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return -ENODEV; 319138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 320138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 321138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return 0; 322138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 323138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 324138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic void ibft_release(struct kobject *kobj) 325138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 326138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_kobject *ibft = 327138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek container_of(kobj, struct ibft_kobject, kobj); 328138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek kfree(ibft); 329138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 330138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 331138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 332138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Routines for parsing the iBFT data to be human readable. 333138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 3349cf899d12583082c77a0fcc758f3179b440518eeAdrian Bunkstatic ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry, 3359cf899d12583082c77a0fcc758f3179b440518eeAdrian Bunk struct ibft_attribute *attr, 3369cf899d12583082c77a0fcc758f3179b440518eeAdrian Bunk char *buf) 337138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 338138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_initiator *initiator = entry->initiator; 339138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek void *ibft_loc = entry->header; 340138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char *str = buf; 341138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 342138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (!initiator) 343138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return 0; 344138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 345138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek switch (attr->type) { 346138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_index: 347138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "%d\n", initiator->hdr.index); 348138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 349138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_flags: 350138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "%d\n", initiator->hdr.flags); 351138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 352138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_isns_server: 353138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_ipaddr(str, initiator->isns_server); 354138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 355138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_slp_server: 356138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_ipaddr(str, initiator->slp_server); 357138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 358138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_pri_radius_server: 359138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_ipaddr(str, initiator->pri_radius_server); 360138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 361138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_sec_radius_server: 362138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_ipaddr(str, initiator->sec_radius_server); 363138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 364138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_initiator_name: 365138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_string(str, initiator->initiator_name_len, 366138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek (char *)ibft_loc + 367138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek initiator->initiator_name_off); 368138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 369138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek default: 370138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 371138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 372138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 373138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return str - buf; 374138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 375138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 3769cf899d12583082c77a0fcc758f3179b440518eeAdrian Bunkstatic ssize_t ibft_attr_show_nic(struct ibft_kobject *entry, 3779cf899d12583082c77a0fcc758f3179b440518eeAdrian Bunk struct ibft_attribute *attr, 3789cf899d12583082c77a0fcc758f3179b440518eeAdrian Bunk char *buf) 379138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 380138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_nic *nic = entry->nic; 381138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek void *ibft_loc = entry->header; 382138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char *str = buf; 383138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char *mac; 384138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek int val; 385138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 386138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (!nic) 387138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return 0; 388138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 389138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek switch (attr->type) { 390138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_index: 391138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "%d\n", nic->hdr.index); 392138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 393138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_flags: 394138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "%d\n", nic->hdr.flags); 395138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 396138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_ip_addr: 397138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_ipaddr(str, nic->ip_addr); 398138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 399138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_subnet_mask: 400138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek val = ~((1 << (32-nic->subnet_mask_prefix))-1); 401138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, NIPQUAD_FMT, 402138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek (u8)(val >> 24), (u8)(val >> 16), 403138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek (u8)(val >> 8), (u8)(val)); 404138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 405138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_origin: 406138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "%d\n", nic->origin); 407138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 408138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_gateway: 409138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_ipaddr(str, nic->gateway); 410138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 411138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_primary_dns: 412138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_ipaddr(str, nic->primary_dns); 413138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 414138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_secondary_dns: 415138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_ipaddr(str, nic->secondary_dns); 416138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 417138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_dhcp: 418138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_ipaddr(str, nic->dhcp); 419138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 420138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_vlan: 421138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "%d\n", nic->vlan); 422138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 423138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_mac: 424138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek mac = nic->mac; 425138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x\n", 426138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek (u8)mac[0], (u8)mac[1], (u8)mac[2], 427138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek (u8)mac[3], (u8)mac[4], (u8)mac[5]); 428138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 429138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_hostname: 430138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_string(str, nic->hostname_len, 431138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek (char *)ibft_loc + nic->hostname_off); 432138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 433138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek default: 434138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 435138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 436138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 437138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return str - buf; 438138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek}; 439138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 4409cf899d12583082c77a0fcc758f3179b440518eeAdrian Bunkstatic ssize_t ibft_attr_show_target(struct ibft_kobject *entry, 4419cf899d12583082c77a0fcc758f3179b440518eeAdrian Bunk struct ibft_attribute *attr, 4429cf899d12583082c77a0fcc758f3179b440518eeAdrian Bunk char *buf) 443138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 444138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_tgt *tgt = entry->tgt; 445138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek void *ibft_loc = entry->header; 446138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char *str = buf; 447138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek int i; 448138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 449138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (!tgt) 450138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return 0; 451138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 452138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek switch (attr->type) { 453138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_index: 454138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "%d\n", tgt->hdr.index); 455138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 456138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_flags: 457138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "%d\n", tgt->hdr.flags); 458138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 459138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_ip_addr: 460138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_ipaddr(str, tgt->ip_addr); 461138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 462138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_port: 463138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "%d\n", tgt->port); 464138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 465138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_lun: 466138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek for (i = 0; i < 8; i++) 467138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "%x", (u8)tgt->lun[i]); 468138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "\n"); 469138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 470138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_nic_assoc: 471138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "%d\n", tgt->nic_assoc); 472138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 473138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_chap_type: 474138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf(str, "%d\n", tgt->chap_type); 475138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 476138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_name: 477138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_string(str, tgt->tgt_name_len, 478138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek (char *)ibft_loc + tgt->tgt_name_off); 479138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 480138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_chap_name: 481138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_string(str, tgt->chap_name_len, 482138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek (char *)ibft_loc + tgt->chap_name_off); 483138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 484138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_chap_secret: 485138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_string(str, tgt->chap_secret_len, 486138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek (char *)ibft_loc + tgt->chap_secret_off); 487138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 488138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_rev_chap_name: 489138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_string(str, tgt->rev_chap_name_len, 490138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek (char *)ibft_loc + 491138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek tgt->rev_chap_name_off); 492138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 493138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_rev_chap_secret: 494138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek str += sprintf_string(str, tgt->rev_chap_secret_len, 495138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek (char *)ibft_loc + 496138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek tgt->rev_chap_secret_off); 497138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 498138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek default: 499138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 500138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 501138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 502138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return str - buf; 503138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 504138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 505138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 506138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * The routine called for all sysfs attributes. 507138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 508138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic ssize_t ibft_show_attribute(struct kobject *kobj, 509138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct attribute *attr, 510138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char *buf) 511138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 512138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_kobject *dev = 513138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek container_of(kobj, struct ibft_kobject, kobj); 514138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_attribute *ibft_attr = 515138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek container_of(attr, struct ibft_attribute, attr); 516138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ssize_t ret = -EIO; 517138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char *str = buf; 518138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 519138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (!capable(CAP_SYS_ADMIN)) 520138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return -EACCES; 521138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 522138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (ibft_attr->show) 523138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ret = ibft_attr->show(dev, ibft_attr, str); 524138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 525138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return ret; 526138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 527138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 528138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic struct sysfs_ops ibft_attr_ops = { 529138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek .show = ibft_show_attribute, 530138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek}; 531138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 532138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic struct kobj_type ibft_ktype = { 533138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek .release = ibft_release, 534138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek .sysfs_ops = &ibft_attr_ops, 535138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek}; 536138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 537138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic struct kset *ibft_kset; 538138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 539138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic int __init ibft_check_device(void) 540138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 541138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek int len; 542138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u8 *pos; 543138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u8 csum = 0; 544138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 545138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek len = ibft_addr->length; 546138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 547138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek /* Sanity checking of iBFT. */ 548138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (ibft_addr->revision != 1) { 549138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek printk(KERN_ERR "iBFT module supports only revision 1, " \ 550138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek "while this is %d.\n", ibft_addr->revision); 551138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return -ENOENT; 552138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 553138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek for (pos = (u8 *)ibft_addr; pos < (u8 *)ibft_addr + len; pos++) 554138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek csum += *pos; 555138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 556138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (csum) { 557138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek printk(KERN_ERR "iBFT has incorrect checksum (0x%x)!\n", csum); 558138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return -ENOENT; 559138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 560138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 561138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return 0; 562138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 563138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 564138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 565138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Helper function for ibft_register_kobjects. 566138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 567138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic int __init ibft_create_kobject(struct ibft_table_header *header, 568138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_hdr *hdr, 569138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct list_head *list) 570138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 571138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_kobject *ibft_kobj = NULL; 572138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_nic *nic = (struct ibft_nic *)hdr; 573138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct pci_dev *pci_dev; 574138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek int rc = 0; 575138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 576138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_kobj = kzalloc(sizeof(*ibft_kobj), GFP_KERNEL); 577138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (!ibft_kobj) 578138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return -ENOMEM; 579138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 580138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_kobj->header = header; 581138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_kobj->hdr = hdr; 582138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 583138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek switch (hdr->id) { 584138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case id_initiator: 585138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = ibft_verify_hdr("initiator", hdr, id_initiator, 586138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek sizeof(*ibft_kobj->initiator)); 587138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 588138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case id_nic: 589138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = ibft_verify_hdr("ethernet", hdr, id_nic, 590138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek sizeof(*ibft_kobj->nic)); 591138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 592138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case id_target: 593138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = ibft_verify_hdr("target", hdr, id_target, 594138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek sizeof(*ibft_kobj->tgt)); 595138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 596138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case id_reserved: 597138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case id_control: 598138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case id_extensions: 599138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek /* Fields which we don't support. Ignore them */ 600138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 601138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 602138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek default: 603138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek printk(KERN_ERR "iBFT has unknown structure type (%d). " \ 604138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek "Report this bug to %.6s!\n", hdr->id, 605138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek header->oem_id); 606138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 607138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 608138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 609138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 610138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (rc) { 611138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek /* Skip adding this kobject, but exit with non-fatal error. */ 612138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek kfree(ibft_kobj); 613138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek goto out_invalid_struct; 614138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 615138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 616138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_kobj->kobj.kset = ibft_kset; 617138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 618138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = kobject_init_and_add(&ibft_kobj->kobj, &ibft_ktype, 619138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek NULL, ibft_id_names[hdr->id], hdr->index); 620138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 621138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (rc) { 622138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek kfree(ibft_kobj); 623138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek goto out; 624138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 625138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 626138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek kobject_uevent(&ibft_kobj->kobj, KOBJ_ADD); 627138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 628138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (hdr->id == id_nic) { 629138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek /* 630138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * We don't search for the device in other domains than 631138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * zero. This is because on x86 platforms the BIOS 632138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * executes only devices which are in domain 0. Furthermore, the 633138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * iBFT spec doesn't have a domain id field :-( 634138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 635138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek pci_dev = pci_get_bus_and_slot((nic->pci_bdf & 0xff00) >> 8, 636138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek (nic->pci_bdf & 0xff)); 637138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (pci_dev) { 638138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = sysfs_create_link(&ibft_kobj->kobj, 639138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek &pci_dev->dev.kobj, "device"); 640138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek pci_dev_put(pci_dev); 641138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 642138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 643138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 644138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek /* Nothing broke so lets add it to the list. */ 645138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek list_add_tail(&ibft_kobj->node, list); 646138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekout: 647138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return rc; 648138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekout_invalid_struct: 649138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek /* Unsupported structs are skipped. */ 650138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return 0; 651138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 652138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 653138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 654138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Scan the IBFT table structure for the NIC and Target fields. When 655138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * found add them on the passed-in list. We do not support the other 656138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * fields at this point, so they are skipped. 657138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 658138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic int __init ibft_register_kobjects(struct ibft_table_header *header, 659138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct list_head *list) 660138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 661138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_control *control = NULL; 662138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek void *ptr, *end; 663138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek int rc = 0; 664138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 offset; 665138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek u16 eot_offset; 666138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 667138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek control = (void *)header + sizeof(*header); 668138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek end = (void *)control + control->hdr.length; 669bb8fb4e6840ecebdc61f7ebd0653187e7128dde5Mike Christie eot_offset = (void *)header + header->length - (void *)control; 670138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control, 671138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek sizeof(*control)); 672138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 673138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek /* iBFT table safety checking */ 674138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc |= ((control->hdr.index) ? -ENODEV : 0); 675138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (rc) { 676138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek printk(KERN_ERR "iBFT error: Control header is invalid!\n"); 677138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return rc; 678138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 679138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek for (ptr = &control->initiator_off; ptr < end; ptr += sizeof(u16)) { 680138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek offset = *(u16 *)ptr; 681138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (offset && offset < header->length && offset < eot_offset) { 682138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = ibft_create_kobject(header, 683138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek (void *)header + offset, 684138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek list); 685138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (rc) 686138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 687138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 688138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 689138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 690138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return rc; 691138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 692138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 693138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic void ibft_unregister(struct list_head *attr_list, 694138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct list_head *kobj_list) 695138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 696138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_kobject *data = NULL, *n; 697138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_attribute *attr = NULL, *m; 698138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 699138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek list_for_each_entry_safe(attr, m, attr_list, node) { 700138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek sysfs_remove_file(attr->kobj, &attr->attr); 701138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek list_del(&attr->node); 702138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek kfree(attr); 703138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek }; 704138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek list_del_init(attr_list); 705138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 706138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek list_for_each_entry_safe(data, n, kobj_list, node) { 707138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek list_del(&data->node); 708138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (data->hdr->id == id_nic) 709138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek sysfs_remove_link(&data->kobj, "device"); 710138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek kobject_put(&data->kobj); 711138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek }; 712138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek list_del_init(kobj_list); 713138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 714138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 715138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic int __init ibft_create_attribute(struct ibft_kobject *kobj_data, 716138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek int type, 717138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek const char *name, 718138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ssize_t (*show)(struct ibft_kobject *, 719138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_attribute*, 720138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek char *buf), 721138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct list_head *list) 722138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 723138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_attribute *attr = NULL; 724138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_hdr *hdr = kobj_data->hdr; 725138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 726138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek attr = kmalloc(sizeof(*attr), GFP_KERNEL); 727138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (!attr) 728138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return -ENOMEM; 729138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 730138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek attr->attr.name = name; 731138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek attr->attr.mode = S_IRUSR; 732138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 733138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek attr->hdr = hdr; 734138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek attr->show = show; 735138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek attr->kobj = &kobj_data->kobj; 736138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek attr->type = type; 737138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 738138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek list_add_tail(&attr->node, list); 739138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 740138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return 0; 741138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 742138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 743138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 744138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Helper routiners to check to determine if the entry is valid 745138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * in the proper iBFT structure. 746138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 747138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic int __init ibft_check_nic_for(struct ibft_nic *nic, int entry) 748138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 749138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek int rc = 0; 750138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 751138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek switch (entry) { 752138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_index: 753138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_flags: 754138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 755138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 756138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_ip_addr: 757138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (!memcmp(nic->dhcp, nulls, sizeof(nic->dhcp))) 758138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 759138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 760138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_subnet_mask: 761138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (!memcmp(nic->dhcp, nulls, sizeof(nic->dhcp))) 762138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 763138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 764138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_origin: 765138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 766138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 767138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_gateway: 768138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (memcmp(nic->gateway, nulls, sizeof(nic->gateway))) 769138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 770138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 771138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_primary_dns: 772138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (memcmp(nic->primary_dns, nulls, 773138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek sizeof(nic->primary_dns))) 774138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 775138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 776138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_secondary_dns: 777138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (memcmp(nic->secondary_dns, nulls, 778138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek sizeof(nic->secondary_dns))) 779138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 780138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 781138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_dhcp: 782138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (memcmp(nic->dhcp, nulls, sizeof(nic->dhcp))) 783138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 784138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 785138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_vlan: 786138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_mac: 787138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 788138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 789138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_eth_hostname: 790138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (nic->hostname_off) 791138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 792138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 793138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek default: 794138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 795138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 796138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 797138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return rc; 798138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 799138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 800138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic int __init ibft_check_tgt_for(struct ibft_tgt *tgt, int entry) 801138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 802138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek int rc = 0; 803138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 804138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek switch (entry) { 805138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_index: 806138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_flags: 807138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_ip_addr: 808138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_port: 809138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_lun: 810138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_nic_assoc: 811138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_chap_type: 812138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 813138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_name: 814138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (tgt->tgt_name_len) 815138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 816138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 817138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_chap_name: 818138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_chap_secret: 819138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (tgt->chap_name_len) 820138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 821138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 822138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_rev_chap_name: 823138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_tgt_rev_chap_secret: 824138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (tgt->rev_chap_name_len) 825138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 826138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 827138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek default: 828138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 829138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 830138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 831138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return rc; 832138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 833138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 834138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic int __init ibft_check_initiator_for(struct ibft_initiator *init, 835138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek int entry) 836138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 837138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek int rc = 0; 838138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 839138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek switch (entry) { 840138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_index: 841138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_flags: 842138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 843138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 844138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_isns_server: 845138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (memcmp(init->isns_server, nulls, 846138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek sizeof(init->isns_server))) 847138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 848138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 849138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_slp_server: 850138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (memcmp(init->slp_server, nulls, 851138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek sizeof(init->slp_server))) 852138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 853138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 854138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_pri_radius_server: 855138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (memcmp(init->pri_radius_server, nulls, 856138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek sizeof(init->pri_radius_server))) 857138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 858138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 859138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_sec_radius_server: 860138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (memcmp(init->sec_radius_server, nulls, 861138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek sizeof(init->sec_radius_server))) 862138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 863138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 864138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case ibft_init_initiator_name: 865138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (init->initiator_name_len) 866138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = 1; 867138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 868138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek default: 869138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 870138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 871138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 872138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return rc; 873138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 874138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 875138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 876138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * Register the attributes for all of the kobjects. 877138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 878138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic int __init ibft_register_attributes(struct list_head *kobject_list, 879138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct list_head *attr_list) 880138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 881138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek int rc = 0, i = 0; 882138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_kobject *data = NULL; 883138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek struct ibft_attribute *attr = NULL, *m; 884138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 885138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek list_for_each_entry(data, kobject_list, node) { 886138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek switch (data->hdr->id) { 887138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case id_nic: 888138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek for (i = 0; i < ibft_eth_end_marker && !rc; i++) 889138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (ibft_check_nic_for(data->nic, i)) 890138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = ibft_create_attribute(data, i, 891138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_eth_properties[i], 892138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_attr_show_nic, attr_list); 893138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 894138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case id_target: 895138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek for (i = 0; i < ibft_tgt_end_marker && !rc; i++) 896138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (ibft_check_tgt_for(data->tgt, i)) 897138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = ibft_create_attribute(data, i, 898138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_tgt_properties[i], 899138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_attr_show_target, 900138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek attr_list); 901138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 902138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek case id_initiator: 903138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek for (i = 0; i < ibft_init_end_marker && !rc; i++) 904138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (ibft_check_initiator_for( 905138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek data->initiator, i)) 906138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = ibft_create_attribute(data, i, 907138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_initiator_properties[i], 908138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_attr_show_initiator, 909138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek attr_list); 910138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 911138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek default: 912138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 913138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 914138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (rc) 915138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 916138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 917138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek list_for_each_entry_safe(attr, m, attr_list, node) { 918138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = sysfs_create_file(attr->kobj, &attr->attr); 919138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (rc) { 920138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek list_del(&attr->node); 921138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek kfree(attr); 922138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek break; 923138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 924138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } 925138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 926138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return rc; 927138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 928138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 929138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek/* 930138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek * ibft_init() - creates sysfs tree entries for the iBFT data. 931138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek */ 932138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic int __init ibft_init(void) 933138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 934138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek int rc = 0; 935138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 936138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_kset = kset_create_and_add("ibft", NULL, firmware_kobj); 937138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (!ibft_kset) 938138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return -ENOMEM; 939138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 940138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (ibft_addr) { 941138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek printk(KERN_INFO "iBFT detected at 0x%lx.\n", 942138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek virt_to_phys((void *)ibft_addr)); 943138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 944138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = ibft_check_device(); 945138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (rc) 946138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek goto out_firmware_unregister; 947138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 948138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek /* Scan the IBFT for data and register the kobjects. */ 949138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = ibft_register_kobjects(ibft_addr, &ibft_kobject_list); 950138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (rc) 951138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek goto out_free; 952138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 953138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek /* Register the attributes */ 954138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek rc = ibft_register_attributes(&ibft_kobject_list, 955138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek &ibft_attr_list); 956138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek if (rc) 957138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek goto out_free; 958138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek } else 959138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek printk(KERN_INFO "No iBFT detected.\n"); 960138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 961138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return 0; 962138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 963138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekout_free: 964138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_unregister(&ibft_attr_list, &ibft_kobject_list); 965138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekout_firmware_unregister: 966138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek kset_unregister(ibft_kset); 967138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek return rc; 968138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 969138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 970138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekstatic void __exit ibft_exit(void) 971138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek{ 972138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek ibft_unregister(&ibft_attr_list, &ibft_kobject_list); 973138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek kset_unregister(ibft_kset); 974138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek} 975138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutek 976138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekmodule_init(ibft_init); 977138fe4e069798d9aa948a5402ff15e58f483ee4eKonrad Rzeszutekmodule_exit(ibft_exit); 978