aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);