ssu100.c (618e183d03a95da200bed48e5277efe428feef26) ssu100.c (31ecdb6befeab20d93b49b8dd640c081b48912d0)
1/*
2 * usb-serial driver for Quatech SSU-100
3 *
4 * based on ftdi_sio.c and the original serqt_usb.c from Quatech
5 *
6 */
7
8#include <linux/errno.h>

--- 47 unchanged lines hidden (view full) ---

56 {} /* Terminating entry */
57};
58MODULE_DEVICE_TABLE(usb, id_table);
59
60struct ssu100_port_private {
61 spinlock_t status_lock;
62 u8 shadowLSR;
63 u8 shadowMSR;
1/*
2 * usb-serial driver for Quatech SSU-100
3 *
4 * based on ftdi_sio.c and the original serqt_usb.c from Quatech
5 *
6 */
7
8#include <linux/errno.h>

--- 47 unchanged lines hidden (view full) ---

56 {} /* Terminating entry */
57};
58MODULE_DEVICE_TABLE(usb, id_table);
59
60struct ssu100_port_private {
61 spinlock_t status_lock;
62 u8 shadowLSR;
63 u8 shadowMSR;
64 struct async_icount icount;
65};
66
67static inline int ssu100_control_msg(struct usb_device *dev,
68 u8 request, u16 data, u16 index)
69{
70 return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
71 request, 0x40, data, index,
72 NULL, 0, 300);

--- 267 unchanged lines hidden (view full) ---

340
341static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
342{
343 struct ssu100_port_private *priv = usb_get_serial_port_data(port);
344 struct async_icount prev, cur;
345 unsigned long flags;
346
347 spin_lock_irqsave(&priv->status_lock, flags);
64};
65
66static inline int ssu100_control_msg(struct usb_device *dev,
67 u8 request, u16 data, u16 index)
68{
69 return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
70 request, 0x40, data, index,
71 NULL, 0, 300);

--- 267 unchanged lines hidden (view full) ---

339
340static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
341{
342 struct ssu100_port_private *priv = usb_get_serial_port_data(port);
343 struct async_icount prev, cur;
344 unsigned long flags;
345
346 spin_lock_irqsave(&priv->status_lock, flags);
348 prev = priv->icount;
347 prev = port->icount;
349 spin_unlock_irqrestore(&priv->status_lock, flags);
350
351 while (1) {
352 wait_event_interruptible(port->delta_msr_wait,
353 (port->serial->disconnected ||
348 spin_unlock_irqrestore(&priv->status_lock, flags);
349
350 while (1) {
351 wait_event_interruptible(port->delta_msr_wait,
352 (port->serial->disconnected ||
354 (priv->icount.rng != prev.rng) ||
355 (priv->icount.dsr != prev.dsr) ||
356 (priv->icount.dcd != prev.dcd) ||
357 (priv->icount.cts != prev.cts)));
353 (port->icount.rng != prev.rng) ||
354 (port->icount.dsr != prev.dsr) ||
355 (port->icount.dcd != prev.dcd) ||
356 (port->icount.cts != prev.cts)));
358
359 if (signal_pending(current))
360 return -ERESTARTSYS;
361
362 if (port->serial->disconnected)
363 return -EIO;
364
365 spin_lock_irqsave(&priv->status_lock, flags);
357
358 if (signal_pending(current))
359 return -ERESTARTSYS;
360
361 if (port->serial->disconnected)
362 return -EIO;
363
364 spin_lock_irqsave(&priv->status_lock, flags);
366 cur = priv->icount;
365 cur = port->icount;
367 spin_unlock_irqrestore(&priv->status_lock, flags);
368
369 if ((prev.rng == cur.rng) &&
370 (prev.dsr == cur.dsr) &&
371 (prev.dcd == cur.dcd) &&
372 (prev.cts == cur.cts))
373 return -EIO;
374
375 if ((arg & TIOCM_RNG && (prev.rng != cur.rng)) ||
376 (arg & TIOCM_DSR && (prev.dsr != cur.dsr)) ||
377 (arg & TIOCM_CD && (prev.dcd != cur.dcd)) ||
378 (arg & TIOCM_CTS && (prev.cts != cur.cts)))
379 return 0;
380 }
381 return 0;
382}
383
366 spin_unlock_irqrestore(&priv->status_lock, flags);
367
368 if ((prev.rng == cur.rng) &&
369 (prev.dsr == cur.dsr) &&
370 (prev.dcd == cur.dcd) &&
371 (prev.cts == cur.cts))
372 return -EIO;
373
374 if ((arg & TIOCM_RNG && (prev.rng != cur.rng)) ||
375 (arg & TIOCM_DSR && (prev.dsr != cur.dsr)) ||
376 (arg & TIOCM_CD && (prev.dcd != cur.dcd)) ||
377 (arg & TIOCM_CTS && (prev.cts != cur.cts)))
378 return 0;
379 }
380 return 0;
381}
382
384static int ssu100_get_icount(struct tty_struct *tty,
385 struct serial_icounter_struct *icount)
386{
387 struct usb_serial_port *port = tty->driver_data;
388 struct ssu100_port_private *priv = usb_get_serial_port_data(port);
389 struct async_icount cnow = priv->icount;
390
391 icount->cts = cnow.cts;
392 icount->dsr = cnow.dsr;
393 icount->rng = cnow.rng;
394 icount->dcd = cnow.dcd;
395 icount->rx = cnow.rx;
396 icount->tx = cnow.tx;
397 icount->frame = cnow.frame;
398 icount->overrun = cnow.overrun;
399 icount->parity = cnow.parity;
400 icount->brk = cnow.brk;
401 icount->buf_overrun = cnow.buf_overrun;
402
403 return 0;
404}
405
406
407
408static int ssu100_ioctl(struct tty_struct *tty,
409 unsigned int cmd, unsigned long arg)
410{
411 struct usb_serial_port *port = tty->driver_data;
412
413 dev_dbg(&port->dev, "%s cmd 0x%04x\n", __func__, cmd);
414
415 switch (cmd) {

--- 106 unchanged lines hidden (view full) ---

522
523 spin_lock_irqsave(&priv->status_lock, flags);
524 priv->shadowMSR = msr;
525 spin_unlock_irqrestore(&priv->status_lock, flags);
526
527 if (msr & UART_MSR_ANY_DELTA) {
528 /* update input line counters */
529 if (msr & UART_MSR_DCTS)
383static int ssu100_ioctl(struct tty_struct *tty,
384 unsigned int cmd, unsigned long arg)
385{
386 struct usb_serial_port *port = tty->driver_data;
387
388 dev_dbg(&port->dev, "%s cmd 0x%04x\n", __func__, cmd);
389
390 switch (cmd) {

--- 106 unchanged lines hidden (view full) ---

497
498 spin_lock_irqsave(&priv->status_lock, flags);
499 priv->shadowMSR = msr;
500 spin_unlock_irqrestore(&priv->status_lock, flags);
501
502 if (msr & UART_MSR_ANY_DELTA) {
503 /* update input line counters */
504 if (msr & UART_MSR_DCTS)
530 priv->icount.cts++;
505 port->icount.cts++;
531 if (msr & UART_MSR_DDSR)
506 if (msr & UART_MSR_DDSR)
532 priv->icount.dsr++;
507 port->icount.dsr++;
533 if (msr & UART_MSR_DDCD)
508 if (msr & UART_MSR_DDCD)
534 priv->icount.dcd++;
509 port->icount.dcd++;
535 if (msr & UART_MSR_TERI)
510 if (msr & UART_MSR_TERI)
536 priv->icount.rng++;
511 port->icount.rng++;
537 wake_up_interruptible(&port->delta_msr_wait);
538 }
539}
540
541static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr,
542 char *tty_flag)
543{
544 struct ssu100_port_private *priv = usb_get_serial_port_data(port);
545 unsigned long flags;
546
547 spin_lock_irqsave(&priv->status_lock, flags);
548 priv->shadowLSR = lsr;
549 spin_unlock_irqrestore(&priv->status_lock, flags);
550
551 *tty_flag = TTY_NORMAL;
552 if (lsr & UART_LSR_BRK_ERROR_BITS) {
553 /* we always want to update icount, but we only want to
554 * update tty_flag for one case */
555 if (lsr & UART_LSR_BI) {
512 wake_up_interruptible(&port->delta_msr_wait);
513 }
514}
515
516static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr,
517 char *tty_flag)
518{
519 struct ssu100_port_private *priv = usb_get_serial_port_data(port);
520 unsigned long flags;
521
522 spin_lock_irqsave(&priv->status_lock, flags);
523 priv->shadowLSR = lsr;
524 spin_unlock_irqrestore(&priv->status_lock, flags);
525
526 *tty_flag = TTY_NORMAL;
527 if (lsr & UART_LSR_BRK_ERROR_BITS) {
528 /* we always want to update icount, but we only want to
529 * update tty_flag for one case */
530 if (lsr & UART_LSR_BI) {
556 priv->icount.brk++;
531 port->icount.brk++;
557 *tty_flag = TTY_BREAK;
558 usb_serial_handle_break(port);
559 }
560 if (lsr & UART_LSR_PE) {
532 *tty_flag = TTY_BREAK;
533 usb_serial_handle_break(port);
534 }
535 if (lsr & UART_LSR_PE) {
561 priv->icount.parity++;
536 port->icount.parity++;
562 if (*tty_flag == TTY_NORMAL)
563 *tty_flag = TTY_PARITY;
564 }
565 if (lsr & UART_LSR_FE) {
537 if (*tty_flag == TTY_NORMAL)
538 *tty_flag = TTY_PARITY;
539 }
540 if (lsr & UART_LSR_FE) {
566 priv->icount.frame++;
541 port->icount.frame++;
567 if (*tty_flag == TTY_NORMAL)
568 *tty_flag = TTY_FRAME;
569 }
570 if (lsr & UART_LSR_OE){
542 if (*tty_flag == TTY_NORMAL)
543 *tty_flag = TTY_FRAME;
544 }
545 if (lsr & UART_LSR_OE){
571 priv->icount.overrun++;
546 port->icount.overrun++;
572 if (*tty_flag == TTY_NORMAL)
573 *tty_flag = TTY_OVERRUN;
574 }
575 }
576
577}
578
579static void ssu100_process_read_urb(struct urb *urb)

--- 47 unchanged lines hidden (view full) ---

627 .open = ssu100_open,
628 .attach = ssu100_attach,
629 .port_probe = ssu100_port_probe,
630 .port_remove = ssu100_port_remove,
631 .dtr_rts = ssu100_dtr_rts,
632 .process_read_urb = ssu100_process_read_urb,
633 .tiocmget = ssu100_tiocmget,
634 .tiocmset = ssu100_tiocmset,
547 if (*tty_flag == TTY_NORMAL)
548 *tty_flag = TTY_OVERRUN;
549 }
550 }
551
552}
553
554static void ssu100_process_read_urb(struct urb *urb)

--- 47 unchanged lines hidden (view full) ---

602 .open = ssu100_open,
603 .attach = ssu100_attach,
604 .port_probe = ssu100_port_probe,
605 .port_remove = ssu100_port_remove,
606 .dtr_rts = ssu100_dtr_rts,
607 .process_read_urb = ssu100_process_read_urb,
608 .tiocmget = ssu100_tiocmget,
609 .tiocmset = ssu100_tiocmset,
635 .get_icount = ssu100_get_icount,
610 .get_icount = usb_serial_generic_get_icount,
636 .ioctl = ssu100_ioctl,
637 .set_termios = ssu100_set_termios,
638};
639
640static struct usb_serial_driver * const serial_drivers[] = {
641 &ssu100_device, NULL
642};
643
644module_usb_serial_driver(serial_drivers, id_table);
645
646MODULE_DESCRIPTION(DRIVER_DESC);
647MODULE_LICENSE("GPL");
611 .ioctl = ssu100_ioctl,
612 .set_termios = ssu100_set_termios,
613};
614
615static struct usb_serial_driver * const serial_drivers[] = {
616 &ssu100_device, NULL
617};
618
619module_usb_serial_driver(serial_drivers, id_table);
620
621MODULE_DESCRIPTION(DRIVER_DESC);
622MODULE_LICENSE("GPL");