aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2009-02-06 21:31:46 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-03-24 19:20:30 -0400
commitfaac64ad9c7b1aa56a10be6b5f9b813789e81dfd (patch)
tree7d4d739b385807014ee39452dfd9e2e3df98e379 /drivers/usb
parent648d4e16567eae4c643bd2125e91128f06c0d3ad (diff)
USB: serial: opticon: add serial line ioctls
This lets userspace determine what the state of the RTS line is, which is what is needed to properly handle data flow for this device (it raises RTS when there is data to be sent from it.) Cc: Kees Stoop <kees.stoop@opticon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/opticon.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 8c87a49ee2bb..839583dc8b6a 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -14,6 +14,7 @@
14#include <linux/tty.h> 14#include <linux/tty.h>
15#include <linux/tty_driver.h> 15#include <linux/tty_driver.h>
16#include <linux/tty_flip.h> 16#include <linux/tty_flip.h>
17#include <linux/serial.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/usb.h> 19#include <linux/usb.h>
19#include <linux/usb/serial.h> 20#include <linux/usb/serial.h>
@@ -110,7 +111,6 @@ static void opticon_bulk_callback(struct urb *urb)
110 priv->rts = false; 111 priv->rts = false;
111 else 112 else
112 priv->rts = true; 113 priv->rts = true;
113 /* FIXME change the RTS level */
114 } else { 114 } else {
115 dev_dbg(&priv->udev->dev, 115 dev_dbg(&priv->udev->dev,
116 "Unknown data packet received from the device:" 116 "Unknown data packet received from the device:"
@@ -341,6 +341,67 @@ static void opticon_unthrottle(struct tty_struct *tty)
341 __func__, result); 341 __func__, result);
342} 342}
343 343
344static int opticon_tiocmget(struct tty_struct *tty, struct file *file)
345{
346 struct usb_serial_port *port = tty->driver_data;
347 struct opticon_private *priv = usb_get_serial_data(port->serial);
348 unsigned long flags;
349 int result = 0;
350
351 dbg("%s - port %d", __func__, port->number);
352
353 spin_lock_irqsave(&priv->lock, flags);
354 if (priv->rts)
355 result = TIOCM_RTS;
356 spin_unlock_irqrestore(&priv->lock, flags);
357
358 dbg("%s - %x", __func__, result);
359 return result;
360}
361
362static int get_serial_info(struct opticon_private *priv,
363 struct serial_struct __user *serial)
364{
365 struct serial_struct tmp;
366
367 if (!serial)
368 return -EFAULT;
369
370 memset(&tmp, 0x00, sizeof(tmp));
371
372 /* fake emulate a 16550 uart to make userspace code happy */
373 tmp.type = PORT_16550A;
374 tmp.line = priv->serial->minor;
375 tmp.port = 0;
376 tmp.irq = 0;
377 tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
378 tmp.xmit_fifo_size = 1024;
379 tmp.baud_base = 9600;
380 tmp.close_delay = 5*HZ;
381 tmp.closing_wait = 30*HZ;
382
383 if (copy_to_user(serial, &tmp, sizeof(*serial)))
384 return -EFAULT;
385 return 0;
386}
387
388static int opticon_ioctl(struct tty_struct *tty, struct file *file,
389 unsigned int cmd, unsigned long arg)
390{
391 struct usb_serial_port *port = tty->driver_data;
392 struct opticon_private *priv = usb_get_serial_data(port->serial);
393
394 dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
395
396 switch (cmd) {
397 case TIOCGSERIAL:
398 return get_serial_info(priv,
399 (struct serial_struct __user *)arg);
400 }
401
402 return -ENOIOCTLCMD;
403}
404
344static int opticon_startup(struct usb_serial *serial) 405static int opticon_startup(struct usb_serial *serial)
345{ 406{
346 struct opticon_private *priv; 407 struct opticon_private *priv;
@@ -475,6 +536,8 @@ static struct usb_serial_driver opticon_device = {
475 .shutdown = opticon_shutdown, 536 .shutdown = opticon_shutdown,
476 .throttle = opticon_throttle, 537 .throttle = opticon_throttle,
477 .unthrottle = opticon_unthrottle, 538 .unthrottle = opticon_unthrottle,
539 .ioctl = opticon_ioctl,
540 .tiocmget = opticon_tiocmget,
478}; 541};
479 542
480static int __init opticon_init(void) 543static int __init opticon_init(void)