1 /* 2 * Copyright 2008 by Karsten Keil <kkeil@novell.com> 3 * 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. 7 * 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. 12 * 13 */ 14 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> 21 #include "core.h" 22 23 static u_int debug; 24 25 MODULE_AUTHOR("Karsten Keil"); 26 MODULE_LICENSE("GPL"); 27 module_param(debug, uint, S_IRUGO | S_IWUSR); 28 29 static u64 device_ids; 30 #define MAX_DEVICE_ID 63 31 32 static LIST_HEAD(Bprotocols); 33 static DEFINE_RWLOCK(bp_lock); 34 35 static void mISDN_dev_release(struct device *dev) 36 { 37 /* nothing to do: the device is part of its parent's data structure */ 38 } 39 40 static ssize_t id_show(struct device *dev, 41 struct device_attribute *attr, char *buf) 42 { 43 struct mISDNdevice *mdev = dev_to_mISDN(dev); 44 45 if (!mdev) 46 return -ENODEV; 47 return sprintf(buf, "%d\n", mdev->id); 48 } 49 static DEVICE_ATTR_RO(id); 50 51 static ssize_t nrbchan_show(struct device *dev, 52 struct device_attribute *attr, char *buf) 53 { 54 struct mISDNdevice *mdev = dev_to_mISDN(dev); 55 56 if (!mdev) 57 return -ENODEV; 58 return sprintf(buf, "%d\n", mdev->nrbchan); 59 } 60 static DEVICE_ATTR_RO(nrbchan); 61 62 static ssize_t d_protocols_show(struct device *dev, 63 struct device_attribute *attr, char *buf) 64 { 65 struct mISDNdevice *mdev = dev_to_mISDN(dev); 66 67 if (!mdev) 68 return -ENODEV; 69 return sprintf(buf, "%d\n", mdev->Dprotocols); 70 } 71 static DEVICE_ATTR_RO(d_protocols); 72 73 static ssize_t b_protocols_show(struct device *dev, 74 struct device_attribute *attr, char *buf) 75 { 76 struct mISDNdevice *mdev = dev_to_mISDN(dev); 77 78 if (!mdev) 79 return -ENODEV; 80 return sprintf(buf, "%d\n", mdev->Bprotocols | get_all_Bprotocols()); 81 } 82 static DEVICE_ATTR_RO(b_protocols); 83 84 static ssize_t protocol_show(struct device *dev, 85 struct device_attribute *attr, char *buf) 86 { 87 struct mISDNdevice *mdev = dev_to_mISDN(dev); 88 89 if (!mdev) 90 return -ENODEV; 91 return sprintf(buf, "%d\n", mdev->D.protocol); 92 } 93 static DEVICE_ATTR_RO(protocol); 94 95 static ssize_t name_show(struct device *dev, 96 struct device_attribute *attr, char *buf) 97 { 98 strcpy(buf, dev_name(dev)); 99 return strlen(buf); 100 } 101 static DEVICE_ATTR_RO(name); 102 103 #if 0 /* hangs */ 104 static ssize_t name_set(struct device *dev, struct device_attribute *attr, 105 const char *buf, size_t count) 106 { 107 int err = 0; 108 char *out = kmalloc(count + 1, GFP_KERNEL); 109 110 if (!out) 111 return -ENOMEM; 112 113 memcpy(out, buf, count); 114 if (count && out[count - 1] == '\n') 115 out[--count] = 0; 116 if (count) 117 err = device_rename(dev, out); 118 kfree(out); 119 120 return (err < 0) ? err : count; 121 } 122 static DEVICE_ATTR_RW(name); 123 #endif 124 125 static ssize_t channelmap_show(struct device *dev, 126 struct device_attribute *attr, char *buf) 127 { 128 struct mISDNdevice *mdev = dev_to_mISDN(dev); 129 char *bp = buf; 130 int i; 131 132 for (i = 0; i <= mdev->nrbchan; i++) 133 *bp++ = test_channelmap(i, mdev->channelmap) ? '1' : '0'; 134 135 return bp - buf; 136 } 137 static DEVICE_ATTR_RO(channelmap); 138 139 static struct attribute *mISDN_attrs[] = { 140 &dev_attr_id.attr, 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, 146 &dev_attr_name.attr, 147 NULL, 148 }; 149 ATTRIBUTE_GROUPS(mISDN); 150 151 static int mISDN_uevent(struct device *dev, struct kobj_uevent_env *env) 152 { 153 struct mISDNdevice *mdev = dev_to_mISDN(dev); 154 155 if (!mdev) 156 return 0; 157 158 if (add_uevent_var(env, "nchans=%d", mdev->nrbchan)) 159 return -ENOMEM; 160 161 return 0; 162 } 163 164 static void mISDN_class_release(struct class *cls) 165 { 166 /* do nothing, it's static */ 167 } 168 169 static struct class mISDN_class = { 170 .name = "mISDN", 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, 176 }; 177 178 static int 179 _get_mdevice(struct device *dev, const void *id) 180 { 181 struct mISDNdevice *mdev = dev_to_mISDN(dev); 182 183 if (!mdev) 184 return 0; 185 if (mdev->id != *(const u_int *)id) 186 return 0; 187 return 1; 188 } 189 190 struct mISDNdevice 191 *get_mdevice(u_int id) 192 { 193 return dev_to_mISDN(class_find_device(&mISDN_class, NULL, &id, 194 _get_mdevice)); 195 } 196 197 static int 198 _get_mdevice_count(struct device *dev, void *cnt) 199 { 200 *(int *)cnt += 1; 201 return 0; 202 } 203 204 int 205 get_mdevice_count(void) 206 { 207 int cnt = 0; 208 209 class_for_each_device(&mISDN_class, NULL, &cnt, _get_mdevice_count); 210 return cnt; 211 } 212 213 static int 214 get_free_devid(void) 215 { 216 u_int i; 217 218 for (i = 0; i <= MAX_DEVICE_ID; i++) 219 if (!test_and_set_bit(i, (u_long *)&device_ids)) 220 break; 221 if (i > MAX_DEVICE_ID) 222 return -EBUSY; 223 return i; 224 } 225 226 int 227 mISDN_register_device(struct mISDNdevice *dev, 228 struct device *parent, char *name) 229 { 230 int err; 231 232 err = get_free_devid(); 233 if (err < 0) 234 goto error1; 235 dev->id = err; 236 237 device_initialize(&dev->dev); 238 if (name && name[0]) 239 dev_set_name(&dev->dev, "%s", name); 240 else 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); 246 if (err) 247 goto error1; 248 249 dev->dev.class = &mISDN_class; 250 dev->dev.platform_data = dev; 251 dev->dev.parent = parent; 252 dev_set_drvdata(&dev->dev, dev); 253 254 err = device_add(&dev->dev); 255 if (err) 256 goto error3; 257 return 0; 258 259 error3: 260 delete_stack(dev); 261 return err; 262 error1: 263 return err; 264 265 } 266 EXPORT_SYMBOL(mISDN_register_device); 267 268 void 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); 276 277 test_and_clear_bit(dev->id, (u_long *)&device_ids); 278 delete_stack(dev); 279 put_device(&dev->dev); 280 } 281 EXPORT_SYMBOL(mISDN_unregister_device); 282 283 u_int 284 get_all_Bprotocols(void) 285 { 286 struct Bprotocol *bp; 287 u_int m = 0; 288 289 read_lock(&bp_lock); 290 list_for_each_entry(bp, &Bprotocols, list) 291 m |= bp->Bprotocols; 292 read_unlock(&bp_lock); 293 return m; 294 } 295 296 struct Bprotocol * 297 get_Bprotocol4mask(u_int m) 298 { 299 struct Bprotocol *bp; 300 301 read_lock(&bp_lock); 302 list_for_each_entry(bp, &Bprotocols, list) 303 if (bp->Bprotocols & m) { 304 read_unlock(&bp_lock); 305 return bp; 306 } 307 read_unlock(&bp_lock); 308 return NULL; 309 } 310 311 struct Bprotocol * 312 get_Bprotocol4id(u_int id) 313 { 314 u_int m; 315 316 if (id < ISDN_P_B_START || id > 63) { 317 printk(KERN_WARNING "%s id not in range %d\n", 318 __func__, id); 319 return NULL; 320 } 321 m = 1 << (id & ISDN_P_B_MASK); 322 return get_Bprotocol4mask(m); 323 } 324 325 int 326 mISDN_register_Bprotocol(struct Bprotocol *bp) 327 { 328 u_long flags; 329 struct Bprotocol *old; 330 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); 335 if (old) { 336 printk(KERN_WARNING 337 "register duplicate protocol old %s/%x new %s/%x\n", 338 old->name, old->Bprotocols, bp->name, bp->Bprotocols); 339 return -EBUSY; 340 } 341 write_lock_irqsave(&bp_lock, flags); 342 list_add_tail(&bp->list, &Bprotocols); 343 write_unlock_irqrestore(&bp_lock, flags); 344 return 0; 345 } 346 EXPORT_SYMBOL(mISDN_register_Bprotocol); 347 348 void 349 mISDN_unregister_Bprotocol(struct Bprotocol *bp) 350 { 351 u_long flags; 352 353 if (debug & DEBUG_CORE) 354 printk(KERN_DEBUG "%s: %s/%x\n", __func__, bp->name, 355 bp->Bprotocols); 356 write_lock_irqsave(&bp_lock, flags); 357 list_del(&bp->list); 358 write_unlock_irqrestore(&bp_lock, flags); 359 } 360 EXPORT_SYMBOL(mISDN_unregister_Bprotocol); 361 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>"; 365 366 const char *mISDNDevName4ch(struct mISDNchannel *ch) 367 { 368 if (!ch) 369 return msg_no_channel; 370 if (!ch->st) 371 return msg_no_stack; 372 if (!ch->st->dev) 373 return msg_no_stackdev; 374 return dev_name(&ch->st->dev->dev); 375 }; 376 EXPORT_SYMBOL(mISDNDevName4ch); 377 378 static int 379 mISDNInit(void) 380 { 381 int err; 382 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); 388 if (err) 389 goto error1; 390 err = mISDN_inittimer(&debug); 391 if (err) 392 goto error2; 393 err = l1_init(&debug); 394 if (err) 395 goto error3; 396 err = Isdnl2_Init(&debug); 397 if (err) 398 goto error4; 399 err = misdn_sock_init(&debug); 400 if (err) 401 goto error5; 402 return 0; 403 404 error5: 405 Isdnl2_cleanup(); 406 error4: 407 l1_cleanup(); 408 error3: 409 mISDN_timer_cleanup(); 410 error2: 411 class_unregister(&mISDN_class); 412 error1: 413 return err; 414 } 415 416 static void mISDN_cleanup(void) 417 { 418 misdn_sock_cleanup(); 419 Isdnl2_cleanup(); 420 l1_cleanup(); 421 mISDN_timer_cleanup(); 422 class_unregister(&mISDN_class); 423 424 printk(KERN_DEBUG "mISDNcore unloaded\n"); 425 } 426 427 module_init(mISDNInit); 428 module_exit(mISDN_cleanup); 429