11
11
*/
12
12
#define pr_fmt (fmt ) KBUILD_MODNAME ": " fmt
13
13
14
+ #include <linux/container_of.h>
14
15
#include <linux/kernel.h>
15
16
#include <linux/module.h>
16
17
#include <linux/capability.h>
@@ -25,11 +26,16 @@ static u32 da_supported_commands;
25
26
static int da_num_tokens ;
26
27
static struct platform_device * platform_device ;
27
28
static struct calling_interface_token * da_tokens ;
28
- static struct device_attribute * token_location_attrs ;
29
- static struct device_attribute * token_value_attrs ;
29
+ static struct token_sysfs_data * token_entries ;
30
30
static struct attribute * * token_attrs ;
31
31
static DEFINE_MUTEX (smbios_mutex );
32
32
33
+ struct token_sysfs_data {
34
+ struct device_attribute location_attr ;
35
+ struct device_attribute value_attr ;
36
+ struct calling_interface_token * token ;
37
+ };
38
+
33
39
struct smbios_device {
34
40
struct list_head list ;
35
41
struct device * device ;
@@ -416,47 +422,26 @@ static void __init find_tokens(const struct dmi_header *dm, void *dummy)
416
422
}
417
423
}
418
424
419
- static int match_attribute (struct device * dev ,
420
- struct device_attribute * attr )
421
- {
422
- int i ;
423
-
424
- for (i = 0 ; i < da_num_tokens * 2 ; i ++ ) {
425
- if (!token_attrs [i ])
426
- continue ;
427
- if (strcmp (token_attrs [i ]-> name , attr -> attr .name ) == 0 )
428
- return i /2 ;
429
- }
430
- dev_dbg (dev , "couldn't match: %s\n" , attr -> attr .name );
431
- return - EINVAL ;
432
- }
433
-
434
425
static ssize_t location_show (struct device * dev ,
435
426
struct device_attribute * attr , char * buf )
436
427
{
437
- int i ;
428
+ struct token_sysfs_data * data = container_of ( attr , struct token_sysfs_data , location_attr ) ;
438
429
439
430
if (!capable (CAP_SYS_ADMIN ))
440
431
return - EPERM ;
441
432
442
- i = match_attribute (dev , attr );
443
- if (i > 0 )
444
- return sysfs_emit (buf , "%08x" , da_tokens [i ].location );
445
- return 0 ;
433
+ return sysfs_emit (buf , "%08x" , data -> token -> location );
446
434
}
447
435
448
436
static ssize_t value_show (struct device * dev ,
449
437
struct device_attribute * attr , char * buf )
450
438
{
451
- int i ;
439
+ struct token_sysfs_data * data = container_of ( attr , struct token_sysfs_data , value_attr ) ;
452
440
453
441
if (!capable (CAP_SYS_ADMIN ))
454
442
return - EPERM ;
455
443
456
- i = match_attribute (dev , attr );
457
- if (i > 0 )
458
- return sysfs_emit (buf , "%08x" , da_tokens [i ].value );
459
- return 0 ;
444
+ return sysfs_emit (buf , "%08x" , data -> token -> value );
460
445
}
461
446
462
447
static struct attribute_group smbios_attribute_group = {
@@ -473,55 +458,50 @@ static int build_tokens_sysfs(struct platform_device *dev)
473
458
{
474
459
char * location_name ;
475
460
char * value_name ;
476
- size_t size ;
477
461
int ret ;
478
462
int i , j ;
479
463
480
- /* (number of tokens + 1 for null terminated */
481
- size = sizeof (struct device_attribute ) * (da_num_tokens + 1 );
482
- token_location_attrs = kzalloc (size , GFP_KERNEL );
483
- if (!token_location_attrs )
464
+ token_entries = kcalloc (da_num_tokens , sizeof (* token_entries ), GFP_KERNEL );
465
+ if (!token_entries )
484
466
return - ENOMEM ;
485
- token_value_attrs = kzalloc (size , GFP_KERNEL );
486
- if (!token_value_attrs )
487
- goto out_allocate_value ;
488
467
489
468
/* need to store both location and value + terminator*/
490
- size = sizeof (struct attribute * ) * ((2 * da_num_tokens ) + 1 );
491
- token_attrs = kzalloc (size , GFP_KERNEL );
469
+ token_attrs = kcalloc ((2 * da_num_tokens ) + 1 , sizeof (* token_attrs ), GFP_KERNEL );
492
470
if (!token_attrs )
493
471
goto out_allocate_attrs ;
494
472
495
473
for (i = 0 , j = 0 ; i < da_num_tokens ; i ++ ) {
496
474
/* skip empty */
497
475
if (da_tokens [i ].tokenID == 0 )
498
476
continue ;
477
+
478
+ token_entries [i ].token = & da_tokens [i ];
479
+
499
480
/* add location */
500
481
location_name = kasprintf (GFP_KERNEL , "%04x_location" ,
501
482
da_tokens [i ].tokenID );
502
483
if (location_name == NULL )
503
484
goto out_unwind_strings ;
504
- sysfs_attr_init (& token_location_attrs [i ].attr );
505
- token_location_attrs [i ].attr .name = location_name ;
506
- token_location_attrs [i ].attr .mode = 0444 ;
507
- token_location_attrs [i ].show = location_show ;
508
- token_attrs [j ++ ] = & token_location_attrs [i ].attr ;
485
+
486
+ sysfs_attr_init (& token_entries [i ].location_attr .attr );
487
+ token_entries [i ].location_attr .attr .name = location_name ;
488
+ token_entries [i ].location_attr .attr .mode = 0444 ;
489
+ token_entries [i ].location_attr .show = location_show ;
490
+ token_attrs [j ++ ] = & token_entries [i ].location_attr .attr ;
509
491
510
492
/* add value */
511
493
value_name = kasprintf (GFP_KERNEL , "%04x_value" ,
512
494
da_tokens [i ].tokenID );
513
- if (value_name == NULL )
514
- goto loop_fail_create_value ;
515
- sysfs_attr_init (& token_value_attrs [i ].attr );
516
- token_value_attrs [i ].attr .name = value_name ;
517
- token_value_attrs [i ].attr .mode = 0444 ;
518
- token_value_attrs [i ].show = value_show ;
519
- token_attrs [j ++ ] = & token_value_attrs [i ].attr ;
520
- continue ;
521
-
522
- loop_fail_create_value :
523
- kfree (location_name );
524
- goto out_unwind_strings ;
495
+ if (!value_name ) {
496
+ kfree (location_name );
497
+ goto out_unwind_strings ;
498
+ }
499
+
500
+ sysfs_attr_init (& token_entries [i ].value_attr .attr );
501
+ token_entries [i ].value_attr .attr .name = value_name ;
502
+ token_entries [i ].value_attr .attr .mode = 0444 ;
503
+ token_entries [i ].value_attr .show = value_show ;
504
+ token_attrs [j ++ ] = & token_entries [i ].value_attr .attr ;
525
505
}
526
506
smbios_attribute_group .attrs = token_attrs ;
527
507
@@ -532,14 +512,12 @@ static int build_tokens_sysfs(struct platform_device *dev)
532
512
533
513
out_unwind_strings :
534
514
while (i -- ) {
535
- kfree (token_location_attrs [i ].attr .name );
536
- kfree (token_value_attrs [i ].attr .name );
515
+ kfree (token_entries [i ]. location_attr .attr .name );
516
+ kfree (token_entries [i ]. value_attr .attr .name );
537
517
}
538
518
kfree (token_attrs );
539
519
out_allocate_attrs :
540
- kfree (token_value_attrs );
541
- out_allocate_value :
542
- kfree (token_location_attrs );
520
+ kfree (token_entries );
543
521
544
522
return - ENOMEM ;
545
523
}
@@ -551,12 +529,11 @@ static void free_group(struct platform_device *pdev)
551
529
sysfs_remove_group (& pdev -> dev .kobj ,
552
530
& smbios_attribute_group );
553
531
for (i = 0 ; i < da_num_tokens ; i ++ ) {
554
- kfree (token_location_attrs [i ].attr .name );
555
- kfree (token_value_attrs [i ].attr .name );
532
+ kfree (token_entries [i ]. location_attr .attr .name );
533
+ kfree (token_entries [i ]. value_attr .attr .name );
556
534
}
557
535
kfree (token_attrs );
558
- kfree (token_value_attrs );
559
- kfree (token_location_attrs );
536
+ kfree (token_entries );
560
537
}
561
538
562
539
static int __init dell_smbios_init (void )
0 commit comments