aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/synclinkmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/synclinkmp.c')
-rw-r--r--drivers/char/synclinkmp.c55
1 files changed, 35 insertions, 20 deletions
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 6bdb44f7bec2..fcf1ec77450d 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -558,6 +558,7 @@ static void release_resources(SLMP_INFO *info);
558 558
559static int startup(SLMP_INFO *info); 559static int startup(SLMP_INFO *info);
560static int block_til_ready(struct tty_struct *tty, struct file * filp,SLMP_INFO *info); 560static int block_til_ready(struct tty_struct *tty, struct file * filp,SLMP_INFO *info);
561static int carrier_raised(struct tty_port *port);
561static void shutdown(SLMP_INFO *info); 562static void shutdown(SLMP_INFO *info);
562static void program_hw(SLMP_INFO *info); 563static void program_hw(SLMP_INFO *info);
563static void change_params(SLMP_INFO *info); 564static void change_params(SLMP_INFO *info);
@@ -3318,7 +3319,17 @@ static int tiocmset(struct tty_struct *tty, struct file *file,
3318 return 0; 3319 return 0;
3319} 3320}
3320 3321
3322static int carrier_raised(struct tty_port *port)
3323{
3324 SLMP_INFO *info = container_of(port, SLMP_INFO, port);
3325 unsigned long flags;
3321 3326
3327 spin_lock_irqsave(&info->lock,flags);
3328 get_signals(info);
3329 spin_unlock_irqrestore(&info->lock,flags);
3330
3331 return (info->serial_signals & SerialSignal_DCD) ? 1 : 0;
3332}
3322 3333
3323/* Block the current process until the specified port is ready to open. 3334/* Block the current process until the specified port is ready to open.
3324 */ 3335 */
@@ -3330,6 +3341,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3330 bool do_clocal = false; 3341 bool do_clocal = false;
3331 bool extra_count = false; 3342 bool extra_count = false;
3332 unsigned long flags; 3343 unsigned long flags;
3344 int cd;
3345 struct tty_port *port = &info->port;
3333 3346
3334 if (debug_level >= DEBUG_LEVEL_INFO) 3347 if (debug_level >= DEBUG_LEVEL_INFO)
3335 printk("%s(%d):%s block_til_ready()\n", 3348 printk("%s(%d):%s block_til_ready()\n",
@@ -3338,7 +3351,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3338 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ 3351 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
3339 /* nonblock mode is set or port is not enabled */ 3352 /* nonblock mode is set or port is not enabled */
3340 /* just verify that callout device is not active */ 3353 /* just verify that callout device is not active */
3341 info->port.flags |= ASYNC_NORMAL_ACTIVE; 3354 port->flags |= ASYNC_NORMAL_ACTIVE;
3342 return 0; 3355 return 0;
3343 } 3356 }
3344 3357
@@ -3347,25 +3360,25 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3347 3360
3348 /* Wait for carrier detect and the line to become 3361 /* Wait for carrier detect and the line to become
3349 * free (i.e., not in use by the callout). While we are in 3362 * free (i.e., not in use by the callout). While we are in
3350 * this loop, info->port.count is dropped by one, so that 3363 * this loop, port->count is dropped by one, so that
3351 * close() knows when to free things. We restore it upon 3364 * close() knows when to free things. We restore it upon
3352 * exit, either normal or abnormal. 3365 * exit, either normal or abnormal.
3353 */ 3366 */
3354 3367
3355 retval = 0; 3368 retval = 0;
3356 add_wait_queue(&info->port.open_wait, &wait); 3369 add_wait_queue(&port->open_wait, &wait);
3357 3370
3358 if (debug_level >= DEBUG_LEVEL_INFO) 3371 if (debug_level >= DEBUG_LEVEL_INFO)
3359 printk("%s(%d):%s block_til_ready() before block, count=%d\n", 3372 printk("%s(%d):%s block_til_ready() before block, count=%d\n",
3360 __FILE__,__LINE__, tty->driver->name, info->port.count ); 3373 __FILE__,__LINE__, tty->driver->name, port->count );
3361 3374
3362 spin_lock_irqsave(&info->lock, flags); 3375 spin_lock_irqsave(&info->lock, flags);
3363 if (!tty_hung_up_p(filp)) { 3376 if (!tty_hung_up_p(filp)) {
3364 extra_count = true; 3377 extra_count = true;
3365 info->port.count--; 3378 port->count--;
3366 } 3379 }
3367 spin_unlock_irqrestore(&info->lock, flags); 3380 spin_unlock_irqrestore(&info->lock, flags);
3368 info->port.blocked_open++; 3381 port->blocked_open++;
3369 3382
3370 while (1) { 3383 while (1) {
3371 if ((tty->termios->c_cflag & CBAUD)) { 3384 if ((tty->termios->c_cflag & CBAUD)) {
@@ -3377,20 +3390,16 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3377 3390
3378 set_current_state(TASK_INTERRUPTIBLE); 3391 set_current_state(TASK_INTERRUPTIBLE);
3379 3392
3380 if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){ 3393 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){
3381 retval = (info->port.flags & ASYNC_HUP_NOTIFY) ? 3394 retval = (port->flags & ASYNC_HUP_NOTIFY) ?
3382 -EAGAIN : -ERESTARTSYS; 3395 -EAGAIN : -ERESTARTSYS;
3383 break; 3396 break;
3384 } 3397 }
3385 3398
3386 spin_lock_irqsave(&info->lock,flags); 3399 cd = tty_port_carrier_raised(port);
3387 get_signals(info);
3388 spin_unlock_irqrestore(&info->lock,flags);
3389 3400
3390 if (!(info->port.flags & ASYNC_CLOSING) && 3401 if (!(port->flags & ASYNC_CLOSING) && (do_clocal || cd))
3391 (do_clocal || (info->serial_signals & SerialSignal_DCD)) ) {
3392 break; 3402 break;
3393 }
3394 3403
3395 if (signal_pending(current)) { 3404 if (signal_pending(current)) {
3396 retval = -ERESTARTSYS; 3405 retval = -ERESTARTSYS;
@@ -3399,24 +3408,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3399 3408
3400 if (debug_level >= DEBUG_LEVEL_INFO) 3409 if (debug_level >= DEBUG_LEVEL_INFO)
3401 printk("%s(%d):%s block_til_ready() count=%d\n", 3410 printk("%s(%d):%s block_til_ready() count=%d\n",
3402 __FILE__,__LINE__, tty->driver->name, info->port.count ); 3411 __FILE__,__LINE__, tty->driver->name, port->count );
3403 3412
3404 schedule(); 3413 schedule();
3405 } 3414 }
3406 3415
3407 set_current_state(TASK_RUNNING); 3416 set_current_state(TASK_RUNNING);
3408 remove_wait_queue(&info->port.open_wait, &wait); 3417 remove_wait_queue(&port->open_wait, &wait);
3409 3418
3410 if (extra_count) 3419 if (extra_count)
3411 info->port.count++; 3420 port->count++;
3412 info->port.blocked_open--; 3421 port->blocked_open--;
3413 3422
3414 if (debug_level >= DEBUG_LEVEL_INFO) 3423 if (debug_level >= DEBUG_LEVEL_INFO)
3415 printk("%s(%d):%s block_til_ready() after, count=%d\n", 3424 printk("%s(%d):%s block_til_ready() after, count=%d\n",
3416 __FILE__,__LINE__, tty->driver->name, info->port.count ); 3425 __FILE__,__LINE__, tty->driver->name, port->count );
3417 3426
3418 if (!retval) 3427 if (!retval)
3419 info->port.flags |= ASYNC_NORMAL_ACTIVE; 3428 port->flags |= ASYNC_NORMAL_ACTIVE;
3420 3429
3421 return retval; 3430 return retval;
3422} 3431}
@@ -3782,6 +3791,10 @@ static void add_device(SLMP_INFO *info)
3782#endif 3791#endif
3783} 3792}
3784 3793
3794static const struct tty_port_operations port_ops = {
3795 .carrier_raised = carrier_raised,
3796};
3797
3785/* Allocate and initialize a device instance structure 3798/* Allocate and initialize a device instance structure
3786 * 3799 *
3787 * Return Value: pointer to SLMP_INFO if success, otherwise NULL 3800 * Return Value: pointer to SLMP_INFO if success, otherwise NULL
@@ -3798,6 +3811,7 @@ static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
3798 __FILE__,__LINE__, adapter_num, port_num); 3811 __FILE__,__LINE__, adapter_num, port_num);
3799 } else { 3812 } else {
3800 tty_port_init(&info->port); 3813 tty_port_init(&info->port);
3814 info->port.ops = &port_ops;
3801 info->magic = MGSL_MAGIC; 3815 info->magic = MGSL_MAGIC;
3802 INIT_WORK(&info->task, bh_handler); 3816 INIT_WORK(&info->task, bh_handler);
3803 info->max_frame_size = 4096; 3817 info->max_frame_size = 4096;
@@ -3940,6 +3954,7 @@ static const struct tty_operations ops = {
3940 .tiocmset = tiocmset, 3954 .tiocmset = tiocmset,
3941}; 3955};
3942 3956
3957
3943static void synclinkmp_cleanup(void) 3958static void synclinkmp_cleanup(void)
3944{ 3959{
3945 int rc; 3960 int rc;