root/drivers/scsi/iscsi_boot_sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. iscsi_boot_show_attribute
  2. iscsi_boot_kobj_release
  3. iscsi_boot_tgt_attr_is_visible
  4. iscsi_boot_eth_attr_is_visible
  5. iscsi_boot_ini_attr_is_visible
  6. iscsi_boot_acpitbl_attr_is_visible
  7. iscsi_boot_create_kobj
  8. iscsi_boot_remove_kobj
  9. iscsi_boot_create_target
  10. iscsi_boot_create_initiator
  11. iscsi_boot_create_ethernet
  12. iscsi_boot_create_acpitbl
  13. iscsi_boot_create_kset
  14. iscsi_boot_create_host_kset
  15. iscsi_boot_destroy_kset

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Export the iSCSI boot info to userland via sysfs.
   4  *
   5  * Copyright (C) 2010 Red Hat, Inc.  All rights reserved.
   6  * Copyright (C) 2010 Mike Christie
   7  */
   8 
   9 #include <linux/module.h>
  10 #include <linux/string.h>
  11 #include <linux/slab.h>
  12 #include <linux/sysfs.h>
  13 #include <linux/capability.h>
  14 #include <linux/iscsi_boot_sysfs.h>
  15 
  16 
  17 MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>");
  18 MODULE_DESCRIPTION("sysfs interface and helpers to export iSCSI boot information");
  19 MODULE_LICENSE("GPL");
  20 /*
  21  * The kobject and attribute structures.
  22  */
  23 struct iscsi_boot_attr {
  24         struct attribute attr;
  25         int type;
  26         ssize_t (*show) (void *data, int type, char *buf);
  27 };
  28 
  29 /*
  30  * The routine called for all sysfs attributes.
  31  */
  32 static ssize_t iscsi_boot_show_attribute(struct kobject *kobj,
  33                                          struct attribute *attr, char *buf)
  34 {
  35         struct iscsi_boot_kobj *boot_kobj =
  36                         container_of(kobj, struct iscsi_boot_kobj, kobj);
  37         struct iscsi_boot_attr *boot_attr =
  38                         container_of(attr, struct iscsi_boot_attr, attr);
  39         ssize_t ret = -EIO;
  40         char *str = buf;
  41 
  42         if (!capable(CAP_SYS_ADMIN))
  43                 return -EACCES;
  44 
  45         if (boot_kobj->show)
  46                 ret = boot_kobj->show(boot_kobj->data, boot_attr->type, str);
  47         return ret;
  48 }
  49 
  50 static const struct sysfs_ops iscsi_boot_attr_ops = {
  51         .show = iscsi_boot_show_attribute,
  52 };
  53 
  54 static void iscsi_boot_kobj_release(struct kobject *kobj)
  55 {
  56         struct iscsi_boot_kobj *boot_kobj =
  57                         container_of(kobj, struct iscsi_boot_kobj, kobj);
  58 
  59         if (boot_kobj->release)
  60                 boot_kobj->release(boot_kobj->data);
  61         kfree(boot_kobj);
  62 }
  63 
  64 static struct kobj_type iscsi_boot_ktype = {
  65         .release = iscsi_boot_kobj_release,
  66         .sysfs_ops = &iscsi_boot_attr_ops,
  67 };
  68 
  69 #define iscsi_boot_rd_attr(fnname, sysfs_name, attr_type)               \
  70 static struct iscsi_boot_attr iscsi_boot_attr_##fnname = {      \
  71         .attr   = { .name = __stringify(sysfs_name), .mode = 0444 },    \
  72         .type   = attr_type,                                            \
  73 }
  74 
  75 /* Target attrs */
  76 iscsi_boot_rd_attr(tgt_index, index, ISCSI_BOOT_TGT_INDEX);
  77 iscsi_boot_rd_attr(tgt_flags, flags, ISCSI_BOOT_TGT_FLAGS);
  78 iscsi_boot_rd_attr(tgt_ip, ip-addr, ISCSI_BOOT_TGT_IP_ADDR);
  79 iscsi_boot_rd_attr(tgt_port, port, ISCSI_BOOT_TGT_PORT);
  80 iscsi_boot_rd_attr(tgt_lun, lun, ISCSI_BOOT_TGT_LUN);
  81 iscsi_boot_rd_attr(tgt_chap, chap-type, ISCSI_BOOT_TGT_CHAP_TYPE);
  82 iscsi_boot_rd_attr(tgt_nic, nic-assoc, ISCSI_BOOT_TGT_NIC_ASSOC);
  83 iscsi_boot_rd_attr(tgt_name, target-name, ISCSI_BOOT_TGT_NAME);
  84 iscsi_boot_rd_attr(tgt_chap_name, chap-name, ISCSI_BOOT_TGT_CHAP_NAME);
  85 iscsi_boot_rd_attr(tgt_chap_secret, chap-secret, ISCSI_BOOT_TGT_CHAP_SECRET);
  86 iscsi_boot_rd_attr(tgt_chap_rev_name, rev-chap-name,
  87                    ISCSI_BOOT_TGT_REV_CHAP_NAME);
  88 iscsi_boot_rd_attr(tgt_chap_rev_secret, rev-chap-name-secret,
  89                    ISCSI_BOOT_TGT_REV_CHAP_SECRET);
  90 
  91 static struct attribute *target_attrs[] = {
  92         &iscsi_boot_attr_tgt_index.attr,
  93         &iscsi_boot_attr_tgt_flags.attr,
  94         &iscsi_boot_attr_tgt_ip.attr,
  95         &iscsi_boot_attr_tgt_port.attr,
  96         &iscsi_boot_attr_tgt_lun.attr,
  97         &iscsi_boot_attr_tgt_chap.attr,
  98         &iscsi_boot_attr_tgt_nic.attr,
  99         &iscsi_boot_attr_tgt_name.attr,
 100         &iscsi_boot_attr_tgt_chap_name.attr,
 101         &iscsi_boot_attr_tgt_chap_secret.attr,
 102         &iscsi_boot_attr_tgt_chap_rev_name.attr,
 103         &iscsi_boot_attr_tgt_chap_rev_secret.attr,
 104         NULL
 105 };
 106 
 107 static umode_t iscsi_boot_tgt_attr_is_visible(struct kobject *kobj,
 108                                              struct attribute *attr, int i)
 109 {
 110         struct iscsi_boot_kobj *boot_kobj =
 111                         container_of(kobj, struct iscsi_boot_kobj, kobj);
 112 
 113         if (attr ==  &iscsi_boot_attr_tgt_index.attr)
 114                 return boot_kobj->is_visible(boot_kobj->data,
 115                                              ISCSI_BOOT_TGT_INDEX);
 116         else if (attr == &iscsi_boot_attr_tgt_flags.attr)
 117                 return boot_kobj->is_visible(boot_kobj->data,
 118                                              ISCSI_BOOT_TGT_FLAGS);
 119         else if (attr == &iscsi_boot_attr_tgt_ip.attr)
 120                 return boot_kobj->is_visible(boot_kobj->data,
 121                                               ISCSI_BOOT_TGT_IP_ADDR);
 122         else if (attr == &iscsi_boot_attr_tgt_port.attr)
 123                 return boot_kobj->is_visible(boot_kobj->data,
 124                                               ISCSI_BOOT_TGT_PORT);
 125         else if (attr == &iscsi_boot_attr_tgt_lun.attr)
 126                 return boot_kobj->is_visible(boot_kobj->data,
 127                                               ISCSI_BOOT_TGT_LUN);
 128         else if (attr == &iscsi_boot_attr_tgt_chap.attr)
 129                 return boot_kobj->is_visible(boot_kobj->data,
 130                                              ISCSI_BOOT_TGT_CHAP_TYPE);
 131         else if (attr == &iscsi_boot_attr_tgt_nic.attr)
 132                 return boot_kobj->is_visible(boot_kobj->data,
 133                                              ISCSI_BOOT_TGT_NIC_ASSOC);
 134         else if (attr == &iscsi_boot_attr_tgt_name.attr)
 135                 return boot_kobj->is_visible(boot_kobj->data,
 136                                              ISCSI_BOOT_TGT_NAME);
 137         else if (attr == &iscsi_boot_attr_tgt_chap_name.attr)
 138                 return boot_kobj->is_visible(boot_kobj->data,
 139                                              ISCSI_BOOT_TGT_CHAP_NAME);
 140         else if (attr == &iscsi_boot_attr_tgt_chap_secret.attr)
 141                 return boot_kobj->is_visible(boot_kobj->data,
 142                                              ISCSI_BOOT_TGT_CHAP_SECRET);
 143         else if (attr == &iscsi_boot_attr_tgt_chap_rev_name.attr)
 144                 return boot_kobj->is_visible(boot_kobj->data,
 145                                              ISCSI_BOOT_TGT_REV_CHAP_NAME);
 146         else if (attr == &iscsi_boot_attr_tgt_chap_rev_secret.attr)
 147                 return boot_kobj->is_visible(boot_kobj->data,
 148                                              ISCSI_BOOT_TGT_REV_CHAP_SECRET);
 149         return 0;
 150 }
 151 
 152 static struct attribute_group iscsi_boot_target_attr_group = {
 153         .attrs = target_attrs,
 154         .is_visible = iscsi_boot_tgt_attr_is_visible,
 155 };
 156 
 157 /* Ethernet attrs */
 158 iscsi_boot_rd_attr(eth_index, index, ISCSI_BOOT_ETH_INDEX);
 159 iscsi_boot_rd_attr(eth_flags, flags, ISCSI_BOOT_ETH_FLAGS);
 160 iscsi_boot_rd_attr(eth_ip, ip-addr, ISCSI_BOOT_ETH_IP_ADDR);
 161 iscsi_boot_rd_attr(eth_prefix, prefix-len, ISCSI_BOOT_ETH_PREFIX_LEN);
 162 iscsi_boot_rd_attr(eth_subnet, subnet-mask, ISCSI_BOOT_ETH_SUBNET_MASK);
 163 iscsi_boot_rd_attr(eth_origin, origin, ISCSI_BOOT_ETH_ORIGIN);
 164 iscsi_boot_rd_attr(eth_gateway, gateway, ISCSI_BOOT_ETH_GATEWAY);
 165 iscsi_boot_rd_attr(eth_primary_dns, primary-dns, ISCSI_BOOT_ETH_PRIMARY_DNS);
 166 iscsi_boot_rd_attr(eth_secondary_dns, secondary-dns,
 167                    ISCSI_BOOT_ETH_SECONDARY_DNS);
 168 iscsi_boot_rd_attr(eth_dhcp, dhcp, ISCSI_BOOT_ETH_DHCP);
 169 iscsi_boot_rd_attr(eth_vlan, vlan, ISCSI_BOOT_ETH_VLAN);
 170 iscsi_boot_rd_attr(eth_mac, mac, ISCSI_BOOT_ETH_MAC);
 171 iscsi_boot_rd_attr(eth_hostname, hostname, ISCSI_BOOT_ETH_HOSTNAME);
 172 
 173 static struct attribute *ethernet_attrs[] = {
 174         &iscsi_boot_attr_eth_index.attr,
 175         &iscsi_boot_attr_eth_flags.attr,
 176         &iscsi_boot_attr_eth_ip.attr,
 177         &iscsi_boot_attr_eth_prefix.attr,
 178         &iscsi_boot_attr_eth_subnet.attr,
 179         &iscsi_boot_attr_eth_origin.attr,
 180         &iscsi_boot_attr_eth_gateway.attr,
 181         &iscsi_boot_attr_eth_primary_dns.attr,
 182         &iscsi_boot_attr_eth_secondary_dns.attr,
 183         &iscsi_boot_attr_eth_dhcp.attr,
 184         &iscsi_boot_attr_eth_vlan.attr,
 185         &iscsi_boot_attr_eth_mac.attr,
 186         &iscsi_boot_attr_eth_hostname.attr,
 187         NULL
 188 };
 189 
 190 static umode_t iscsi_boot_eth_attr_is_visible(struct kobject *kobj,
 191                                              struct attribute *attr, int i)
 192 {
 193         struct iscsi_boot_kobj *boot_kobj =
 194                         container_of(kobj, struct iscsi_boot_kobj, kobj);
 195 
 196         if (attr ==  &iscsi_boot_attr_eth_index.attr)
 197                 return boot_kobj->is_visible(boot_kobj->data,
 198                                              ISCSI_BOOT_ETH_INDEX);
 199         else if (attr ==  &iscsi_boot_attr_eth_flags.attr)
 200                 return boot_kobj->is_visible(boot_kobj->data,
 201                                              ISCSI_BOOT_ETH_FLAGS);
 202         else if (attr ==  &iscsi_boot_attr_eth_ip.attr)
 203                 return boot_kobj->is_visible(boot_kobj->data,
 204                                              ISCSI_BOOT_ETH_IP_ADDR);
 205         else if (attr ==  &iscsi_boot_attr_eth_prefix.attr)
 206                 return boot_kobj->is_visible(boot_kobj->data,
 207                                              ISCSI_BOOT_ETH_PREFIX_LEN);
 208         else if (attr ==  &iscsi_boot_attr_eth_subnet.attr)
 209                 return boot_kobj->is_visible(boot_kobj->data,
 210                                              ISCSI_BOOT_ETH_SUBNET_MASK);
 211         else if (attr ==  &iscsi_boot_attr_eth_origin.attr)
 212                 return boot_kobj->is_visible(boot_kobj->data,
 213                                              ISCSI_BOOT_ETH_ORIGIN);
 214         else if (attr ==  &iscsi_boot_attr_eth_gateway.attr)
 215                 return boot_kobj->is_visible(boot_kobj->data,
 216                                              ISCSI_BOOT_ETH_GATEWAY);
 217         else if (attr ==  &iscsi_boot_attr_eth_primary_dns.attr)
 218                 return boot_kobj->is_visible(boot_kobj->data,
 219                                              ISCSI_BOOT_ETH_PRIMARY_DNS);
 220         else if (attr ==  &iscsi_boot_attr_eth_secondary_dns.attr)
 221                 return boot_kobj->is_visible(boot_kobj->data,
 222                                              ISCSI_BOOT_ETH_SECONDARY_DNS);
 223         else if (attr ==  &iscsi_boot_attr_eth_dhcp.attr)
 224                 return boot_kobj->is_visible(boot_kobj->data,
 225                                              ISCSI_BOOT_ETH_DHCP);
 226         else if (attr ==  &iscsi_boot_attr_eth_vlan.attr)
 227                 return boot_kobj->is_visible(boot_kobj->data,
 228                                              ISCSI_BOOT_ETH_VLAN);
 229         else if (attr ==  &iscsi_boot_attr_eth_mac.attr)
 230                 return boot_kobj->is_visible(boot_kobj->data,
 231                                              ISCSI_BOOT_ETH_MAC);
 232         else if (attr ==  &iscsi_boot_attr_eth_hostname.attr)
 233                 return boot_kobj->is_visible(boot_kobj->data,
 234                                              ISCSI_BOOT_ETH_HOSTNAME);
 235         return 0;
 236 }
 237 
 238 static struct attribute_group iscsi_boot_ethernet_attr_group = {
 239         .attrs = ethernet_attrs,
 240         .is_visible = iscsi_boot_eth_attr_is_visible,
 241 };
 242 
 243 /* Initiator attrs */
 244 iscsi_boot_rd_attr(ini_index, index, ISCSI_BOOT_INI_INDEX);
 245 iscsi_boot_rd_attr(ini_flags, flags, ISCSI_BOOT_INI_FLAGS);
 246 iscsi_boot_rd_attr(ini_isns, isns-server, ISCSI_BOOT_INI_ISNS_SERVER);
 247 iscsi_boot_rd_attr(ini_slp, slp-server, ISCSI_BOOT_INI_SLP_SERVER);
 248 iscsi_boot_rd_attr(ini_primary_radius, pri-radius-server,
 249                    ISCSI_BOOT_INI_PRI_RADIUS_SERVER);
 250 iscsi_boot_rd_attr(ini_secondary_radius, sec-radius-server,
 251                    ISCSI_BOOT_INI_SEC_RADIUS_SERVER);
 252 iscsi_boot_rd_attr(ini_name, initiator-name, ISCSI_BOOT_INI_INITIATOR_NAME);
 253 
 254 static struct attribute *initiator_attrs[] = {
 255         &iscsi_boot_attr_ini_index.attr,
 256         &iscsi_boot_attr_ini_flags.attr,
 257         &iscsi_boot_attr_ini_isns.attr,
 258         &iscsi_boot_attr_ini_slp.attr,
 259         &iscsi_boot_attr_ini_primary_radius.attr,
 260         &iscsi_boot_attr_ini_secondary_radius.attr,
 261         &iscsi_boot_attr_ini_name.attr,
 262         NULL
 263 };
 264 
 265 static umode_t iscsi_boot_ini_attr_is_visible(struct kobject *kobj,
 266                                              struct attribute *attr, int i)
 267 {
 268         struct iscsi_boot_kobj *boot_kobj =
 269                         container_of(kobj, struct iscsi_boot_kobj, kobj);
 270 
 271         if (attr ==  &iscsi_boot_attr_ini_index.attr)
 272                 return boot_kobj->is_visible(boot_kobj->data,
 273                                              ISCSI_BOOT_INI_INDEX);
 274         if (attr ==  &iscsi_boot_attr_ini_flags.attr)
 275                 return boot_kobj->is_visible(boot_kobj->data,
 276                                              ISCSI_BOOT_INI_FLAGS);
 277         if (attr ==  &iscsi_boot_attr_ini_isns.attr)
 278                 return boot_kobj->is_visible(boot_kobj->data,
 279                                              ISCSI_BOOT_INI_ISNS_SERVER);
 280         if (attr ==  &iscsi_boot_attr_ini_slp.attr)
 281                 return boot_kobj->is_visible(boot_kobj->data,
 282                                              ISCSI_BOOT_INI_SLP_SERVER);
 283         if (attr ==  &iscsi_boot_attr_ini_primary_radius.attr)
 284                 return boot_kobj->is_visible(boot_kobj->data,
 285                                              ISCSI_BOOT_INI_PRI_RADIUS_SERVER);
 286         if (attr ==  &iscsi_boot_attr_ini_secondary_radius.attr)
 287                 return boot_kobj->is_visible(boot_kobj->data,
 288                                              ISCSI_BOOT_INI_SEC_RADIUS_SERVER);
 289         if (attr ==  &iscsi_boot_attr_ini_name.attr)
 290                 return boot_kobj->is_visible(boot_kobj->data,
 291                                              ISCSI_BOOT_INI_INITIATOR_NAME);
 292 
 293         return 0;
 294 }
 295 
 296 static struct attribute_group iscsi_boot_initiator_attr_group = {
 297         .attrs = initiator_attrs,
 298         .is_visible = iscsi_boot_ini_attr_is_visible,
 299 };
 300 
 301 /* iBFT ACPI Table attributes */
 302 iscsi_boot_rd_attr(acpitbl_signature, signature, ISCSI_BOOT_ACPITBL_SIGNATURE);
 303 iscsi_boot_rd_attr(acpitbl_oem_id, oem_id, ISCSI_BOOT_ACPITBL_OEM_ID);
 304 iscsi_boot_rd_attr(acpitbl_oem_table_id, oem_table_id,
 305                    ISCSI_BOOT_ACPITBL_OEM_TABLE_ID);
 306 
 307 static struct attribute *acpitbl_attrs[] = {
 308         &iscsi_boot_attr_acpitbl_signature.attr,
 309         &iscsi_boot_attr_acpitbl_oem_id.attr,
 310         &iscsi_boot_attr_acpitbl_oem_table_id.attr,
 311         NULL
 312 };
 313 
 314 static umode_t iscsi_boot_acpitbl_attr_is_visible(struct kobject *kobj,
 315                                              struct attribute *attr, int i)
 316 {
 317         struct iscsi_boot_kobj *boot_kobj =
 318                         container_of(kobj, struct iscsi_boot_kobj, kobj);
 319 
 320         if (attr ==  &iscsi_boot_attr_acpitbl_signature.attr)
 321                 return boot_kobj->is_visible(boot_kobj->data,
 322                                              ISCSI_BOOT_ACPITBL_SIGNATURE);
 323         if (attr ==  &iscsi_boot_attr_acpitbl_oem_id.attr)
 324                 return boot_kobj->is_visible(boot_kobj->data,
 325                                              ISCSI_BOOT_ACPITBL_OEM_ID);
 326         if (attr ==  &iscsi_boot_attr_acpitbl_oem_table_id.attr)
 327                 return boot_kobj->is_visible(boot_kobj->data,
 328                                              ISCSI_BOOT_ACPITBL_OEM_TABLE_ID);
 329         return 0;
 330 }
 331 
 332 static struct attribute_group iscsi_boot_acpitbl_attr_group = {
 333         .attrs = acpitbl_attrs,
 334         .is_visible = iscsi_boot_acpitbl_attr_is_visible,
 335 };
 336 
 337 static struct iscsi_boot_kobj *
 338 iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,
 339                        struct attribute_group *attr_group,
 340                        const char *name, int index, void *data,
 341                        ssize_t (*show) (void *data, int type, char *buf),
 342                        umode_t (*is_visible) (void *data, int type),
 343                        void (*release) (void *data))
 344 {
 345         struct iscsi_boot_kobj *boot_kobj;
 346 
 347         boot_kobj = kzalloc(sizeof(*boot_kobj), GFP_KERNEL);
 348         if (!boot_kobj)
 349                 return NULL;
 350         INIT_LIST_HEAD(&boot_kobj->list);
 351 
 352         boot_kobj->kobj.kset = boot_kset->kset;
 353         if (kobject_init_and_add(&boot_kobj->kobj, &iscsi_boot_ktype,
 354                                  NULL, name, index)) {
 355                 kfree(boot_kobj);
 356                 return NULL;
 357         }
 358         boot_kobj->data = data;
 359         boot_kobj->show = show;
 360         boot_kobj->is_visible = is_visible;
 361         boot_kobj->release = release;
 362 
 363         if (sysfs_create_group(&boot_kobj->kobj, attr_group)) {
 364                 /*
 365                  * We do not want to free this because the caller
 366                  * will assume that since the creation call failed
 367                  * the boot kobj was not setup and the normal release
 368                  * path is not being run.
 369                  */
 370                 boot_kobj->release = NULL;
 371                 kobject_put(&boot_kobj->kobj);
 372                 return NULL;
 373         }
 374         boot_kobj->attr_group = attr_group;
 375 
 376         kobject_uevent(&boot_kobj->kobj, KOBJ_ADD);
 377         /* Nothing broke so lets add it to the list. */
 378         list_add_tail(&boot_kobj->list, &boot_kset->kobj_list);
 379         return boot_kobj;
 380 }
 381 
 382 static void iscsi_boot_remove_kobj(struct iscsi_boot_kobj *boot_kobj)
 383 {
 384         list_del(&boot_kobj->list);
 385         sysfs_remove_group(&boot_kobj->kobj, boot_kobj->attr_group);
 386         kobject_put(&boot_kobj->kobj);
 387 }
 388 
 389 /**
 390  * iscsi_boot_create_target() - create boot target sysfs dir
 391  * @boot_kset: boot kset
 392  * @index: the target id
 393  * @data: driver specific data for target
 394  * @show: attr show function
 395  * @is_visible: attr visibility function
 396  * @release: release function
 397  *
 398  * Note: The boot sysfs lib will free the data passed in for the caller
 399  * when all refs to the target kobject have been released.
 400  */
 401 struct iscsi_boot_kobj *
 402 iscsi_boot_create_target(struct iscsi_boot_kset *boot_kset, int index,
 403                          void *data,
 404                          ssize_t (*show) (void *data, int type, char *buf),
 405                          umode_t (*is_visible) (void *data, int type),
 406                          void (*release) (void *data))
 407 {
 408         return iscsi_boot_create_kobj(boot_kset, &iscsi_boot_target_attr_group,
 409                                       "target%d", index, data, show, is_visible,
 410                                       release);
 411 }
 412 EXPORT_SYMBOL_GPL(iscsi_boot_create_target);
 413 
 414 /**
 415  * iscsi_boot_create_initiator() - create boot initiator sysfs dir
 416  * @boot_kset: boot kset
 417  * @index: the initiator id
 418  * @data: driver specific data
 419  * @show: attr show function
 420  * @is_visible: attr visibility function
 421  * @release: release function
 422  *
 423  * Note: The boot sysfs lib will free the data passed in for the caller
 424  * when all refs to the initiator kobject have been released.
 425  */
 426 struct iscsi_boot_kobj *
 427 iscsi_boot_create_initiator(struct iscsi_boot_kset *boot_kset, int index,
 428                             void *data,
 429                             ssize_t (*show) (void *data, int type, char *buf),
 430                             umode_t (*is_visible) (void *data, int type),
 431                             void (*release) (void *data))
 432 {
 433         return iscsi_boot_create_kobj(boot_kset,
 434                                       &iscsi_boot_initiator_attr_group,
 435                                       "initiator", index, data, show,
 436                                       is_visible, release);
 437 }
 438 EXPORT_SYMBOL_GPL(iscsi_boot_create_initiator);
 439 
 440 /**
 441  * iscsi_boot_create_ethernet() - create boot ethernet sysfs dir
 442  * @boot_kset: boot kset
 443  * @index: the ethernet device id
 444  * @data: driver specific data
 445  * @show: attr show function
 446  * @is_visible: attr visibility function
 447  * @release: release function
 448  *
 449  * Note: The boot sysfs lib will free the data passed in for the caller
 450  * when all refs to the ethernet kobject have been released.
 451  */
 452 struct iscsi_boot_kobj *
 453 iscsi_boot_create_ethernet(struct iscsi_boot_kset *boot_kset, int index,
 454                            void *data,
 455                            ssize_t (*show) (void *data, int type, char *buf),
 456                            umode_t (*is_visible) (void *data, int type),
 457                            void (*release) (void *data))
 458 {
 459         return iscsi_boot_create_kobj(boot_kset,
 460                                       &iscsi_boot_ethernet_attr_group,
 461                                       "ethernet%d", index, data, show,
 462                                       is_visible, release);
 463 }
 464 EXPORT_SYMBOL_GPL(iscsi_boot_create_ethernet);
 465 
 466 /**
 467  * iscsi_boot_create_acpitbl() - create boot acpi table sysfs dir
 468  * @boot_kset: boot kset
 469  * @index: not used
 470  * @data: driver specific data
 471  * @show: attr show function
 472  * @is_visible: attr visibility function
 473  * @release: release function
 474  *
 475  * Note: The boot sysfs lib will free the data passed in for the caller
 476  * when all refs to the acpitbl kobject have been released.
 477  */
 478 struct iscsi_boot_kobj *
 479 iscsi_boot_create_acpitbl(struct iscsi_boot_kset *boot_kset, int index,
 480                            void *data,
 481                            ssize_t (*show)(void *data, int type, char *buf),
 482                            umode_t (*is_visible)(void *data, int type),
 483                            void (*release)(void *data))
 484 {
 485         return iscsi_boot_create_kobj(boot_kset,
 486                                       &iscsi_boot_acpitbl_attr_group,
 487                                       "acpi_header", index, data, show,
 488                                       is_visible, release);
 489 }
 490 EXPORT_SYMBOL_GPL(iscsi_boot_create_acpitbl);
 491 
 492 /**
 493  * iscsi_boot_create_kset() - creates root sysfs tree
 494  * @set_name: name of root dir
 495  */
 496 struct iscsi_boot_kset *iscsi_boot_create_kset(const char *set_name)
 497 {
 498         struct iscsi_boot_kset *boot_kset;
 499 
 500         boot_kset = kzalloc(sizeof(*boot_kset), GFP_KERNEL);
 501         if (!boot_kset)
 502                 return NULL;
 503 
 504         boot_kset->kset = kset_create_and_add(set_name, NULL, firmware_kobj);
 505         if (!boot_kset->kset) {
 506                 kfree(boot_kset);
 507                 return NULL;
 508         }
 509 
 510         INIT_LIST_HEAD(&boot_kset->kobj_list);
 511         return boot_kset;
 512 }
 513 EXPORT_SYMBOL_GPL(iscsi_boot_create_kset);
 514 
 515 /**
 516  * iscsi_boot_create_host_kset() - creates root sysfs tree for a scsi host
 517  * @hostno: host number of scsi host
 518  */
 519 struct iscsi_boot_kset *iscsi_boot_create_host_kset(unsigned int hostno)
 520 {
 521         struct iscsi_boot_kset *boot_kset;
 522         char *set_name;
 523 
 524         set_name = kasprintf(GFP_KERNEL, "iscsi_boot%u", hostno);
 525         if (!set_name)
 526                 return NULL;
 527 
 528         boot_kset = iscsi_boot_create_kset(set_name);
 529         kfree(set_name);
 530         return boot_kset;
 531 }
 532 EXPORT_SYMBOL_GPL(iscsi_boot_create_host_kset);
 533 
 534 /**
 535  * iscsi_boot_destroy_kset() - destroy kset and kobjects under it
 536  * @boot_kset: boot kset
 537  *
 538  * This will remove the kset and kobjects and attrs under it.
 539  */
 540 void iscsi_boot_destroy_kset(struct iscsi_boot_kset *boot_kset)
 541 {
 542         struct iscsi_boot_kobj *boot_kobj, *tmp_kobj;
 543 
 544         if (!boot_kset)
 545                 return;
 546 
 547         list_for_each_entry_safe(boot_kobj, tmp_kobj,
 548                                  &boot_kset->kobj_list, list)
 549                 iscsi_boot_remove_kobj(boot_kobj);
 550 
 551         kset_unregister(boot_kset->kset);
 552         kfree(boot_kset);
 553 }
 554 EXPORT_SYMBOL_GPL(iscsi_boot_destroy_kset);

/* [<][>][^][v][top][bottom][index][help] */