aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/dgnc/dgnc_tty.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/dgnc/dgnc_tty.c')
-rw-r--r--drivers/staging/dgnc/dgnc_tty.c180
1 files changed, 70 insertions, 110 deletions
diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c
index 4eeecc992a02..953d9310fa74 100644
--- a/drivers/staging/dgnc/dgnc_tty.c
+++ b/drivers/staging/dgnc/dgnc_tty.c
@@ -45,7 +45,6 @@
/*
* internal variables
*/
-static struct dgnc_board *dgnc_BoardsByMajor[256];
static unsigned char *dgnc_TmpWriteBuf;
/*
@@ -100,7 +99,7 @@ static void dgnc_tty_unthrottle(struct tty_struct *tty);
static void dgnc_tty_flush_chars(struct tty_struct *tty);
static void dgnc_tty_flush_buffer(struct tty_struct *tty);
static void dgnc_tty_hangup(struct tty_struct *tty);
-static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command,
+static int dgnc_set_modem_info(struct channel_t *ch, unsigned int command,
unsigned int __user *value);
static int dgnc_get_modem_info(struct channel_t *ch,
unsigned int __user *value);
@@ -186,7 +185,8 @@ int dgnc_tty_register(struct dgnc_board *brd)
if (IS_ERR(brd->serial_driver))
return PTR_ERR(brd->serial_driver);
- snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgnc_%d_", brd->boardnum);
+ snprintf(brd->serial_name, MAXTTYNAMELEN, "tty_dgnc_%d_",
+ brd->boardnum);
brd->serial_driver->name = brd->serial_name;
brd->serial_driver->name_base = 0;
@@ -203,15 +203,11 @@ int dgnc_tty_register(struct dgnc_board *brd)
*/
tty_set_operations(brd->serial_driver, &dgnc_tty_ops);
- if (!brd->dgnc_major_serial_registered) {
- /* Register tty devices */
- rc = tty_register_driver(brd->serial_driver);
- if (rc < 0) {
- dev_dbg(&brd->pdev->dev,
- "Can't register tty device (%d)\n", rc);
- goto free_serial_driver;
- }
- brd->dgnc_major_serial_registered = true;
+ rc = tty_register_driver(brd->serial_driver);
+ if (rc < 0) {
+ dev_dbg(&brd->pdev->dev,
+ "Can't register tty device (%d)\n", rc);
+ goto free_serial_driver;
}
/*
@@ -246,20 +242,14 @@ int dgnc_tty_register(struct dgnc_board *brd)
*/
tty_set_operations(brd->print_driver, &dgnc_tty_ops);
- if (!brd->dgnc_major_transparent_print_registered) {
- /* Register Transparent Print devices */
- rc = tty_register_driver(brd->print_driver);
- if (rc < 0) {
- dev_dbg(&brd->pdev->dev,
- "Can't register Transparent Print device(%d)\n",
- rc);
- goto free_print_driver;
- }
- brd->dgnc_major_transparent_print_registered = true;
+ rc = tty_register_driver(brd->print_driver);
+ if (rc < 0) {
+ dev_dbg(&brd->pdev->dev,
+ "Can't register Transparent Print device(%d)\n",
+ rc);
+ goto free_print_driver;
}
- dgnc_BoardsByMajor[brd->serial_driver->major] = brd;
-
return 0;
free_print_driver:
@@ -272,6 +262,14 @@ free_serial_driver:
return rc;
}
+void dgnc_tty_unregister(struct dgnc_board *brd)
+{
+ tty_unregister_driver(brd->print_driver);
+ tty_unregister_driver(brd->serial_driver);
+ put_tty_driver(brd->print_driver);
+ put_tty_driver(brd->serial_driver);
+}
+
/*
* dgnc_tty_init()
*
@@ -378,38 +376,30 @@ void dgnc_tty_post_uninit(void)
}
/*
- * dgnc_tty_uninit()
+ * dgnc_cleanup_tty()
*
* Uninitialize the TTY portion of this driver. Free all memory and
* resources.
*/
-void dgnc_tty_uninit(struct dgnc_board *brd)
+void dgnc_cleanup_tty(struct dgnc_board *brd)
{
int i = 0;
- if (brd->dgnc_major_serial_registered) {
- dgnc_BoardsByMajor[brd->serial_driver->major] = NULL;
- for (i = 0; i < brd->nasync; i++) {
- if (brd->channels[i])
- dgnc_remove_tty_sysfs(brd->channels[i]->
- ch_tun.un_sysfs);
- tty_unregister_device(brd->serial_driver, i);
- }
- tty_unregister_driver(brd->serial_driver);
- brd->dgnc_major_serial_registered = false;
+ for (i = 0; i < brd->nasync; i++) {
+ if (brd->channels[i])
+ dgnc_remove_tty_sysfs(brd->channels[i]->
+ ch_tun.un_sysfs);
+ tty_unregister_device(brd->serial_driver, i);
}
+ tty_unregister_driver(brd->serial_driver);
- if (brd->dgnc_major_transparent_print_registered) {
- dgnc_BoardsByMajor[brd->print_driver->major] = NULL;
- for (i = 0; i < brd->nasync; i++) {
- if (brd->channels[i])
- dgnc_remove_tty_sysfs(brd->channels[i]->
- ch_pun.un_sysfs);
- tty_unregister_device(brd->print_driver, i);
- }
- tty_unregister_driver(brd->print_driver);
- brd->dgnc_major_transparent_print_registered = false;
+ for (i = 0; i < brd->nasync; i++) {
+ if (brd->channels[i])
+ dgnc_remove_tty_sysfs(brd->channels[i]->
+ ch_pun.un_sysfs);
+ tty_unregister_device(brd->print_driver, i);
}
+ tty_unregister_driver(brd->print_driver);
put_tty_driver(brd->serial_driver);
put_tty_driver(brd->print_driver);
@@ -640,19 +630,12 @@ exit_unlock:
************************************************************************/
void dgnc_carrier(struct channel_t *ch)
{
- struct dgnc_board *bd;
-
int virt_carrier = 0;
int phys_carrier = 0;
if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
return;
- bd = ch->ch_bd;
-
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return;
-
if (ch->ch_mistat & UART_MSR_DCD)
phys_carrier = 1;
@@ -947,6 +930,24 @@ void dgnc_wakeup_writes(struct channel_t *ch)
spin_unlock_irqrestore(&ch->ch_lock, flags);
}
+struct dgnc_board *find_board_by_major(unsigned int major)
+{
+ int i;
+
+ for (i = 0; i < MAXBOARDS; i++) {
+ struct dgnc_board *brd = dgnc_board[i];
+
+ if (!brd)
+ return NULL;
+
+ if (major == brd->serial_driver->major ||
+ major == brd->print_driver->major)
+ return brd;
+ }
+
+ return NULL;
+}
+
/************************************************************************
*
* TTY Entry points and helper functions
@@ -976,7 +977,7 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
return -ENXIO;
/* Get board pointer from our array of majors we have allocated */
- brd = dgnc_BoardsByMajor[major];
+ brd = find_board_by_major(major);
if (!brd)
return -ENXIO;
@@ -1172,17 +1173,12 @@ static int dgnc_block_til_ready(struct tty_struct *tty,
struct channel_t *ch)
{
int retval = 0;
- struct un_t *un = NULL;
+ struct un_t *un = tty->driver_data;
unsigned long flags;
uint old_flags = 0;
int sleep_on_un_flags = 0;
- if (!tty || tty->magic != TTY_MAGIC || !file || !ch ||
- ch->magic != DGNC_CHANNEL_MAGIC)
- return -ENXIO;
-
- un = tty->driver_data;
- if (!un || un->magic != DGNC_UNIT_MAGIC)
+ if (!file)
return -ENXIO;
spin_lock_irqsave(&ch->ch_lock, flags);
@@ -1301,15 +1297,9 @@ static int dgnc_block_til_ready(struct tty_struct *tty,
*/
static void dgnc_tty_hangup(struct tty_struct *tty)
{
- struct un_t *un;
-
if (!tty || tty->magic != TTY_MAGIC)
return;
- un = tty->driver_data;
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return;
-
/* flush the transmit queues */
dgnc_tty_flush_buffer(tty);
}
@@ -1510,18 +1500,8 @@ static int dgnc_tty_chars_in_buffer(struct tty_struct *tty)
* returns the new bytes_available. This only affects printer
* output.
*/
-static int dgnc_maxcps_room(struct tty_struct *tty, int bytes_available)
+static int dgnc_maxcps_room(struct channel_t *ch, int bytes_available)
{
- struct un_t *un = tty->driver_data;
- struct channel_t *ch = un->un_ch;
-
- /*
- * If its not the Transparent print device, return
- * the full data amount.
- */
- if (un->un_type != DGNC_PRINT)
- return bytes_available;
-
if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0) {
int cps_limit = 0;
unsigned long current_time = jiffies;
@@ -1585,7 +1565,8 @@ static int dgnc_tty_write_room(struct tty_struct *tty)
ret += WQUEUESIZE;
/* Limit printer to maxcps */
- ret = dgnc_maxcps_room(tty, ret);
+ if (un->un_type != DGNC_PRINT)
+ ret = dgnc_maxcps_room(ch, ret);
/*
* If we are printer device, leave space for
@@ -1677,7 +1658,8 @@ static int dgnc_tty_write(struct tty_struct *tty,
* Limit printer output to maxcps overall, with bursts allowed
* up to bufsize characters.
*/
- bufcount = dgnc_maxcps_room(tty, bufcount);
+ if (un->un_type != DGNC_PRINT)
+ bufcount = dgnc_maxcps_room(ch, bufcount);
/*
* Take minimum of what the user wants to send, and the
@@ -1984,7 +1966,7 @@ static void dgnc_tty_send_xchar(struct tty_struct *tty, char c)
static inline int dgnc_get_mstat(struct channel_t *ch)
{
unsigned char mstat;
- int result = -EIO;
+ int result = 0;
unsigned long flags;
if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
@@ -1996,8 +1978,6 @@ static inline int dgnc_get_mstat(struct channel_t *ch)
spin_unlock_irqrestore(&ch->ch_lock, flags);
- result = 0;
-
if (mstat & UART_MCR_DTR)
result |= TIOCM_DTR;
if (mstat & UART_MCR_RTS)
@@ -2028,32 +2008,14 @@ static int dgnc_get_modem_info(struct channel_t *ch,
*
* Set modem signals, called by ld.
*/
-static int dgnc_set_modem_info(struct tty_struct *tty,
+static int dgnc_set_modem_info(struct channel_t *ch,
unsigned int command,
unsigned int __user *value)
{
- struct dgnc_board *bd;
- struct channel_t *ch;
- struct un_t *un;
int ret = -ENXIO;
unsigned int arg = 0;
unsigned long flags;
- if (!tty || tty->magic != TTY_MAGIC)
- return ret;
-
- un = tty->driver_data;
- if (!un || un->magic != DGNC_UNIT_MAGIC)
- return ret;
-
- ch = un->un_ch;
- if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
- return ret;
-
- bd = ch->ch_bd;
- if (!bd || bd->magic != DGNC_BOARD_MAGIC)
- return ret;
-
ret = get_user(arg, value);
if (ret)
return ret;
@@ -2593,9 +2555,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
spin_unlock_irqrestore(&ch->ch_lock, flags);
- rc = put_user(C_CLOCAL(tty) ? 1 : 0,
- (unsigned long __user *)arg);
- return rc;
+ return put_user(C_CLOCAL(tty) ? 1 : 0,
+ (unsigned long __user *)arg);
case TIOCSSOFTCAR:
@@ -2620,7 +2581,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
case TIOCMBIC:
case TIOCMSET:
spin_unlock_irqrestore(&ch->ch_lock, flags);
- return dgnc_set_modem_info(tty, cmd, uarg);
+ return dgnc_set_modem_info(ch, cmd, uarg);
/*
* Here are any additional ioctl's that we want to implement
@@ -2766,8 +2727,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
case DIGI_GETCUSTOMBAUD:
spin_unlock_irqrestore(&ch->ch_lock, flags);
- rc = put_user(ch->ch_custom_speed, (unsigned int __user *)arg);
- return rc;
+ return put_user(ch->ch_custom_speed,
+ (unsigned int __user *)arg);
case DIGI_SETCUSTOMBAUD:
{
@@ -2853,8 +2814,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
events |= (EV_IPU | EV_IPS);
spin_unlock_irqrestore(&ch->ch_lock, flags);
- rc = put_user(events, (unsigned int __user *)arg);
- return rc;
+ return put_user(events, (unsigned int __user *)arg);
}
/*