aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/iscsi_boot_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/iscsi_boot_sysfs.c')
-rw-r--r--drivers/scsi/iscsi_boot_sysfs.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/drivers/scsi/iscsi_boot_sysfs.c b/drivers/scsi/iscsi_boot_sysfs.c
index df6bff7366cf..89700cbca16e 100644
--- a/drivers/scsi/iscsi_boot_sysfs.c
+++ b/drivers/scsi/iscsi_boot_sysfs.c
@@ -64,7 +64,8 @@ static void iscsi_boot_kobj_release(struct kobject *kobj)
64 struct iscsi_boot_kobj *boot_kobj = 64 struct iscsi_boot_kobj *boot_kobj =
65 container_of(kobj, struct iscsi_boot_kobj, kobj); 65 container_of(kobj, struct iscsi_boot_kobj, kobj);
66 66
67 kfree(boot_kobj->data); 67 if (boot_kobj->release)
68 boot_kobj->release(boot_kobj->data);
68 kfree(boot_kobj); 69 kfree(boot_kobj);
69} 70}
70 71
@@ -305,7 +306,8 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,
305 struct attribute_group *attr_group, 306 struct attribute_group *attr_group,
306 const char *name, int index, void *data, 307 const char *name, int index, void *data,
307 ssize_t (*show) (void *data, int type, char *buf), 308 ssize_t (*show) (void *data, int type, char *buf),
308 mode_t (*is_visible) (void *data, int type)) 309 mode_t (*is_visible) (void *data, int type),
310 void (*release) (void *data))
309{ 311{
310 struct iscsi_boot_kobj *boot_kobj; 312 struct iscsi_boot_kobj *boot_kobj;
311 313
@@ -323,6 +325,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,
323 boot_kobj->data = data; 325 boot_kobj->data = data;
324 boot_kobj->show = show; 326 boot_kobj->show = show;
325 boot_kobj->is_visible = is_visible; 327 boot_kobj->is_visible = is_visible;
328 boot_kobj->release = release;
326 329
327 if (sysfs_create_group(&boot_kobj->kobj, attr_group)) { 330 if (sysfs_create_group(&boot_kobj->kobj, attr_group)) {
328 /* 331 /*
@@ -331,7 +334,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,
331 * the boot kobj was not setup and the normal release 334 * the boot kobj was not setup and the normal release
332 * path is not being run. 335 * path is not being run.
333 */ 336 */
334 boot_kobj->data = NULL; 337 boot_kobj->release = NULL;
335 kobject_put(&boot_kobj->kobj); 338 kobject_put(&boot_kobj->kobj);
336 return NULL; 339 return NULL;
337 } 340 }
@@ -357,6 +360,7 @@ static void iscsi_boot_remove_kobj(struct iscsi_boot_kobj *boot_kobj)
357 * @data: driver specific data for target 360 * @data: driver specific data for target
358 * @show: attr show function 361 * @show: attr show function
359 * @is_visible: attr visibility function 362 * @is_visible: attr visibility function
363 * @release: release function
360 * 364 *
361 * Note: The boot sysfs lib will free the data passed in for the caller 365 * Note: The boot sysfs lib will free the data passed in for the caller
362 * when all refs to the target kobject have been released. 366 * when all refs to the target kobject have been released.
@@ -365,10 +369,12 @@ struct iscsi_boot_kobj *
365iscsi_boot_create_target(struct iscsi_boot_kset *boot_kset, int index, 369iscsi_boot_create_target(struct iscsi_boot_kset *boot_kset, int index,
366 void *data, 370 void *data,
367 ssize_t (*show) (void *data, int type, char *buf), 371 ssize_t (*show) (void *data, int type, char *buf),
368 mode_t (*is_visible) (void *data, int type)) 372 mode_t (*is_visible) (void *data, int type),
373 void (*release) (void *data))
369{ 374{
370 return iscsi_boot_create_kobj(boot_kset, &iscsi_boot_target_attr_group, 375 return iscsi_boot_create_kobj(boot_kset, &iscsi_boot_target_attr_group,
371 "target%d", index, data, show, is_visible); 376 "target%d", index, data, show, is_visible,
377 release);
372} 378}
373EXPORT_SYMBOL_GPL(iscsi_boot_create_target); 379EXPORT_SYMBOL_GPL(iscsi_boot_create_target);
374 380
@@ -379,6 +385,7 @@ EXPORT_SYMBOL_GPL(iscsi_boot_create_target);
379 * @data: driver specific data 385 * @data: driver specific data
380 * @show: attr show function 386 * @show: attr show function
381 * @is_visible: attr visibility function 387 * @is_visible: attr visibility function
388 * @release: release function
382 * 389 *
383 * Note: The boot sysfs lib will free the data passed in for the caller 390 * Note: The boot sysfs lib will free the data passed in for the caller
384 * when all refs to the initiator kobject have been released. 391 * when all refs to the initiator kobject have been released.
@@ -387,12 +394,13 @@ struct iscsi_boot_kobj *
387iscsi_boot_create_initiator(struct iscsi_boot_kset *boot_kset, int index, 394iscsi_boot_create_initiator(struct iscsi_boot_kset *boot_kset, int index,
388 void *data, 395 void *data,
389 ssize_t (*show) (void *data, int type, char *buf), 396 ssize_t (*show) (void *data, int type, char *buf),
390 mode_t (*is_visible) (void *data, int type)) 397 mode_t (*is_visible) (void *data, int type),
398 void (*release) (void *data))
391{ 399{
392 return iscsi_boot_create_kobj(boot_kset, 400 return iscsi_boot_create_kobj(boot_kset,
393 &iscsi_boot_initiator_attr_group, 401 &iscsi_boot_initiator_attr_group,
394 "initiator", index, data, show, 402 "initiator", index, data, show,
395 is_visible); 403 is_visible, release);
396} 404}
397EXPORT_SYMBOL_GPL(iscsi_boot_create_initiator); 405EXPORT_SYMBOL_GPL(iscsi_boot_create_initiator);
398 406
@@ -403,6 +411,7 @@ EXPORT_SYMBOL_GPL(iscsi_boot_create_initiator);
403 * @data: driver specific data 411 * @data: driver specific data
404 * @show: attr show function 412 * @show: attr show function
405 * @is_visible: attr visibility function 413 * @is_visible: attr visibility function
414 * @release: release function
406 * 415 *
407 * Note: The boot sysfs lib will free the data passed in for the caller 416 * Note: The boot sysfs lib will free the data passed in for the caller
408 * when all refs to the ethernet kobject have been released. 417 * when all refs to the ethernet kobject have been released.
@@ -411,12 +420,13 @@ struct iscsi_boot_kobj *
411iscsi_boot_create_ethernet(struct iscsi_boot_kset *boot_kset, int index, 420iscsi_boot_create_ethernet(struct iscsi_boot_kset *boot_kset, int index,
412 void *data, 421 void *data,
413 ssize_t (*show) (void *data, int type, char *buf), 422 ssize_t (*show) (void *data, int type, char *buf),
414 mode_t (*is_visible) (void *data, int type)) 423 mode_t (*is_visible) (void *data, int type),
424 void (*release) (void *data))
415{ 425{
416 return iscsi_boot_create_kobj(boot_kset, 426 return iscsi_boot_create_kobj(boot_kset,
417 &iscsi_boot_ethernet_attr_group, 427 &iscsi_boot_ethernet_attr_group,
418 "ethernet%d", index, data, show, 428 "ethernet%d", index, data, show,
419 is_visible); 429 is_visible, release);
420} 430}
421EXPORT_SYMBOL_GPL(iscsi_boot_create_ethernet); 431EXPORT_SYMBOL_GPL(iscsi_boot_create_ethernet);
422 432
@@ -472,6 +482,9 @@ void iscsi_boot_destroy_kset(struct iscsi_boot_kset *boot_kset)
472{ 482{
473 struct iscsi_boot_kobj *boot_kobj, *tmp_kobj; 483 struct iscsi_boot_kobj *boot_kobj, *tmp_kobj;
474 484
485 if (!boot_kset)
486 return;
487
475 list_for_each_entry_safe(boot_kobj, tmp_kobj, 488 list_for_each_entry_safe(boot_kobj, tmp_kobj,
476 &boot_kset->kobj_list, list) 489 &boot_kset->kobj_list, list)
477 iscsi_boot_remove_kobj(boot_kobj); 490 iscsi_boot_remove_kobj(boot_kobj);