aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/capi
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@web.de>2010-02-08 05:12:25 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-16 19:01:27 -0500
commit40fb2d0da77df5d39f1ba8878502725ebb806554 (patch)
treeb5a35828d01574665b73588d3142a4c2cb0488de /drivers/isdn/capi
parente76b1544074b5fc7983a21fb1f51a7faf03d3179 (diff)
CAPI: Dynamically register minor devices
Register capiminors dynamically with the TTY core so that udev can make them show up as the NCCIs appear or disappear. This removes the need to check if the capiminor requested in capinc_tty_open actually exists. And this completely obsoletes capifs which will be scheduled for removal in a later patch. Signed-off-by: Jan Kiszka <jan.kiszka@web.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn/capi')
-rw-r--r--drivers/isdn/capi/capi.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index c22b34976c24..901b79bc3b56 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -153,6 +153,8 @@ static LIST_HEAD(capidev_list);
153static DEFINE_RWLOCK(capiminors_lock); 153static DEFINE_RWLOCK(capiminors_lock);
154static struct capiminor **capiminors; 154static struct capiminor **capiminors;
155 155
156static struct tty_driver *capinc_tty_driver;
157
156/* -------- datahandles --------------------------------------------- */ 158/* -------- datahandles --------------------------------------------- */
157 159
158static int capiminor_add_ack(struct capiminor *mp, u16 datahandle) 160static int capiminor_add_ack(struct capiminor *mp, u16 datahandle)
@@ -213,6 +215,7 @@ static void capiminor_del_all_ack(struct capiminor *mp)
213static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) 215static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
214{ 216{
215 struct capiminor *mp; 217 struct capiminor *mp;
218 struct device *dev;
216 unsigned int minor; 219 unsigned int minor;
217 unsigned long flags; 220 unsigned long flags;
218 221
@@ -243,19 +246,33 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
243 246
244 if (minor == capi_ttyminors) { 247 if (minor == capi_ttyminors) {
245 printk(KERN_NOTICE "capi: out of minors\n"); 248 printk(KERN_NOTICE "capi: out of minors\n");
246 kfree(mp); 249 goto err_out1;
247 return NULL;
248 } 250 }
249 251
250 mp->minor = minor; 252 mp->minor = minor;
251 253
254 dev = tty_register_device(capinc_tty_driver, minor, NULL);
255 if (IS_ERR(dev))
256 goto err_out2;
257
252 return mp; 258 return mp;
259
260err_out2:
261 write_lock_irqsave(&capiminors_lock, flags);
262 capiminors[minor] = NULL;
263 write_unlock_irqrestore(&capiminors_lock, flags);
264
265err_out1:
266 kfree(mp);
267 return NULL;
253} 268}
254 269
255static void capiminor_free(struct capiminor *mp) 270static void capiminor_free(struct capiminor *mp)
256{ 271{
257 unsigned long flags; 272 unsigned long flags;
258 273
274 tty_unregister_device(capinc_tty_driver, mp->minor);
275
259 write_lock_irqsave(&capiminors_lock, flags); 276 write_lock_irqsave(&capiminors_lock, flags);
260 capiminors[mp->minor] = NULL; 277 capiminors[mp->minor] = NULL;
261 write_unlock_irqrestore(&capiminors_lock, flags); 278 write_unlock_irqrestore(&capiminors_lock, flags);
@@ -268,13 +285,10 @@ static void capiminor_free(struct capiminor *mp)
268 kfree(mp); 285 kfree(mp);
269} 286}
270 287
271static struct capiminor *capiminor_find(unsigned int minor) 288static struct capiminor *capiminor_get(unsigned int minor)
272{ 289{
273 struct capiminor *mp; 290 struct capiminor *mp;
274 291
275 if (minor >= capi_ttyminors)
276 return NULL;
277
278 read_lock(&capiminors_lock); 292 read_lock(&capiminors_lock);
279 mp = capiminors[minor]; 293 mp = capiminors[minor];
280 read_unlock(&capiminors_lock); 294 read_unlock(&capiminors_lock);
@@ -981,8 +995,7 @@ static int capinc_tty_open(struct tty_struct * tty, struct file * file)
981 struct capiminor *mp; 995 struct capiminor *mp;
982 unsigned long flags; 996 unsigned long flags;
983 997
984 if ((mp = capiminor_find(iminor(file->f_path.dentry->d_inode))) == NULL) 998 mp = capiminor_get(iminor(file->f_path.dentry->d_inode));
985 return -ENXIO;
986 if (mp->nccip == NULL) 999 if (mp->nccip == NULL)
987 return -ENXIO; 1000 return -ENXIO;
988 1001
@@ -1284,8 +1297,6 @@ static void capinc_tty_send_xchar(struct tty_struct *tty, char ch)
1284#endif 1297#endif
1285} 1298}
1286 1299
1287static struct tty_driver *capinc_tty_driver;
1288
1289static const struct tty_operations capinc_ops = { 1300static const struct tty_operations capinc_ops = {
1290 .open = capinc_tty_open, 1301 .open = capinc_tty_open,
1291 .close = capinc_tty_close, 1302 .close = capinc_tty_close,
@@ -1339,7 +1350,9 @@ static int __init capinc_tty_init(void)
1339 drv->init_termios.c_oflag = OPOST | ONLCR; 1350 drv->init_termios.c_oflag = OPOST | ONLCR;
1340 drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; 1351 drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1341 drv->init_termios.c_lflag = 0; 1352 drv->init_termios.c_lflag = 0;
1342 drv->flags = TTY_DRIVER_REAL_RAW|TTY_DRIVER_RESET_TERMIOS; 1353 drv->flags =
1354 TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS |
1355 TTY_DRIVER_DYNAMIC_DEV;
1343 tty_set_operations(drv, &capinc_ops); 1356 tty_set_operations(drv, &capinc_ops);
1344 1357
1345 err = tty_register_driver(drv); 1358 err = tty_register_driver(drv);