2 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
15 #include <linux/slab.h>
16 #include <linux/types.h>
17 #include <linux/stddef.h>
18 #include <linux/module.h>
19 #include <linux/spinlock.h>
20 #include <linux/mISDNif.h>
25 MODULE_AUTHOR("Karsten Keil");
26 MODULE_LICENSE("GPL");
27 module_param(debug
, uint
, S_IRUGO
| S_IWUSR
);
29 static u64 device_ids
;
30 #define MAX_DEVICE_ID 63
32 static LIST_HEAD(Bprotocols
);
33 static DEFINE_RWLOCK(bp_lock
);
35 static void mISDN_dev_release(struct device
*dev
)
37 /* nothing to do: the device is part of its parent's data structure */
40 static ssize_t
id_show(struct device
*dev
,
41 struct device_attribute
*attr
, char *buf
)
43 struct mISDNdevice
*mdev
= dev_to_mISDN(dev
);
47 return sprintf(buf
, "%d\n", mdev
->id
);
49 static DEVICE_ATTR_RO(id
);
51 static ssize_t
nrbchan_show(struct device
*dev
,
52 struct device_attribute
*attr
, char *buf
)
54 struct mISDNdevice
*mdev
= dev_to_mISDN(dev
);
58 return sprintf(buf
, "%d\n", mdev
->nrbchan
);
60 static DEVICE_ATTR_RO(nrbchan
);
62 static ssize_t
d_protocols_show(struct device
*dev
,
63 struct device_attribute
*attr
, char *buf
)
65 struct mISDNdevice
*mdev
= dev_to_mISDN(dev
);
69 return sprintf(buf
, "%d\n", mdev
->Dprotocols
);
71 static DEVICE_ATTR_RO(d_protocols
);
73 static ssize_t
b_protocols_show(struct device
*dev
,
74 struct device_attribute
*attr
, char *buf
)
76 struct mISDNdevice
*mdev
= dev_to_mISDN(dev
);
80 return sprintf(buf
, "%d\n", mdev
->Bprotocols
| get_all_Bprotocols());
82 static DEVICE_ATTR_RO(b_protocols
);
84 static ssize_t
protocol_show(struct device
*dev
,
85 struct device_attribute
*attr
, char *buf
)
87 struct mISDNdevice
*mdev
= dev_to_mISDN(dev
);
91 return sprintf(buf
, "%d\n", mdev
->D
.protocol
);
93 static DEVICE_ATTR_RO(protocol
);
95 static ssize_t
name_show(struct device
*dev
,
96 struct device_attribute
*attr
, char *buf
)
98 strcpy(buf
, dev_name(dev
));
101 static DEVICE_ATTR_RO(name
);
104 static ssize_t
name_set(struct device
*dev
, struct device_attribute
*attr
,
105 const char *buf
, size_t count
)
108 char *out
= kmalloc(count
+ 1, GFP_KERNEL
);
113 memcpy(out
, buf
, count
);
114 if (count
&& out
[count
- 1] == '\n')
117 err
= device_rename(dev
, out
);
120 return (err
< 0) ? err
: count
;
122 static DEVICE_ATTR_RW(name
);
125 static ssize_t
channelmap_show(struct device
*dev
,
126 struct device_attribute
*attr
, char *buf
)
128 struct mISDNdevice
*mdev
= dev_to_mISDN(dev
);
132 for (i
= 0; i
<= mdev
->nrbchan
; i
++)
133 *bp
++ = test_channelmap(i
, mdev
->channelmap
) ? '1' : '0';
137 static DEVICE_ATTR_RO(channelmap
);
139 static struct attribute
*mISDN_attrs
[] = {
141 &dev_attr_d_protocols
.attr
,
142 &dev_attr_b_protocols
.attr
,
143 &dev_attr_protocol
.attr
,
144 &dev_attr_channelmap
.attr
,
145 &dev_attr_nrbchan
.attr
,
149 ATTRIBUTE_GROUPS(mISDN
);
151 static int mISDN_uevent(struct device
*dev
, struct kobj_uevent_env
*env
)
153 struct mISDNdevice
*mdev
= dev_to_mISDN(dev
);
158 if (add_uevent_var(env
, "nchans=%d", mdev
->nrbchan
))
164 static void mISDN_class_release(struct class *cls
)
166 /* do nothing, it's static */
169 static struct class mISDN_class
= {
171 .owner
= THIS_MODULE
,
172 .dev_uevent
= mISDN_uevent
,
173 .dev_groups
= mISDN_groups
,
174 .dev_release
= mISDN_dev_release
,
175 .class_release
= mISDN_class_release
,
179 _get_mdevice(struct device
*dev
, const void *id
)
181 struct mISDNdevice
*mdev
= dev_to_mISDN(dev
);
185 if (mdev
->id
!= *(const u_int
*)id
)
191 *get_mdevice(u_int id
)
193 return dev_to_mISDN(class_find_device(&mISDN_class
, NULL
, &id
,
198 _get_mdevice_count(struct device
*dev
, void *cnt
)
205 get_mdevice_count(void)
209 class_for_each_device(&mISDN_class
, NULL
, &cnt
, _get_mdevice_count
);
218 for (i
= 0; i
<= MAX_DEVICE_ID
; i
++)
219 if (!test_and_set_bit(i
, (u_long
*)&device_ids
))
221 if (i
> MAX_DEVICE_ID
)
227 mISDN_register_device(struct mISDNdevice
*dev
,
228 struct device
*parent
, char *name
)
232 err
= get_free_devid();
237 device_initialize(&dev
->dev
);
239 dev_set_name(&dev
->dev
, "%s", name
);
241 dev_set_name(&dev
->dev
, "mISDN%d", dev
->id
);
242 if (debug
& DEBUG_CORE
)
243 printk(KERN_DEBUG
"mISDN_register %s %d\n",
244 dev_name(&dev
->dev
), dev
->id
);
245 err
= create_stack(dev
);
249 dev
->dev
.class = &mISDN_class
;
250 dev
->dev
.platform_data
= dev
;
251 dev
->dev
.parent
= parent
;
252 dev_set_drvdata(&dev
->dev
, dev
);
254 err
= device_add(&dev
->dev
);
266 EXPORT_SYMBOL(mISDN_register_device
);
269 mISDN_unregister_device(struct mISDNdevice
*dev
) {
270 if (debug
& DEBUG_CORE
)
271 printk(KERN_DEBUG
"mISDN_unregister %s %d\n",
272 dev_name(&dev
->dev
), dev
->id
);
273 /* sysfs_remove_link(&dev->dev.kobj, "device"); */
274 device_del(&dev
->dev
);
275 dev_set_drvdata(&dev
->dev
, NULL
);
277 test_and_clear_bit(dev
->id
, (u_long
*)&device_ids
);
279 put_device(&dev
->dev
);
281 EXPORT_SYMBOL(mISDN_unregister_device
);
284 get_all_Bprotocols(void)
286 struct Bprotocol
*bp
;
290 list_for_each_entry(bp
, &Bprotocols
, list
)
292 read_unlock(&bp_lock
);
297 get_Bprotocol4mask(u_int m
)
299 struct Bprotocol
*bp
;
302 list_for_each_entry(bp
, &Bprotocols
, list
)
303 if (bp
->Bprotocols
& m
) {
304 read_unlock(&bp_lock
);
307 read_unlock(&bp_lock
);
312 get_Bprotocol4id(u_int id
)
316 if (id
< ISDN_P_B_START
|| id
> 63) {
317 printk(KERN_WARNING
"%s id not in range %d\n",
321 m
= 1 << (id
& ISDN_P_B_MASK
);
322 return get_Bprotocol4mask(m
);
326 mISDN_register_Bprotocol(struct Bprotocol
*bp
)
329 struct Bprotocol
*old
;
331 if (debug
& DEBUG_CORE
)
332 printk(KERN_DEBUG
"%s: %s/%x\n", __func__
,
333 bp
->name
, bp
->Bprotocols
);
334 old
= get_Bprotocol4mask(bp
->Bprotocols
);
337 "register duplicate protocol old %s/%x new %s/%x\n",
338 old
->name
, old
->Bprotocols
, bp
->name
, bp
->Bprotocols
);
341 write_lock_irqsave(&bp_lock
, flags
);
342 list_add_tail(&bp
->list
, &Bprotocols
);
343 write_unlock_irqrestore(&bp_lock
, flags
);
346 EXPORT_SYMBOL(mISDN_register_Bprotocol
);
349 mISDN_unregister_Bprotocol(struct Bprotocol
*bp
)
353 if (debug
& DEBUG_CORE
)
354 printk(KERN_DEBUG
"%s: %s/%x\n", __func__
, bp
->name
,
356 write_lock_irqsave(&bp_lock
, flags
);
358 write_unlock_irqrestore(&bp_lock
, flags
);
360 EXPORT_SYMBOL(mISDN_unregister_Bprotocol
);
362 static const char *msg_no_channel
= "<no channel>";
363 static const char *msg_no_stack
= "<no stack>";
364 static const char *msg_no_stackdev
= "<no stack device>";
366 const char *mISDNDevName4ch(struct mISDNchannel
*ch
)
369 return msg_no_channel
;
373 return msg_no_stackdev
;
374 return dev_name(&ch
->st
->dev
->dev
);
376 EXPORT_SYMBOL(mISDNDevName4ch
);
383 printk(KERN_INFO
"Modular ISDN core version %d.%d.%d\n",
384 MISDN_MAJOR_VERSION
, MISDN_MINOR_VERSION
, MISDN_RELEASE
);
385 mISDN_init_clock(&debug
);
386 mISDN_initstack(&debug
);
387 err
= class_register(&mISDN_class
);
390 err
= mISDN_inittimer(&debug
);
393 err
= l1_init(&debug
);
396 err
= Isdnl2_Init(&debug
);
399 err
= misdn_sock_init(&debug
);
409 mISDN_timer_cleanup();
411 class_unregister(&mISDN_class
);
416 static void mISDN_cleanup(void)
418 misdn_sock_cleanup();
421 mISDN_timer_cleanup();
422 class_unregister(&mISDN_class
);
424 printk(KERN_DEBUG
"mISDNcore unloaded\n");
427 module_init(mISDNInit
);
428 module_exit(mISDN_cleanup
);