@@ -363,6 +363,9 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg)
363
363
static void free_msi_irqs (struct pci_dev * dev )
364
364
{
365
365
struct msi_desc * entry , * tmp ;
366
+ struct attribute * * msi_attrs ;
367
+ struct device_attribute * dev_attr ;
368
+ int count = 0 ;
366
369
367
370
list_for_each_entry (entry , & dev -> msi_list , list ) {
368
371
int i , nvec ;
@@ -398,6 +401,22 @@ static void free_msi_irqs(struct pci_dev *dev)
398
401
list_del (& entry -> list );
399
402
kfree (entry );
400
403
}
404
+
405
+ if (dev -> msi_irq_groups ) {
406
+ sysfs_remove_groups (& dev -> dev .kobj , dev -> msi_irq_groups );
407
+ msi_attrs = dev -> msi_irq_groups [0 ]-> attrs ;
408
+ list_for_each_entry (entry , & dev -> msi_list , list ) {
409
+ dev_attr = container_of (msi_attrs [count ],
410
+ struct device_attribute , attr );
411
+ kfree (dev_attr -> attr .name );
412
+ kfree (dev_attr );
413
+ ++ count ;
414
+ }
415
+ kfree (msi_attrs );
416
+ kfree (dev -> msi_irq_groups [0 ]);
417
+ kfree (dev -> msi_irq_groups );
418
+ dev -> msi_irq_groups = NULL ;
419
+ }
401
420
}
402
421
403
422
static struct msi_desc * alloc_msi_entry (struct pci_dev * dev )
@@ -471,94 +490,95 @@ void pci_restore_msi_state(struct pci_dev *dev)
471
490
}
472
491
EXPORT_SYMBOL_GPL (pci_restore_msi_state );
473
492
474
-
475
- #define to_msi_attr (obj ) container_of(obj, struct msi_attribute, attr)
476
- #define to_msi_desc (obj ) container_of(obj, struct msi_desc, kobj)
477
-
478
- struct msi_attribute {
479
- struct attribute attr ;
480
- ssize_t (* show )(struct msi_desc * entry , struct msi_attribute * attr ,
481
- char * buf );
482
- ssize_t (* store )(struct msi_desc * entry , struct msi_attribute * attr ,
483
- const char * buf , size_t count );
484
- };
485
-
486
- static ssize_t show_msi_mode (struct msi_desc * entry , struct msi_attribute * atr ,
493
+ static ssize_t msi_mode_show (struct device * dev , struct device_attribute * attr ,
487
494
char * buf )
488
495
{
489
- return sprintf (buf , "%s\n" , entry -> msi_attrib .is_msix ? "msix" : "msi" );
490
- }
491
-
492
- static ssize_t msi_irq_attr_show (struct kobject * kobj ,
493
- struct attribute * attr , char * buf )
494
- {
495
- struct msi_attribute * attribute = to_msi_attr (attr );
496
- struct msi_desc * entry = to_msi_desc (kobj );
497
-
498
- if (!attribute -> show )
499
- return - EIO ;
500
-
501
- return attribute -> show (entry , attribute , buf );
502
- }
503
-
504
- static const struct sysfs_ops msi_irq_sysfs_ops = {
505
- .show = msi_irq_attr_show ,
506
- };
507
-
508
- static struct msi_attribute mode_attribute =
509
- __ATTR (mode , S_IRUGO , show_msi_mode , NULL );
510
-
511
-
512
- static struct attribute * msi_irq_default_attrs [] = {
513
- & mode_attribute .attr ,
514
- NULL
515
- };
496
+ struct pci_dev * pdev = to_pci_dev (dev );
497
+ struct msi_desc * entry ;
498
+ unsigned long irq ;
499
+ int retval ;
516
500
517
- static void msi_kobj_release ( struct kobject * kobj )
518
- {
519
- struct msi_desc * entry = to_msi_desc ( kobj ) ;
501
+ retval = kstrtoul ( attr -> attr . name , 10 , & irq );
502
+ if ( retval )
503
+ return retval ;
520
504
521
- pci_dev_put (entry -> dev );
505
+ list_for_each_entry (entry , & pdev -> msi_list , list ) {
506
+ if (entry -> irq == irq ) {
507
+ return sprintf (buf , "%s\n" ,
508
+ entry -> msi_attrib .is_msix ? "msix" : "msi" );
509
+ }
510
+ }
511
+ return - ENODEV ;
522
512
}
523
513
524
- static struct kobj_type msi_irq_ktype = {
525
- .release = msi_kobj_release ,
526
- .sysfs_ops = & msi_irq_sysfs_ops ,
527
- .default_attrs = msi_irq_default_attrs ,
528
- };
529
-
530
514
static int populate_msi_sysfs (struct pci_dev * pdev )
531
515
{
516
+ struct attribute * * msi_attrs ;
517
+ struct attribute * msi_attr ;
518
+ struct device_attribute * msi_dev_attr ;
519
+ struct attribute_group * msi_irq_group ;
520
+ const struct attribute_group * * msi_irq_groups ;
532
521
struct msi_desc * entry ;
533
- struct kobject * kobj ;
534
- int ret ;
522
+ int ret = - ENOMEM ;
523
+ int num_msi = 0 ;
535
524
int count = 0 ;
536
525
537
- pdev -> msi_kset = kset_create_and_add ("msi_irqs" , NULL , & pdev -> dev .kobj );
538
- if (!pdev -> msi_kset )
539
- return - ENOMEM ;
526
+ /* Determine how many msi entries we have */
527
+ list_for_each_entry (entry , & pdev -> msi_list , list ) {
528
+ ++ num_msi ;
529
+ }
530
+ if (!num_msi )
531
+ return 0 ;
540
532
533
+ /* Dynamically create the MSI attributes for the PCI device */
534
+ msi_attrs = kzalloc (sizeof (void * ) * (num_msi + 1 ), GFP_KERNEL );
535
+ if (!msi_attrs )
536
+ return - ENOMEM ;
541
537
list_for_each_entry (entry , & pdev -> msi_list , list ) {
542
- kobj = & entry -> kobj ;
543
- kobj -> kset = pdev -> msi_kset ;
544
- pci_dev_get (pdev );
545
- ret = kobject_init_and_add (kobj , & msi_irq_ktype , NULL ,
546
- "%u" , entry -> irq );
547
- if (ret )
548
- goto out_unroll ;
549
-
550
- count ++ ;
538
+ char * name = kmalloc (20 , GFP_KERNEL );
539
+ msi_dev_attr = kzalloc (sizeof (* msi_dev_attr ), GFP_KERNEL );
540
+ if (!msi_dev_attr )
541
+ goto error_attrs ;
542
+ sprintf (name , "%d" , entry -> irq );
543
+ sysfs_attr_init (& msi_dev_attr -> attr );
544
+ msi_dev_attr -> attr .name = name ;
545
+ msi_dev_attr -> attr .mode = S_IRUGO ;
546
+ msi_dev_attr -> show = msi_mode_show ;
547
+ msi_attrs [count ] = & msi_dev_attr -> attr ;
548
+ ++ count ;
551
549
}
552
550
551
+ msi_irq_group = kzalloc (sizeof (* msi_irq_group ), GFP_KERNEL );
552
+ if (!msi_irq_group )
553
+ goto error_attrs ;
554
+ msi_irq_group -> name = "msi_irqs" ;
555
+ msi_irq_group -> attrs = msi_attrs ;
556
+
557
+ msi_irq_groups = kzalloc (sizeof (void * ) * 2 , GFP_KERNEL );
558
+ if (!msi_irq_groups )
559
+ goto error_irq_group ;
560
+ msi_irq_groups [0 ] = msi_irq_group ;
561
+
562
+ ret = sysfs_create_groups (& pdev -> dev .kobj , msi_irq_groups );
563
+ if (ret )
564
+ goto error_irq_groups ;
565
+ pdev -> msi_irq_groups = msi_irq_groups ;
566
+
553
567
return 0 ;
554
568
555
- out_unroll :
556
- list_for_each_entry (entry , & pdev -> msi_list , list ) {
557
- if (!count )
558
- break ;
559
- kobject_del (& entry -> kobj );
560
- kobject_put (& entry -> kobj );
561
- count -- ;
569
+ error_irq_groups :
570
+ kfree (msi_irq_groups );
571
+ error_irq_group :
572
+ kfree (msi_irq_group );
573
+ error_attrs :
574
+ count = 0 ;
575
+ msi_attr = msi_attrs [count ];
576
+ while (msi_attr ) {
577
+ msi_dev_attr = container_of (msi_attr , struct device_attribute , attr );
578
+ kfree (msi_attr -> name );
579
+ kfree (msi_dev_attr );
580
+ ++ count ;
581
+ msi_attr = msi_attrs [count ];
562
582
}
563
583
return ret ;
564
584
}
@@ -925,8 +945,6 @@ void pci_disable_msi(struct pci_dev *dev)
925
945
926
946
pci_msi_shutdown (dev );
927
947
free_msi_irqs (dev );
928
- kset_unregister (dev -> msi_kset );
929
- dev -> msi_kset = NULL ;
930
948
}
931
949
EXPORT_SYMBOL (pci_disable_msi );
932
950
@@ -1023,8 +1041,6 @@ void pci_disable_msix(struct pci_dev *dev)
1023
1041
1024
1042
pci_msix_shutdown (dev );
1025
1043
free_msi_irqs (dev );
1026
- kset_unregister (dev -> msi_kset );
1027
- dev -> msi_kset = NULL ;
1028
1044
}
1029
1045
EXPORT_SYMBOL (pci_disable_msix );
1030
1046
0 commit comments