Commit 7b369697 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

[PATCH] USB: keyspan_pda: add support for new tty tiocmget and tiocmset functions.

parent a64171f2
...@@ -455,6 +455,8 @@ static void edge_unthrottle (struct usb_serial_port *port); ...@@ -455,6 +455,8 @@ static void edge_unthrottle (struct usb_serial_port *port);
static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios); static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios);
static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg); static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg);
static void edge_break (struct usb_serial_port *port, int break_state); static void edge_break (struct usb_serial_port *port, int break_state);
static int edge_tiocmget (struct usb_serial_port *port, struct file *file);
static int edge_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
static int edge_startup (struct usb_serial *serial); static int edge_startup (struct usb_serial *serial);
static void edge_shutdown (struct usb_serial *serial); static void edge_shutdown (struct usb_serial *serial);
...@@ -1762,42 +1764,27 @@ static int get_number_bytes_avail(struct edgeport_port *edge_port, unsigned int ...@@ -1762,42 +1764,27 @@ static int get_number_bytes_avail(struct edgeport_port *edge_port, unsigned int
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
} }
static int set_modem_info(struct edgeport_port *edge_port, unsigned int cmd, unsigned int *value) static int edge_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear)
{ {
unsigned int mcr = edge_port->shadowMCR; struct edgeport_port *edge_port = usb_get_serial_port_data(port);
unsigned int arg; unsigned int mcr;
if (copy_from_user(&arg, value, sizeof(int)))
return -EFAULT;
switch (cmd) {
case TIOCMBIS:
if (arg & TIOCM_RTS)
mcr |= MCR_RTS;
if (arg & TIOCM_DTR)
mcr |= MCR_RTS;
if (arg & TIOCM_LOOP)
mcr |= MCR_LOOPBACK;
break;
case TIOCMBIC: dbg("%s - port %d", __FUNCTION__, port->number);
if (arg & TIOCM_RTS)
mcr &= ~MCR_RTS;
if (arg & TIOCM_DTR)
mcr &= ~MCR_RTS;
if (arg & TIOCM_LOOP)
mcr &= ~MCR_LOOPBACK;
break;
case TIOCMSET: mcr = edge_port->shadowMCR;
/* turn off the RTS and DTR and LOOPBACK if (set & TIOCM_RTS)
* and then only turn on what was asked to */ mcr |= MCR_RTS;
mcr &= ~(MCR_RTS | MCR_DTR | MCR_LOOPBACK); if (set & TIOCM_DTR)
mcr |= ((arg & TIOCM_RTS) ? MCR_RTS : 0); mcr |= MCR_DTR;
mcr |= ((arg & TIOCM_DTR) ? MCR_DTR : 0); if (set & TIOCM_LOOP)
mcr |= ((arg & TIOCM_LOOP) ? MCR_LOOPBACK : 0); mcr |= MCR_LOOPBACK;
break;
} if (clear & TIOCM_RTS)
mcr &= ~MCR_RTS;
if (clear & TIOCM_DTR)
mcr &= ~MCR_DTR;
if (clear & TIOCM_LOOP)
mcr &= ~MCR_LOOPBACK;
edge_port->shadowMCR = mcr; edge_port->shadowMCR = mcr;
...@@ -1806,12 +1793,17 @@ static int set_modem_info(struct edgeport_port *edge_port, unsigned int cmd, uns ...@@ -1806,12 +1793,17 @@ static int set_modem_info(struct edgeport_port *edge_port, unsigned int cmd, uns
return 0; return 0;
} }
static int get_modem_info(struct edgeport_port *edge_port, unsigned int *value) static int edge_tiocmget(struct usb_serial_port *port, struct file *file)
{ {
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
unsigned int result = 0; unsigned int result = 0;
unsigned int msr = edge_port->shadowMSR; unsigned int msr;
unsigned int mcr = edge_port->shadowMCR; unsigned int mcr;
dbg("%s - port %d", __FUNCTION__, port->number);
msr = edge_port->shadowMSR;
mcr = edge_port->shadowMCR;
result = ((mcr & MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */ result = ((mcr & MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */
| ((mcr & MCR_RTS) ? TIOCM_RTS: 0) /* 0x004 */ | ((mcr & MCR_RTS) ? TIOCM_RTS: 0) /* 0x004 */
| ((msr & MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */ | ((msr & MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */
...@@ -1822,13 +1814,9 @@ static int get_modem_info(struct edgeport_port *edge_port, unsigned int *value) ...@@ -1822,13 +1814,9 @@ static int get_modem_info(struct edgeport_port *edge_port, unsigned int *value)
dbg("%s -- %x", __FUNCTION__, result); dbg("%s -- %x", __FUNCTION__, result);
if (copy_to_user(value, &result, sizeof(int))) return result;
return -EFAULT;
return 0;
} }
static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct * retinfo) static int get_serial_info(struct edgeport_port *edge_port, struct serial_struct * retinfo)
{ {
struct serial_struct tmp; struct serial_struct tmp;
...@@ -1885,16 +1873,6 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned ...@@ -1885,16 +1873,6 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned
return get_lsr_info(edge_port, (unsigned int *) arg); return get_lsr_info(edge_port, (unsigned int *) arg);
return 0; return 0;
case TIOCMBIS:
case TIOCMBIC:
case TIOCMSET:
dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __FUNCTION__, port->number);
return set_modem_info(edge_port, cmd, (unsigned int *) arg);
case TIOCMGET:
dbg("%s (%d) TIOCMGET", __FUNCTION__, port->number);
return get_modem_info(edge_port, (unsigned int *) arg);
case TIOCGSERIAL: case TIOCGSERIAL:
dbg("%s (%d) TIOCGSERIAL", __FUNCTION__, port->number); dbg("%s (%d) TIOCGSERIAL", __FUNCTION__, port->number);
return get_serial_info(edge_port, (struct serial_struct *) arg); return get_serial_info(edge_port, (struct serial_struct *) arg);
......
...@@ -114,6 +114,8 @@ static struct usb_serial_device_type edgeport_1port_device = { ...@@ -114,6 +114,8 @@ static struct usb_serial_device_type edgeport_1port_device = {
.shutdown = edge_shutdown, .shutdown = edge_shutdown,
.ioctl = edge_ioctl, .ioctl = edge_ioctl,
.set_termios = edge_set_termios, .set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
.tiocmset = edge_tiocmset,
.write = edge_write, .write = edge_write,
.write_room = edge_write_room, .write_room = edge_write_room,
.chars_in_buffer = edge_chars_in_buffer, .chars_in_buffer = edge_chars_in_buffer,
...@@ -137,6 +139,8 @@ static struct usb_serial_device_type edgeport_2port_device = { ...@@ -137,6 +139,8 @@ static struct usb_serial_device_type edgeport_2port_device = {
.shutdown = edge_shutdown, .shutdown = edge_shutdown,
.ioctl = edge_ioctl, .ioctl = edge_ioctl,
.set_termios = edge_set_termios, .set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
.tiocmset = edge_tiocmset,
.write = edge_write, .write = edge_write,
.write_room = edge_write_room, .write_room = edge_write_room,
.chars_in_buffer = edge_chars_in_buffer, .chars_in_buffer = edge_chars_in_buffer,
...@@ -160,6 +164,8 @@ static struct usb_serial_device_type edgeport_4port_device = { ...@@ -160,6 +164,8 @@ static struct usb_serial_device_type edgeport_4port_device = {
.shutdown = edge_shutdown, .shutdown = edge_shutdown,
.ioctl = edge_ioctl, .ioctl = edge_ioctl,
.set_termios = edge_set_termios, .set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
.tiocmset = edge_tiocmset,
.write = edge_write, .write = edge_write,
.write_room = edge_write_room, .write_room = edge_write_room,
.chars_in_buffer = edge_chars_in_buffer, .chars_in_buffer = edge_chars_in_buffer,
...@@ -183,6 +189,8 @@ static struct usb_serial_device_type edgeport_8port_device = { ...@@ -183,6 +189,8 @@ static struct usb_serial_device_type edgeport_8port_device = {
.shutdown = edge_shutdown, .shutdown = edge_shutdown,
.ioctl = edge_ioctl, .ioctl = edge_ioctl,
.set_termios = edge_set_termios, .set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
.tiocmset = edge_tiocmset,
.write = edge_write, .write = edge_write,
.write_room = edge_write_room, .write_room = edge_write_room,
.chars_in_buffer = edge_chars_in_buffer, .chars_in_buffer = edge_chars_in_buffer,
......
...@@ -2403,42 +2403,27 @@ static void edge_set_termios (struct usb_serial_port *port, struct termios *old_ ...@@ -2403,42 +2403,27 @@ static void edge_set_termios (struct usb_serial_port *port, struct termios *old_
return; return;
} }
static int set_modem_info (struct edgeport_port *edge_port, unsigned int cmd, unsigned int *value) static int edge_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear)
{ {
unsigned int mcr = edge_port->shadow_mcr; struct edgeport_port *edge_port = usb_get_serial_port_data(port);
unsigned int arg; unsigned int mcr;
if (copy_from_user(&arg, value, sizeof(int))) dbg("%s - port %d", __FUNCTION__, port->number);
return -EFAULT;
switch (cmd) {
case TIOCMBIS:
if (arg & TIOCM_RTS)
mcr |= MCR_RTS;
if (arg & TIOCM_DTR)
mcr |= MCR_RTS;
if (arg & TIOCM_LOOP)
mcr |= MCR_LOOPBACK;
break;
case TIOCMBIC:
if (arg & TIOCM_RTS)
mcr &= ~MCR_RTS;
if (arg & TIOCM_DTR)
mcr &= ~MCR_RTS;
if (arg & TIOCM_LOOP)
mcr &= ~MCR_LOOPBACK;
break;
case TIOCMSET: mcr = edge_port->shadow_mcr;
/* turn off the RTS and DTR and LOOPBACK if (set & TIOCM_RTS)
* and then only turn on what was asked to */ mcr |= MCR_RTS;
mcr &= ~(MCR_RTS | MCR_DTR | MCR_LOOPBACK); if (set & TIOCM_DTR)
mcr |= ((arg & TIOCM_RTS) ? MCR_RTS : 0); mcr |= MCR_DTR;
mcr |= ((arg & TIOCM_DTR) ? MCR_DTR : 0); if (set & TIOCM_LOOP)
mcr |= ((arg & TIOCM_LOOP) ? MCR_LOOPBACK : 0); mcr |= MCR_LOOPBACK;
break;
} if (clear & TIOCM_RTS)
mcr &= ~MCR_RTS;
if (clear & TIOCM_DTR)
mcr &= ~MCR_DTR;
if (clear & TIOCM_LOOP)
mcr &= ~MCR_LOOPBACK;
edge_port->shadow_mcr = mcr; edge_port->shadow_mcr = mcr;
...@@ -2447,12 +2432,17 @@ static int set_modem_info (struct edgeport_port *edge_port, unsigned int cmd, un ...@@ -2447,12 +2432,17 @@ static int set_modem_info (struct edgeport_port *edge_port, unsigned int cmd, un
return 0; return 0;
} }
static int get_modem_info (struct edgeport_port *edge_port, unsigned int *value) static int edge_tiocmget(struct usb_serial_port *port, struct file *file)
{ {
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
unsigned int result = 0; unsigned int result = 0;
unsigned int msr = edge_port->shadow_msr; unsigned int msr;
unsigned int mcr = edge_port->shadow_mcr; unsigned int mcr;
dbg("%s - port %d", __FUNCTION__, port->number);
msr = edge_port->shadow_msr;
mcr = edge_port->shadow_mcr;
result = ((mcr & MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */ result = ((mcr & MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */
| ((mcr & MCR_RTS) ? TIOCM_RTS: 0) /* 0x004 */ | ((mcr & MCR_RTS) ? TIOCM_RTS: 0) /* 0x004 */
| ((msr & MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */ | ((msr & MSR_CTS) ? TIOCM_CTS: 0) /* 0x020 */
...@@ -2463,9 +2453,7 @@ static int get_modem_info (struct edgeport_port *edge_port, unsigned int *value) ...@@ -2463,9 +2453,7 @@ static int get_modem_info (struct edgeport_port *edge_port, unsigned int *value)
dbg("%s -- %x", __FUNCTION__, result); dbg("%s -- %x", __FUNCTION__, result);
if (copy_to_user(value, &result, sizeof(int))) return result;
return -EFAULT;
return 0;
} }
static int get_serial_info (struct edgeport_port *edge_port, struct serial_struct * retinfo) static int get_serial_info (struct edgeport_port *edge_port, struct serial_struct * retinfo)
...@@ -2515,18 +2503,6 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned ...@@ -2515,18 +2503,6 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned
// return get_lsr_info(edge_port, (unsigned int *) arg); // return get_lsr_info(edge_port, (unsigned int *) arg);
break; break;
case TIOCMBIS:
case TIOCMBIC:
case TIOCMSET:
dbg("%s - (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __FUNCTION__, port->number);
return set_modem_info(edge_port, cmd, (unsigned int *) arg);
break;
case TIOCMGET:
dbg("%s - (%d) TIOCMGET", __FUNCTION__, port->number);
return get_modem_info(edge_port, (unsigned int *) arg);
break;
case TIOCGSERIAL: case TIOCGSERIAL:
dbg("%s - (%d) TIOCGSERIAL", __FUNCTION__, port->number); dbg("%s - (%d) TIOCGSERIAL", __FUNCTION__, port->number);
return get_serial_info(edge_port, (struct serial_struct *) arg); return get_serial_info(edge_port, (struct serial_struct *) arg);
...@@ -2665,6 +2641,8 @@ static struct usb_serial_device_type edgeport_1port_device = { ...@@ -2665,6 +2641,8 @@ static struct usb_serial_device_type edgeport_1port_device = {
.shutdown = edge_shutdown, .shutdown = edge_shutdown,
.ioctl = edge_ioctl, .ioctl = edge_ioctl,
.set_termios = edge_set_termios, .set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
.tiocmset = edge_tiocmset,
.write = edge_write, .write = edge_write,
.write_room = edge_write_room, .write_room = edge_write_room,
.chars_in_buffer = edge_chars_in_buffer, .chars_in_buffer = edge_chars_in_buffer,
...@@ -2688,6 +2666,8 @@ static struct usb_serial_device_type edgeport_2port_device = { ...@@ -2688,6 +2666,8 @@ static struct usb_serial_device_type edgeport_2port_device = {
.shutdown = edge_shutdown, .shutdown = edge_shutdown,
.ioctl = edge_ioctl, .ioctl = edge_ioctl,
.set_termios = edge_set_termios, .set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
.tiocmset = edge_tiocmset,
.write = edge_write, .write = edge_write,
.write_room = edge_write_room, .write_room = edge_write_room,
.chars_in_buffer = edge_chars_in_buffer, .chars_in_buffer = edge_chars_in_buffer,
......
...@@ -282,48 +282,46 @@ static void keyspan_set_termios (struct usb_serial_port *port, ...@@ -282,48 +282,46 @@ static void keyspan_set_termios (struct usb_serial_port *port,
keyspan_send_setup(port, 0); keyspan_send_setup(port, 0);
} }
static int keyspan_ioctl(struct usb_serial_port *port, struct file *file, static int keyspan_tiocmget(struct usb_serial_port *port, struct file *file)
unsigned int cmd, unsigned long arg)
{ {
unsigned int value, set; unsigned int value;
struct keyspan_port_private *p_priv; struct keyspan_port_private *p_priv;
p_priv = usb_get_serial_port_data(port); p_priv = usb_get_serial_port_data(port);
switch (cmd) { value = ((p_priv->rts_state) ? TIOCM_RTS : 0) |
case TIOCMGET: ((p_priv->dtr_state) ? TIOCM_DTR : 0) |
value = ((p_priv->rts_state) ? TIOCM_RTS : 0) | ((p_priv->cts_state) ? TIOCM_CTS : 0) |
((p_priv->dtr_state) ? TIOCM_DTR : 0) | ((p_priv->dsr_state) ? TIOCM_DSR : 0) |
((p_priv->cts_state) ? TIOCM_CTS : 0) | ((p_priv->dcd_state) ? TIOCM_CAR : 0) |
((p_priv->dsr_state) ? TIOCM_DSR : 0) | ((p_priv->ri_state) ? TIOCM_RNG : 0);
((p_priv->dcd_state) ? TIOCM_CAR : 0) |
((p_priv->ri_state) ? TIOCM_RNG : 0); return value;
}
if (put_user(value, (unsigned int *) arg))
return -EFAULT; static int keyspan_tiocmset(struct usb_serial_port *port, struct file *file,
return 0; unsigned int set, unsigned int clear)
{
struct keyspan_port_private *p_priv;
p_priv = usb_get_serial_port_data(port);
case TIOCMSET: if (set & TIOCM_RTS)
if (get_user(value, (unsigned int *) arg)) p_priv->rts_state = 1;
return -EFAULT; if (set & TIOCM_DTR)
p_priv->rts_state = ((value & TIOCM_RTS) ? 1 : 0); p_priv->dtr_state = 1;
p_priv->dtr_state = ((value & TIOCM_DTR) ? 1 : 0);
keyspan_send_setup(port, 0); if (clear & TIOCM_RTS)
return 0; p_priv->rts_state = 0;
if (clear & TIOCM_DTR)
case TIOCMBIS: p_priv->dtr_state = 0;
case TIOCMBIC: keyspan_send_setup(port, 0);
if (get_user(value, (unsigned int *) arg)) return 0;
return -EFAULT; }
set = (cmd == TIOCMBIS);
if (value & TIOCM_RTS)
p_priv->rts_state = set;
if (value & TIOCM_DTR)
p_priv->dtr_state = set;
keyspan_send_setup(port, 0);
return 0;
}
static int keyspan_ioctl(struct usb_serial_port *port, struct file *file,
unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
} }
......
...@@ -63,6 +63,11 @@ static void keyspan_set_termios (struct usb_serial_port *port, ...@@ -63,6 +63,11 @@ static void keyspan_set_termios (struct usb_serial_port *port,
struct termios *old); struct termios *old);
static void keyspan_break_ctl (struct usb_serial_port *port, static void keyspan_break_ctl (struct usb_serial_port *port,
int break_state); int break_state);
static int keyspan_tiocmget (struct usb_serial_port *port,
struct file *file);
static int keyspan_tiocmset (struct usb_serial_port *port,
struct file *file, unsigned int set,
unsigned int clear);
static int keyspan_fake_startup (struct usb_serial *serial); static int keyspan_fake_startup (struct usb_serial *serial);
static int keyspan_usa19_calc_baud (u32 baud_rate, u32 baudclk, static int keyspan_usa19_calc_baud (u32 baud_rate, u32 baudclk,
...@@ -551,6 +556,8 @@ static struct usb_serial_device_type keyspan_1port_device = { ...@@ -551,6 +556,8 @@ static struct usb_serial_device_type keyspan_1port_device = {
.ioctl = keyspan_ioctl, .ioctl = keyspan_ioctl,
.set_termios = keyspan_set_termios, .set_termios = keyspan_set_termios,
.break_ctl = keyspan_break_ctl, .break_ctl = keyspan_break_ctl,
.tiocmget = keyspan_tiocmget,
.tiocmset = keyspan_tiocmset,
.attach = keyspan_startup, .attach = keyspan_startup,
.shutdown = keyspan_shutdown, .shutdown = keyspan_shutdown,
}; };
...@@ -574,6 +581,8 @@ static struct usb_serial_device_type keyspan_2port_device = { ...@@ -574,6 +581,8 @@ static struct usb_serial_device_type keyspan_2port_device = {
.ioctl = keyspan_ioctl, .ioctl = keyspan_ioctl,
.set_termios = keyspan_set_termios, .set_termios = keyspan_set_termios,
.break_ctl = keyspan_break_ctl, .break_ctl = keyspan_break_ctl,
.tiocmget = keyspan_tiocmget,
.tiocmset = keyspan_tiocmset,
.attach = keyspan_startup, .attach = keyspan_startup,
.shutdown = keyspan_shutdown, .shutdown = keyspan_shutdown,
}; };
...@@ -597,6 +606,8 @@ static struct usb_serial_device_type keyspan_4port_device = { ...@@ -597,6 +606,8 @@ static struct usb_serial_device_type keyspan_4port_device = {
.ioctl = keyspan_ioctl, .ioctl = keyspan_ioctl,
.set_termios = keyspan_set_termios, .set_termios = keyspan_set_termios,
.break_ctl = keyspan_break_ctl, .break_ctl = keyspan_break_ctl,
.tiocmget = keyspan_tiocmget,
.tiocmset = keyspan_tiocmset,
.attach = keyspan_startup, .attach = keyspan_startup,
.shutdown = keyspan_shutdown, .shutdown = keyspan_shutdown,
}; };
......
...@@ -457,62 +457,54 @@ static int keyspan_pda_set_modem_info(struct usb_serial *serial, ...@@ -457,62 +457,54 @@ static int keyspan_pda_set_modem_info(struct usb_serial *serial,
return rc; return rc;
} }
static int keyspan_pda_tiocmget(struct usb_serial_port *port, struct file *file)
{
struct usb_serial *serial = port->serial;
int rc;
unsigned char status;
int value;
static int keyspan_pda_ioctl(struct usb_serial_port *port, struct file *file, rc = keyspan_pda_get_modem_info(serial, &status);
unsigned int cmd, unsigned long arg) if (rc < 0)
return rc;
value =
((status & (1<<7)) ? TIOCM_DTR : 0) |
((status & (1<<6)) ? TIOCM_CAR : 0) |
((status & (1<<5)) ? TIOCM_RNG : 0) |
((status & (1<<4)) ? TIOCM_DSR : 0) |
((status & (1<<3)) ? TIOCM_CTS : 0) |
((status & (1<<2)) ? TIOCM_RTS : 0);
return value;
}
static int keyspan_pda_tiocmset(struct usb_serial_port *port, struct file *file,
unsigned int set, unsigned int clear)
{ {
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
int rc; int rc;
unsigned int value; unsigned char status;
unsigned char status, mask;
rc = keyspan_pda_get_modem_info(serial, &status);
if (rc < 0)
return rc;
if (set & TIOCM_RTS)
status |= (1<<2);
if (set & TIOCM_DTR)
status |= (1<<7);
if (clear & TIOCM_RTS)
status &= ~(1<<2);
if (clear & TIOCM_DTR)
status &= ~(1<<7);
rc = keyspan_pda_set_modem_info(serial, status);
return rc;
}
static int keyspan_pda_ioctl(struct usb_serial_port *port, struct file *file,
unsigned int cmd, unsigned long arg)
{
switch (cmd) { switch (cmd) {
case TIOCMGET: /* get modem pins state */
rc = keyspan_pda_get_modem_info(serial, &status);
if (rc < 0)
return rc;
value =
((status & (1<<7)) ? TIOCM_DTR : 0) |
((status & (1<<6)) ? TIOCM_CAR : 0) |
((status & (1<<5)) ? TIOCM_RNG : 0) |
((status & (1<<4)) ? TIOCM_DSR : 0) |
((status & (1<<3)) ? TIOCM_CTS : 0) |
((status & (1<<2)) ? TIOCM_RTS : 0);
if (copy_to_user((unsigned int *)arg, &value, sizeof(int)))
return -EFAULT;
return 0;
case TIOCMSET: /* set a state as returned by MGET */
if (copy_from_user(&value, (unsigned int *)arg, sizeof(int)))
return -EFAULT;
status =
((value & TIOCM_DTR) ? (1<<7) : 0) |
((value & TIOCM_CAR) ? (1<<6) : 0) |
((value & TIOCM_RNG) ? (1<<5) : 0) |
((value & TIOCM_DSR) ? (1<<4) : 0) |
((value & TIOCM_CTS) ? (1<<3) : 0) |
((value & TIOCM_RTS) ? (1<<2) : 0);
rc = keyspan_pda_set_modem_info(serial, status);
if (rc < 0)
return rc;
return 0;
case TIOCMBIS: /* set bits in bitmask <arg> */
case TIOCMBIC: /* clear bits from bitmask <arg> */
if (copy_from_user(&value, (unsigned int *)arg, sizeof(int)))
return -EFAULT;
rc = keyspan_pda_get_modem_info(serial, &status);
if (rc < 0)
return rc;
mask =
((value & TIOCM_RTS) ? (1<<2) : 0) |
((value & TIOCM_DTR) ? (1<<7) : 0);
if (cmd == TIOCMBIS)
status |= mask;
else
status &= ~mask;
rc = keyspan_pda_set_modem_info(serial, status);
if (rc < 0)
return rc;
return 0;
case TIOCMIWAIT: case TIOCMIWAIT:
/* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/ /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
/* TODO */ /* TODO */
...@@ -874,6 +866,8 @@ static struct usb_serial_device_type keyspan_pda_device = { ...@@ -874,6 +866,8 @@ static struct usb_serial_device_type keyspan_pda_device = {
.ioctl = keyspan_pda_ioctl, .ioctl = keyspan_pda_ioctl,
.set_termios = keyspan_pda_set_termios, .set_termios = keyspan_pda_set_termios,
.break_ctl = keyspan_pda_break_ctl, .break_ctl = keyspan_pda_break_ctl,
.tiocmget = keyspan_pda_tiocmget,
.tiocmset = keyspan_pda_tiocmset,
.attach = keyspan_pda_startup, .attach = keyspan_pda_startup,
.shutdown = keyspan_pda_shutdown, .shutdown = keyspan_pda_shutdown,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment