Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 185200
b: refs/heads/master
c: 266794e
h: refs/heads/master
v: v3
  • Loading branch information
Alan Cox authored and Greg Kroah-Hartman committed Mar 2, 2010
1 parent 84b4c9e commit 429451f
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 48 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8b197a5ce7a7218bb9fc721647ba0d5734f27348
refs/heads/master: 266794eb71cfee65b38371954b9db2f6dbda207c
115 changes: 68 additions & 47 deletions trunk/drivers/char/nozomi.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,8 @@ struct port {
struct mutex tty_sem;
wait_queue_head_t tty_wait;
struct async_icount tty_icount;

struct nozomi *dc;
};

/* Private data one for each card in the system */
Expand Down Expand Up @@ -414,6 +416,8 @@ MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl);
static struct nozomi *ndevs[NOZOMI_MAX_CARDS];
static struct tty_driver *ntty_driver;

static const struct tty_port_operations noz_tty_port_ops;

/*
* find card by tty_index
*/
Expand Down Expand Up @@ -1473,9 +1477,11 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,

for (i = 0; i < MAX_PORT; i++) {
struct device *tty_dev;

mutex_init(&dc->port[i].tty_sem);
tty_port_init(&dc->port[i].port);
struct port *port = &dc->port[i];
port->dc = dc;
mutex_init(&port->tty_sem);
tty_port_init(&port->port);
port->port.ops = &noz_tty_port_ops;
tty_dev = tty_register_device(ntty_driver, dc->index_start + i,
&pdev->dev);

Expand Down Expand Up @@ -1600,67 +1606,74 @@ static void set_dtr(const struct tty_struct *tty, int dtr)
* ----------------------------------------------------------------------------
*/

/* Called when the userspace process opens the tty, /dev/noz*. */
static int ntty_open(struct tty_struct *tty, struct file *file)
static int ntty_install(struct tty_driver *driver, struct tty_struct *tty)
{
struct port *port = get_port_by_tty(tty);
struct nozomi *dc = get_dc_by_tty(tty);
unsigned long flags;

int ret;
if (!port || !dc || dc->state != NOZOMI_STATE_READY)
return -ENODEV;

if (mutex_lock_interruptible(&port->tty_sem))
return -ERESTARTSYS;

port->port.count++;
dc->open_ttys++;

/* Enable interrupt downlink for channel */
if (port->port.count == 1) {
tty->driver_data = port;
tty_port_tty_set(&port->port, tty);
DBG1("open: %d", port->token_dl);
spin_lock_irqsave(&dc->spin_mutex, flags);
dc->last_ier = dc->last_ier | port->token_dl;
writew(dc->last_ier, dc->reg_ier);
spin_unlock_irqrestore(&dc->spin_mutex, flags);
ret = tty_init_termios(tty);
if (ret == 0) {
tty_driver_kref_get(driver);
driver->ttys[tty->index] = tty;
}
mutex_unlock(&port->tty_sem);
return 0;
return ret;
}

/* Called when the userspace process close the tty, /dev/noz*. Also
called immediately if ntty_open fails in which case tty->driver_data
will be NULL an we exit by the first return */
static void ntty_cleanup(struct tty_struct *tty)
{
tty->driver_data = NULL;
}

static void ntty_close(struct tty_struct *tty, struct file *file)
static int ntty_activate(struct tty_port *tport, struct tty_struct *tty)
{
struct nozomi *dc = get_dc_by_tty(tty);
struct port *nport = tty->driver_data;
struct tty_port *port = &nport->port;
struct port *port = container_of(tport, struct port, port);
struct nozomi *dc = port->dc;
unsigned long flags;

if (!dc || !nport)
return;
DBG1("open: %d", port->token_dl);
spin_lock_irqsave(&dc->spin_mutex, flags);
dc->last_ier = dc->last_ier | port->token_dl;
writew(dc->last_ier, dc->reg_ier);
dc->open_ttys++;
spin_unlock_irqrestore(&dc->spin_mutex, flags);
printk("noz: activated %d: %p\n", tty->index, tport);
return 0;
}

/* Users cannot interrupt a close */
mutex_lock(&nport->tty_sem);
static int ntty_open(struct tty_struct *tty, struct file *filp)
{
struct port *port = get_port_by_tty(tty);
return tty_port_open(&port->port, tty, filp);
}

WARN_ON(!port->count);
static void ntty_shutdown(struct tty_port *tport)
{
struct port *port = container_of(tport, struct port, port);
struct nozomi *dc = port->dc;
unsigned long flags;

DBG1("close: %d", port->token_dl);
spin_lock_irqsave(&dc->spin_mutex, flags);
dc->last_ier &= ~(port->token_dl);
writew(dc->last_ier, dc->reg_ier);
dc->open_ttys--;
port->count--;
spin_unlock_irqrestore(&dc->spin_mutex, flags);
printk("noz: shutdown %p\n", tport);
}

if (port->count == 0) {
DBG1("close: %d", nport->token_dl);
tty_port_tty_set(port, NULL);
spin_lock_irqsave(&dc->spin_mutex, flags);
dc->last_ier &= ~(nport->token_dl);
writew(dc->last_ier, dc->reg_ier);
spin_unlock_irqrestore(&dc->spin_mutex, flags);
}
mutex_unlock(&nport->tty_sem);
static void ntty_close(struct tty_struct *tty, struct file *filp)
{
struct port *port = tty->driver_data;
if (port)
tty_port_close(&port->port, tty, filp);
}

static void ntty_hangup(struct tty_struct *tty)
{
struct port *port = tty->driver_data;
tty_port_hangup(&port->port);
}

/*
Expand Down Expand Up @@ -1906,17 +1919,25 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty)
return rval;
}

static const struct tty_port_operations noz_tty_port_ops = {
.activate = ntty_activate,
.shutdown = ntty_shutdown,
};

static const struct tty_operations tty_ops = {
.ioctl = ntty_ioctl,
.open = ntty_open,
.close = ntty_close,
.hangup = ntty_hangup,
.write = ntty_write,
.write_room = ntty_write_room,
.unthrottle = ntty_unthrottle,
.throttle = ntty_throttle,
.chars_in_buffer = ntty_chars_in_buffer,
.tiocmget = ntty_tiocmget,
.tiocmset = ntty_tiocmset,
.install = ntty_install,
.cleanup = ntty_cleanup,
};

/* Module initialization */
Expand Down

0 comments on commit 429451f

Please sign in to comment.