at v2.6.27-rc2 90 lines 1.8 kB view raw
1#include <linux/kernel.h> 2#include <linux/spinlock.h> 3#include <linux/device.h> 4#include <linux/idr.h> 5#include <linux/kdev_t.h> 6#include <linux/err.h> 7#include <linux/dca.h> 8 9static struct class *dca_class; 10static struct idr dca_idr; 11static spinlock_t dca_idr_lock; 12 13int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot) 14{ 15 struct device *cd; 16 static int req_count; 17 18 cd = device_create_drvdata(dca_class, dca->cd, 19 MKDEV(0, slot + 1), NULL, 20 "requester%d", req_count++); 21 if (IS_ERR(cd)) 22 return PTR_ERR(cd); 23 return 0; 24} 25 26void dca_sysfs_remove_req(struct dca_provider *dca, int slot) 27{ 28 device_destroy(dca_class, MKDEV(0, slot + 1)); 29} 30 31int dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev) 32{ 33 struct device *cd; 34 int err = 0; 35 36idr_try_again: 37 if (!idr_pre_get(&dca_idr, GFP_KERNEL)) 38 return -ENOMEM; 39 spin_lock(&dca_idr_lock); 40 err = idr_get_new(&dca_idr, dca, &dca->id); 41 spin_unlock(&dca_idr_lock); 42 switch (err) { 43 case 0: 44 break; 45 case -EAGAIN: 46 goto idr_try_again; 47 default: 48 return err; 49 } 50 51 cd = device_create_drvdata(dca_class, dev, MKDEV(0, 0), NULL, 52 "dca%d", dca->id); 53 if (IS_ERR(cd)) { 54 spin_lock(&dca_idr_lock); 55 idr_remove(&dca_idr, dca->id); 56 spin_unlock(&dca_idr_lock); 57 return PTR_ERR(cd); 58 } 59 dca->cd = cd; 60 return 0; 61} 62 63void dca_sysfs_remove_provider(struct dca_provider *dca) 64{ 65 device_unregister(dca->cd); 66 dca->cd = NULL; 67 spin_lock(&dca_idr_lock); 68 idr_remove(&dca_idr, dca->id); 69 spin_unlock(&dca_idr_lock); 70} 71 72int __init dca_sysfs_init(void) 73{ 74 idr_init(&dca_idr); 75 spin_lock_init(&dca_idr_lock); 76 77 dca_class = class_create(THIS_MODULE, "dca"); 78 if (IS_ERR(dca_class)) { 79 idr_destroy(&dca_idr); 80 return PTR_ERR(dca_class); 81 } 82 return 0; 83} 84 85void __exit dca_sysfs_exit(void) 86{ 87 class_destroy(dca_class); 88 idr_destroy(&dca_idr); 89} 90