|
@@ -558,6 +558,7 @@ static void release_resources(SLMP_INFO *info);
|
|
|
|
|
|
static int startup(SLMP_INFO *info);
|
|
static int startup(SLMP_INFO *info);
|
|
static int block_til_ready(struct tty_struct *tty, struct file * filp,SLMP_INFO *info);
|
|
static int block_til_ready(struct tty_struct *tty, struct file * filp,SLMP_INFO *info);
|
|
|
|
+static int carrier_raised(struct tty_port *port);
|
|
static void shutdown(SLMP_INFO *info);
|
|
static void shutdown(SLMP_INFO *info);
|
|
static void program_hw(SLMP_INFO *info);
|
|
static void program_hw(SLMP_INFO *info);
|
|
static void change_params(SLMP_INFO *info);
|
|
static void change_params(SLMP_INFO *info);
|
|
@@ -3318,7 +3319,17 @@ static int tiocmset(struct tty_struct *tty, struct file *file,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int carrier_raised(struct tty_port *port)
|
|
|
|
+{
|
|
|
|
+ SLMP_INFO *info = container_of(port, SLMP_INFO, port);
|
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
|
|
+ spin_lock_irqsave(&info->lock,flags);
|
|
|
|
+ get_signals(info);
|
|
|
|
+ spin_unlock_irqrestore(&info->lock,flags);
|
|
|
|
+
|
|
|
|
+ return (info->serial_signals & SerialSignal_DCD) ? 1 : 0;
|
|
|
|
+}
|
|
|
|
|
|
/* Block the current process until the specified port is ready to open.
|
|
/* Block the current process until the specified port is ready to open.
|
|
*/
|
|
*/
|
|
@@ -3330,6 +3341,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
|
|
bool do_clocal = false;
|
|
bool do_clocal = false;
|
|
bool extra_count = false;
|
|
bool extra_count = false;
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
+ int cd;
|
|
|
|
+ struct tty_port *port = &info->port;
|
|
|
|
|
|
if (debug_level >= DEBUG_LEVEL_INFO)
|
|
if (debug_level >= DEBUG_LEVEL_INFO)
|
|
printk("%s(%d):%s block_til_ready()\n",
|
|
printk("%s(%d):%s block_til_ready()\n",
|
|
@@ -3338,7 +3351,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
|
|
if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
|
|
if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
|
|
/* nonblock mode is set or port is not enabled */
|
|
/* nonblock mode is set or port is not enabled */
|
|
/* just verify that callout device is not active */
|
|
/* just verify that callout device is not active */
|
|
- info->port.flags |= ASYNC_NORMAL_ACTIVE;
|
|
|
|
|
|
+ port->flags |= ASYNC_NORMAL_ACTIVE;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3347,25 +3360,25 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
|
|
|
|
|
|
/* Wait for carrier detect and the line to become
|
|
/* Wait for carrier detect and the line to become
|
|
* free (i.e., not in use by the callout). While we are in
|
|
* free (i.e., not in use by the callout). While we are in
|
|
- * this loop, info->port.count is dropped by one, so that
|
|
|
|
|
|
+ * this loop, port->count is dropped by one, so that
|
|
* close() knows when to free things. We restore it upon
|
|
* close() knows when to free things. We restore it upon
|
|
* exit, either normal or abnormal.
|
|
* exit, either normal or abnormal.
|
|
*/
|
|
*/
|
|
|
|
|
|
retval = 0;
|
|
retval = 0;
|
|
- add_wait_queue(&info->port.open_wait, &wait);
|
|
|
|
|
|
+ add_wait_queue(&port->open_wait, &wait);
|
|
|
|
|
|
if (debug_level >= DEBUG_LEVEL_INFO)
|
|
if (debug_level >= DEBUG_LEVEL_INFO)
|
|
printk("%s(%d):%s block_til_ready() before block, count=%d\n",
|
|
printk("%s(%d):%s block_til_ready() before block, count=%d\n",
|
|
- __FILE__,__LINE__, tty->driver->name, info->port.count );
|
|
|
|
|
|
+ __FILE__,__LINE__, tty->driver->name, port->count );
|
|
|
|
|
|
spin_lock_irqsave(&info->lock, flags);
|
|
spin_lock_irqsave(&info->lock, flags);
|
|
if (!tty_hung_up_p(filp)) {
|
|
if (!tty_hung_up_p(filp)) {
|
|
extra_count = true;
|
|
extra_count = true;
|
|
- info->port.count--;
|
|
|
|
|
|
+ port->count--;
|
|
}
|
|
}
|
|
spin_unlock_irqrestore(&info->lock, flags);
|
|
spin_unlock_irqrestore(&info->lock, flags);
|
|
- info->port.blocked_open++;
|
|
|
|
|
|
+ port->blocked_open++;
|
|
|
|
|
|
while (1) {
|
|
while (1) {
|
|
if ((tty->termios->c_cflag & CBAUD)) {
|
|
if ((tty->termios->c_cflag & CBAUD)) {
|
|
@@ -3377,20 +3390,16 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
|
|
|
|
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
|
|
|
|
- if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){
|
|
|
|
- retval = (info->port.flags & ASYNC_HUP_NOTIFY) ?
|
|
|
|
|
|
+ if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){
|
|
|
|
+ retval = (port->flags & ASYNC_HUP_NOTIFY) ?
|
|
-EAGAIN : -ERESTARTSYS;
|
|
-EAGAIN : -ERESTARTSYS;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- spin_lock_irqsave(&info->lock,flags);
|
|
|
|
- get_signals(info);
|
|
|
|
- spin_unlock_irqrestore(&info->lock,flags);
|
|
|
|
|
|
+ cd = tty_port_carrier_raised(port);
|
|
|
|
|
|
- if (!(info->port.flags & ASYNC_CLOSING) &&
|
|
|
|
- (do_clocal || (info->serial_signals & SerialSignal_DCD)) ) {
|
|
|
|
|
|
+ if (!(port->flags & ASYNC_CLOSING) && (do_clocal || cd))
|
|
break;
|
|
break;
|
|
- }
|
|
|
|
|
|
|
|
if (signal_pending(current)) {
|
|
if (signal_pending(current)) {
|
|
retval = -ERESTARTSYS;
|
|
retval = -ERESTARTSYS;
|
|
@@ -3399,24 +3408,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
|
|
|
|
|
|
if (debug_level >= DEBUG_LEVEL_INFO)
|
|
if (debug_level >= DEBUG_LEVEL_INFO)
|
|
printk("%s(%d):%s block_til_ready() count=%d\n",
|
|
printk("%s(%d):%s block_til_ready() count=%d\n",
|
|
- __FILE__,__LINE__, tty->driver->name, info->port.count );
|
|
|
|
|
|
+ __FILE__,__LINE__, tty->driver->name, port->count );
|
|
|
|
|
|
schedule();
|
|
schedule();
|
|
}
|
|
}
|
|
|
|
|
|
set_current_state(TASK_RUNNING);
|
|
set_current_state(TASK_RUNNING);
|
|
- remove_wait_queue(&info->port.open_wait, &wait);
|
|
|
|
|
|
+ remove_wait_queue(&port->open_wait, &wait);
|
|
|
|
|
|
if (extra_count)
|
|
if (extra_count)
|
|
- info->port.count++;
|
|
|
|
- info->port.blocked_open--;
|
|
|
|
|
|
+ port->count++;
|
|
|
|
+ port->blocked_open--;
|
|
|
|
|
|
if (debug_level >= DEBUG_LEVEL_INFO)
|
|
if (debug_level >= DEBUG_LEVEL_INFO)
|
|
printk("%s(%d):%s block_til_ready() after, count=%d\n",
|
|
printk("%s(%d):%s block_til_ready() after, count=%d\n",
|
|
- __FILE__,__LINE__, tty->driver->name, info->port.count );
|
|
|
|
|
|
+ __FILE__,__LINE__, tty->driver->name, port->count );
|
|
|
|
|
|
if (!retval)
|
|
if (!retval)
|
|
- info->port.flags |= ASYNC_NORMAL_ACTIVE;
|
|
|
|
|
|
+ port->flags |= ASYNC_NORMAL_ACTIVE;
|
|
|
|
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
@@ -3782,6 +3791,10 @@ static void add_device(SLMP_INFO *info)
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static const struct tty_port_operations port_ops = {
|
|
|
|
+ .carrier_raised = carrier_raised,
|
|
|
|
+};
|
|
|
|
+
|
|
/* Allocate and initialize a device instance structure
|
|
/* Allocate and initialize a device instance structure
|
|
*
|
|
*
|
|
* Return Value: pointer to SLMP_INFO if success, otherwise NULL
|
|
* 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)
|
|
__FILE__,__LINE__, adapter_num, port_num);
|
|
__FILE__,__LINE__, adapter_num, port_num);
|
|
} else {
|
|
} else {
|
|
tty_port_init(&info->port);
|
|
tty_port_init(&info->port);
|
|
|
|
+ info->port.ops = &port_ops;
|
|
info->magic = MGSL_MAGIC;
|
|
info->magic = MGSL_MAGIC;
|
|
INIT_WORK(&info->task, bh_handler);
|
|
INIT_WORK(&info->task, bh_handler);
|
|
info->max_frame_size = 4096;
|
|
info->max_frame_size = 4096;
|
|
@@ -3940,6 +3954,7 @@ static const struct tty_operations ops = {
|
|
.tiocmset = tiocmset,
|
|
.tiocmset = tiocmset,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+
|
|
static void synclinkmp_cleanup(void)
|
|
static void synclinkmp_cleanup(void)
|
|
{
|
|
{
|
|
int rc;
|
|
int rc;
|