@@ -270,7 +270,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
270
270
if (!map_found ) {
271
271
map_found = 1 ;
272
272
idev -> map_dir = kobject_create_and_add ("maps" ,
273
- & idev -> dev -> kobj );
273
+ & idev -> dev . kobj );
274
274
if (!idev -> map_dir ) {
275
275
ret = - ENOMEM ;
276
276
goto err_map ;
@@ -299,7 +299,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
299
299
if (!portio_found ) {
300
300
portio_found = 1 ;
301
301
idev -> portio_dir = kobject_create_and_add ("portio" ,
302
- & idev -> dev -> kobj );
302
+ & idev -> dev . kobj );
303
303
if (!idev -> portio_dir ) {
304
304
ret = - ENOMEM ;
305
305
goto err_portio ;
@@ -342,7 +342,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
342
342
kobject_put (& map -> kobj );
343
343
}
344
344
kobject_put (idev -> map_dir );
345
- dev_err (idev -> dev , "error creating sysfs files (%d)\n" , ret );
345
+ dev_err (& idev -> dev , "error creating sysfs files (%d)\n" , ret );
346
346
return ret ;
347
347
}
348
348
@@ -379,7 +379,7 @@ static int uio_get_minor(struct uio_device *idev)
379
379
idev -> minor = retval ;
380
380
retval = 0 ;
381
381
} else if (retval == - ENOSPC ) {
382
- dev_err (idev -> dev , "too many uio devices\n" );
382
+ dev_err (& idev -> dev , "too many uio devices\n" );
383
383
retval = - EINVAL ;
384
384
}
385
385
mutex_unlock (& minor_lock );
@@ -433,6 +433,7 @@ static int uio_open(struct inode *inode, struct file *filep)
433
433
struct uio_device * idev ;
434
434
struct uio_listener * listener ;
435
435
int ret = 0 ;
436
+ unsigned long flags ;
436
437
437
438
mutex_lock (& minor_lock );
438
439
idev = idr_find (& uio_idr , iminor (inode ));
@@ -442,9 +443,11 @@ static int uio_open(struct inode *inode, struct file *filep)
442
443
goto out ;
443
444
}
444
445
446
+ get_device (& idev -> dev );
447
+
445
448
if (!try_module_get (idev -> owner )) {
446
449
ret = - ENODEV ;
447
- goto out ;
450
+ goto err_module_get ;
448
451
}
449
452
450
453
listener = kmalloc (sizeof (* listener ), GFP_KERNEL );
@@ -457,11 +460,13 @@ static int uio_open(struct inode *inode, struct file *filep)
457
460
listener -> event_count = atomic_read (& idev -> event );
458
461
filep -> private_data = listener ;
459
462
460
- if (idev -> info -> open ) {
463
+ spin_lock_irqsave (& idev -> info_lock , flags );
464
+ if (idev -> info && idev -> info -> open )
461
465
ret = idev -> info -> open (idev -> info , inode );
462
- if (ret )
463
- goto err_infoopen ;
464
- }
466
+ spin_unlock_irqrestore (& idev -> info_lock , flags );
467
+ if (ret )
468
+ goto err_infoopen ;
469
+
465
470
return 0 ;
466
471
467
472
err_infoopen :
@@ -470,6 +475,9 @@ static int uio_open(struct inode *inode, struct file *filep)
470
475
err_alloc_listener :
471
476
module_put (idev -> owner );
472
477
478
+ err_module_get :
479
+ put_device (& idev -> dev );
480
+
473
481
out :
474
482
return ret ;
475
483
}
@@ -487,22 +495,33 @@ static int uio_release(struct inode *inode, struct file *filep)
487
495
int ret = 0 ;
488
496
struct uio_listener * listener = filep -> private_data ;
489
497
struct uio_device * idev = listener -> dev ;
498
+ unsigned long flags ;
490
499
491
- if (idev -> info -> release )
500
+ spin_lock_irqsave (& idev -> info_lock , flags );
501
+ if (idev -> info && idev -> info -> release )
492
502
ret = idev -> info -> release (idev -> info , inode );
503
+ spin_unlock_irqrestore (& idev -> info_lock , flags );
493
504
494
505
module_put (idev -> owner );
495
506
kfree (listener );
507
+ put_device (& idev -> dev );
496
508
return ret ;
497
509
}
498
510
499
511
static __poll_t uio_poll (struct file * filep , poll_table * wait )
500
512
{
501
513
struct uio_listener * listener = filep -> private_data ;
502
514
struct uio_device * idev = listener -> dev ;
515
+ __poll_t ret = 0 ;
516
+ unsigned long flags ;
503
517
504
- if (!idev -> info -> irq )
505
- return - EIO ;
518
+ spin_lock_irqsave (& idev -> info_lock , flags );
519
+ if (!idev -> info || !idev -> info -> irq )
520
+ ret = - EIO ;
521
+ spin_unlock_irqrestore (& idev -> info_lock , flags );
522
+
523
+ if (ret )
524
+ return ret ;
506
525
507
526
poll_wait (filep , & idev -> wait , wait );
508
527
if (listener -> event_count != atomic_read (& idev -> event ))
@@ -516,11 +535,17 @@ static ssize_t uio_read(struct file *filep, char __user *buf,
516
535
struct uio_listener * listener = filep -> private_data ;
517
536
struct uio_device * idev = listener -> dev ;
518
537
DECLARE_WAITQUEUE (wait , current );
519
- ssize_t retval ;
538
+ ssize_t retval = 0 ;
520
539
s32 event_count ;
540
+ unsigned long flags ;
521
541
522
- if (!idev -> info -> irq )
523
- return - EIO ;
542
+ spin_lock_irqsave (& idev -> info_lock , flags );
543
+ if (!idev -> info || !idev -> info -> irq )
544
+ retval = - EIO ;
545
+ spin_unlock_irqrestore (& idev -> info_lock , flags );
546
+
547
+ if (retval )
548
+ return retval ;
524
549
525
550
if (count != sizeof (s32 ))
526
551
return - EINVAL ;
@@ -567,8 +592,10 @@ static ssize_t uio_write(struct file *filep, const char __user *buf,
567
592
struct uio_device * idev = listener -> dev ;
568
593
ssize_t retval ;
569
594
s32 irq_on ;
595
+ unsigned long flags ;
570
596
571
- if (!idev -> info -> irq ) {
597
+ spin_lock_irqsave (& idev -> info_lock , flags );
598
+ if (!idev -> info || !idev -> info -> irq ) {
572
599
retval = - EIO ;
573
600
goto out ;
574
601
}
@@ -591,6 +618,7 @@ static ssize_t uio_write(struct file *filep, const char __user *buf,
591
618
retval = idev -> info -> irqcontrol (idev -> info , irq_on );
592
619
593
620
out :
621
+ spin_unlock_irqrestore (& idev -> info_lock , flags );
594
622
return retval ? retval : sizeof (s32 );
595
623
}
596
624
@@ -803,6 +831,13 @@ static void release_uio_class(void)
803
831
uio_major_cleanup ();
804
832
}
805
833
834
+ static void uio_device_release (struct device * dev )
835
+ {
836
+ struct uio_device * idev = dev_get_drvdata (dev );
837
+
838
+ kfree (idev );
839
+ }
840
+
806
841
/**
807
842
* uio_register_device - register a new userspace IO device
808
843
* @owner: module that creates the new device
@@ -823,28 +858,34 @@ int __uio_register_device(struct module *owner,
823
858
824
859
info -> uio_dev = NULL ;
825
860
826
- idev = devm_kzalloc ( parent , sizeof (* idev ), GFP_KERNEL );
861
+ idev = kzalloc ( sizeof (* idev ), GFP_KERNEL );
827
862
if (!idev ) {
828
863
return - ENOMEM ;
829
864
}
830
865
831
866
idev -> owner = owner ;
832
867
idev -> info = info ;
868
+ spin_lock_init (& idev -> info_lock );
833
869
init_waitqueue_head (& idev -> wait );
834
870
atomic_set (& idev -> event , 0 );
835
871
836
872
ret = uio_get_minor (idev );
837
873
if (ret )
838
874
return ret ;
839
875
840
- idev -> dev = device_create (& uio_class , parent ,
841
- MKDEV (uio_major , idev -> minor ), idev ,
842
- "uio%d" , idev -> minor );
843
- if (IS_ERR (idev -> dev )) {
844
- printk (KERN_ERR "UIO: device register failed\n" );
845
- ret = PTR_ERR (idev -> dev );
876
+ idev -> dev .devt = MKDEV (uio_major , idev -> minor );
877
+ idev -> dev .class = & uio_class ;
878
+ idev -> dev .parent = parent ;
879
+ idev -> dev .release = uio_device_release ;
880
+ dev_set_drvdata (& idev -> dev , idev );
881
+
882
+ ret = dev_set_name (& idev -> dev , "uio%d" , idev -> minor );
883
+ if (ret )
884
+ goto err_device_create ;
885
+
886
+ ret = device_register (& idev -> dev );
887
+ if (ret )
846
888
goto err_device_create ;
847
- }
848
889
849
890
ret = uio_dev_add_attributes (idev );
850
891
if (ret )
@@ -872,7 +913,7 @@ int __uio_register_device(struct module *owner,
872
913
err_request_irq :
873
914
uio_dev_del_attributes (idev );
874
915
err_uio_dev_add_attributes :
875
- device_destroy ( & uio_class , MKDEV ( uio_major , idev -> minor ) );
916
+ device_unregister ( & idev -> dev );
876
917
err_device_create :
877
918
uio_free_minor (idev );
878
919
return ret ;
@@ -887,6 +928,7 @@ EXPORT_SYMBOL_GPL(__uio_register_device);
887
928
void uio_unregister_device (struct uio_info * info )
888
929
{
889
930
struct uio_device * idev ;
931
+ unsigned long flags ;
890
932
891
933
if (!info || !info -> uio_dev )
892
934
return ;
@@ -900,7 +942,11 @@ void uio_unregister_device(struct uio_info *info)
900
942
if (info -> irq && info -> irq != UIO_IRQ_CUSTOM )
901
943
free_irq (info -> irq , idev );
902
944
903
- device_destroy (& uio_class , MKDEV (uio_major , idev -> minor ));
945
+ spin_lock_irqsave (& idev -> info_lock , flags );
946
+ idev -> info = NULL ;
947
+ spin_unlock_irqrestore (& idev -> info_lock , flags );
948
+
949
+ device_unregister (& idev -> dev );
904
950
905
951
return ;
906
952
}
0 commit comments