diff options
-rw-r--r-- | drivers/isdn/capi/capi.c | 35 |
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); | |||
153 | static DEFINE_RWLOCK(capiminors_lock); | 153 | static DEFINE_RWLOCK(capiminors_lock); |
154 | static struct capiminor **capiminors; | 154 | static struct capiminor **capiminors; |
155 | 155 | ||
156 | static struct tty_driver *capinc_tty_driver; | ||
157 | |||
156 | /* -------- datahandles --------------------------------------------- */ | 158 | /* -------- datahandles --------------------------------------------- */ |
157 | 159 | ||
158 | static int capiminor_add_ack(struct capiminor *mp, u16 datahandle) | 160 | static int capiminor_add_ack(struct capiminor *mp, u16 datahandle) |
@@ -213,6 +215,7 @@ static void capiminor_del_all_ack(struct capiminor *mp) | |||
213 | static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) | 215 | static 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 | |||
260 | err_out2: | ||
261 | write_lock_irqsave(&capiminors_lock, flags); | ||
262 | capiminors[minor] = NULL; | ||
263 | write_unlock_irqrestore(&capiminors_lock, flags); | ||
264 | |||
265 | err_out1: | ||
266 | kfree(mp); | ||
267 | return NULL; | ||
253 | } | 268 | } |
254 | 269 | ||
255 | static void capiminor_free(struct capiminor *mp) | 270 | static 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 | ||
271 | static struct capiminor *capiminor_find(unsigned int minor) | 288 | static 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 | ||
1287 | static struct tty_driver *capinc_tty_driver; | ||
1288 | |||
1289 | static const struct tty_operations capinc_ops = { | 1300 | static 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); |