This source file includes following definitions.
- w1_register_family
- w1_unregister_family
- w1_family_registered
- __w1_family_put
- w1_family_put
- w1_family_get
- __w1_family_get
   1 
   2 
   3 
   4 
   5 
   6 #include <linux/spinlock.h>
   7 #include <linux/list.h>
   8 #include <linux/sched/signal.h>
   9 #include <linux/delay.h>
  10 #include <linux/export.h>
  11 
  12 #include "w1_internal.h"
  13 
  14 DEFINE_SPINLOCK(w1_flock);
  15 static LIST_HEAD(w1_families);
  16 
  17 
  18 
  19 
  20 
  21 int w1_register_family(struct w1_family *newf)
  22 {
  23         struct list_head *ent, *n;
  24         struct w1_family *f;
  25         int ret = 0;
  26 
  27         spin_lock(&w1_flock);
  28         list_for_each_safe(ent, n, &w1_families) {
  29                 f = list_entry(ent, struct w1_family, family_entry);
  30 
  31                 if (f->fid == newf->fid) {
  32                         ret = -EEXIST;
  33                         break;
  34                 }
  35         }
  36 
  37         if (!ret) {
  38                 atomic_set(&newf->refcnt, 0);
  39                 list_add_tail(&newf->family_entry, &w1_families);
  40         }
  41         spin_unlock(&w1_flock);
  42 
  43         
  44         w1_reconnect_slaves(newf, 1);
  45 
  46         return ret;
  47 }
  48 EXPORT_SYMBOL(w1_register_family);
  49 
  50 
  51 
  52 
  53 
  54 void w1_unregister_family(struct w1_family *fent)
  55 {
  56         struct list_head *ent, *n;
  57         struct w1_family *f;
  58 
  59         spin_lock(&w1_flock);
  60         list_for_each_safe(ent, n, &w1_families) {
  61                 f = list_entry(ent, struct w1_family, family_entry);
  62 
  63                 if (f->fid == fent->fid) {
  64                         list_del(&fent->family_entry);
  65                         break;
  66                 }
  67         }
  68         spin_unlock(&w1_flock);
  69 
  70         
  71         w1_reconnect_slaves(fent, 0);
  72 
  73         while (atomic_read(&fent->refcnt)) {
  74                 pr_info("Waiting for family %u to become free: refcnt=%d.\n",
  75                                 fent->fid, atomic_read(&fent->refcnt));
  76 
  77                 if (msleep_interruptible(1000))
  78                         flush_signals(current);
  79         }
  80 }
  81 EXPORT_SYMBOL(w1_unregister_family);
  82 
  83 
  84 
  85 
  86 struct w1_family * w1_family_registered(u8 fid)
  87 {
  88         struct list_head *ent, *n;
  89         struct w1_family *f = NULL;
  90         int ret = 0;
  91 
  92         list_for_each_safe(ent, n, &w1_families) {
  93                 f = list_entry(ent, struct w1_family, family_entry);
  94 
  95                 if (f->fid == fid) {
  96                         ret = 1;
  97                         break;
  98                 }
  99         }
 100 
 101         return (ret) ? f : NULL;
 102 }
 103 
 104 static void __w1_family_put(struct w1_family *f)
 105 {
 106         atomic_dec(&f->refcnt);
 107 }
 108 
 109 void w1_family_put(struct w1_family *f)
 110 {
 111         spin_lock(&w1_flock);
 112         __w1_family_put(f);
 113         spin_unlock(&w1_flock);
 114 }
 115 
 116 #if 0
 117 void w1_family_get(struct w1_family *f)
 118 {
 119         spin_lock(&w1_flock);
 120         __w1_family_get(f);
 121         spin_unlock(&w1_flock);
 122 }
 123 #endif  
 124 
 125 void __w1_family_get(struct w1_family *f)
 126 {
 127         smp_mb__before_atomic();
 128         atomic_inc(&f->refcnt);
 129         smp_mb__after_atomic();
 130 }