1111 */
1212#define pr_fmt (fmt ) KBUILD_MODNAME ": " fmt
1313
14+ #include <linux/container_of.h>
1415#include <linux/kernel.h>
1516#include <linux/module.h>
1617#include <linux/capability.h>
@@ -25,11 +26,16 @@ static u32 da_supported_commands;
2526static int da_num_tokens ;
2627static struct platform_device * platform_device ;
2728static 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 ;
3030static struct attribute * * token_attrs ;
3131static DEFINE_MUTEX (smbios_mutex );
3232
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+
3339struct smbios_device {
3440 struct list_head list ;
3541 struct device * device ;
@@ -416,47 +422,26 @@ static void __init find_tokens(const struct dmi_header *dm, void *dummy)
416422 }
417423}
418424
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-
434425static ssize_t location_show (struct device * dev ,
435426 struct device_attribute * attr , char * buf )
436427{
437- int i ;
428+ struct token_sysfs_data * data = container_of ( attr , struct token_sysfs_data , location_attr ) ;
438429
439430 if (!capable (CAP_SYS_ADMIN ))
440431 return - EPERM ;
441432
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 );
446434}
447435
448436static ssize_t value_show (struct device * dev ,
449437 struct device_attribute * attr , char * buf )
450438{
451- int i ;
439+ struct token_sysfs_data * data = container_of ( attr , struct token_sysfs_data , value_attr ) ;
452440
453441 if (!capable (CAP_SYS_ADMIN ))
454442 return - EPERM ;
455443
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 );
460445}
461446
462447static struct attribute_group smbios_attribute_group = {
@@ -473,50 +458,48 @@ static int build_tokens_sysfs(struct platform_device *dev)
473458{
474459 char * location_name ;
475460 char * value_name ;
476- size_t size ;
477461 int ret ;
478462 int i , j ;
479463
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 )
484466 return - ENOMEM ;
485- token_value_attrs = kzalloc (size , GFP_KERNEL );
486- if (!token_value_attrs )
487- goto out_allocate_value ;
488467
489468 /* 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 );
492470 if (!token_attrs )
493471 goto out_allocate_attrs ;
494472
495473 for (i = 0 , j = 0 ; i < da_num_tokens ; i ++ ) {
496474 /* skip empty */
497475 if (da_tokens [i ].tokenID == 0 )
498476 continue ;
477+
478+ token_entries [i ].token = & da_tokens [i ];
479+
499480 /* add location */
500481 location_name = kasprintf (GFP_KERNEL , "%04x_location" ,
501482 da_tokens [i ].tokenID );
502483 if (location_name == NULL )
503484 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 ;
509491
510492 /* add value */
511493 value_name = kasprintf (GFP_KERNEL , "%04x_value" ,
512494 da_tokens [i ].tokenID );
513495 if (value_name == NULL )
514496 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 ;
497+
498+ sysfs_attr_init (& token_entries [i ].value_attr .attr );
499+ token_entries [i ].value_attr .attr .name = value_name ;
500+ token_entries [i ].value_attr .attr .mode = 0444 ;
501+ token_entries [i ].value_attr .show = value_show ;
502+ token_attrs [j ++ ] = & token_entries [i ].value_attr .attr ;
520503 continue ;
521504
522505loop_fail_create_value :
@@ -532,14 +515,12 @@ static int build_tokens_sysfs(struct platform_device *dev)
532515
533516out_unwind_strings :
534517 while (i -- ) {
535- kfree (token_location_attrs [i ].attr .name );
536- kfree (token_value_attrs [i ].attr .name );
518+ kfree (token_entries [i ]. location_attr .attr .name );
519+ kfree (token_entries [i ]. value_attr .attr .name );
537520 }
538521 kfree (token_attrs );
539522out_allocate_attrs :
540- kfree (token_value_attrs );
541- out_allocate_value :
542- kfree (token_location_attrs );
523+ kfree (token_entries );
543524
544525 return - ENOMEM ;
545526}
@@ -551,12 +532,11 @@ static void free_group(struct platform_device *pdev)
551532 sysfs_remove_group (& pdev -> dev .kobj ,
552533 & smbios_attribute_group );
553534 for (i = 0 ; i < da_num_tokens ; i ++ ) {
554- kfree (token_location_attrs [i ].attr .name );
555- kfree (token_value_attrs [i ].attr .name );
535+ kfree (token_entries [i ]. location_attr .attr .name );
536+ kfree (token_entries [i ]. value_attr .attr .name );
556537 }
557538 kfree (token_attrs );
558- kfree (token_value_attrs );
559- kfree (token_location_attrs );
539+ kfree (token_entries );
560540}
561541
562542static int __init dell_smbios_init (void )
0 commit comments