diff options
Diffstat (limited to 'drivers/usb/serial/kobil_sct.c')
-rw-r--r-- | drivers/usb/serial/kobil_sct.c | 80 |
1 files changed, 44 insertions, 36 deletions
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 693f00da7c03..40c67f0096b1 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -70,19 +70,22 @@ static int debug; | |||
70 | /* Function prototypes */ | 70 | /* Function prototypes */ |
71 | static int kobil_startup (struct usb_serial *serial); | 71 | static int kobil_startup (struct usb_serial *serial); |
72 | static void kobil_shutdown (struct usb_serial *serial); | 72 | static void kobil_shutdown (struct usb_serial *serial); |
73 | static int kobil_open (struct usb_serial_port *port, struct file *filp); | 73 | static int kobil_open (struct tty_struct *tty, |
74 | static void kobil_close (struct usb_serial_port *port, struct file *filp); | 74 | struct usb_serial_port *port, struct file *filp); |
75 | static int kobil_write (struct usb_serial_port *port, | 75 | static void kobil_close (struct tty_struct *tty, struct usb_serial_port *port, |
76 | struct file *filp); | ||
77 | static int kobil_write (struct tty_struct *tty, struct usb_serial_port *port, | ||
76 | const unsigned char *buf, int count); | 78 | const unsigned char *buf, int count); |
77 | static int kobil_write_room(struct usb_serial_port *port); | 79 | static int kobil_write_room(struct tty_struct *tty); |
78 | static int kobil_ioctl(struct usb_serial_port *port, struct file *file, | 80 | static int kobil_ioctl(struct tty_struct *tty, struct file *file, |
79 | unsigned int cmd, unsigned long arg); | 81 | unsigned int cmd, unsigned long arg); |
80 | static int kobil_tiocmget(struct usb_serial_port *port, struct file *file); | 82 | static int kobil_tiocmget(struct tty_struct *tty, struct file *file); |
81 | static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, | 83 | static int kobil_tiocmset(struct tty_struct *tty, struct file *file, |
82 | unsigned int set, unsigned int clear); | 84 | unsigned int set, unsigned int clear); |
83 | static void kobil_read_int_callback( struct urb *urb ); | 85 | static void kobil_read_int_callback( struct urb *urb ); |
84 | static void kobil_write_callback( struct urb *purb ); | 86 | static void kobil_write_callback( struct urb *purb ); |
85 | static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old); | 87 | static void kobil_set_termios(struct tty_struct *tty, |
88 | struct usb_serial_port *port, struct ktermios *old); | ||
86 | 89 | ||
87 | 90 | ||
88 | static struct usb_device_id id_table [] = { | 91 | static struct usb_device_id id_table [] = { |
@@ -201,8 +204,8 @@ static void kobil_shutdown (struct usb_serial *serial) | |||
201 | dbg("%s - port %d", __func__, serial->port[0]->number); | 204 | dbg("%s - port %d", __func__, serial->port[0]->number); |
202 | 205 | ||
203 | for (i=0; i < serial->num_ports; ++i) { | 206 | for (i=0; i < serial->num_ports; ++i) { |
204 | while (serial->port[i]->open_count > 0) { | 207 | while (serial->port[i]->port.count > 0) { |
205 | kobil_close (serial->port[i], NULL); | 208 | kobil_close (NULL, serial->port[i], NULL); |
206 | } | 209 | } |
207 | kfree(usb_get_serial_port_data(serial->port[i])); | 210 | kfree(usb_get_serial_port_data(serial->port[i])); |
208 | usb_set_serial_port_data(serial->port[i], NULL); | 211 | usb_set_serial_port_data(serial->port[i], NULL); |
@@ -210,7 +213,8 @@ static void kobil_shutdown (struct usb_serial *serial) | |||
210 | } | 213 | } |
211 | 214 | ||
212 | 215 | ||
213 | static int kobil_open (struct usb_serial_port *port, struct file *filp) | 216 | static int kobil_open(struct tty_struct *tty, |
217 | struct usb_serial_port *port, struct file *filp) | ||
214 | { | 218 | { |
215 | int result = 0; | 219 | int result = 0; |
216 | struct kobil_private *priv; | 220 | struct kobil_private *priv; |
@@ -229,14 +233,15 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) | |||
229 | * the data through, otherwise it is scheduled, and with high | 233 | * the data through, otherwise it is scheduled, and with high |
230 | * data rates (like with OHCI) data can get lost. | 234 | * data rates (like with OHCI) data can get lost. |
231 | */ | 235 | */ |
232 | port->tty->low_latency = 1; | 236 | if (tty) { |
233 | 237 | tty->low_latency = 1; | |
234 | // without this, every push_tty_char is echoed :-( | 238 | |
235 | port->tty->termios->c_lflag = 0; | 239 | /* Default to echo off and other sane device settings */ |
236 | port->tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE); | 240 | tty->termios->c_lflag = 0; |
237 | port->tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF; | 241 | tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE); |
238 | port->tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) | 242 | tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF; |
239 | 243 | tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) | |
244 | } | ||
240 | // allocate memory for transfer buffer | 245 | // allocate memory for transfer buffer |
241 | transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); | 246 | transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); |
242 | if (! transfer_buffer) { | 247 | if (! transfer_buffer) { |
@@ -330,7 +335,8 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) | |||
330 | } | 335 | } |
331 | 336 | ||
332 | 337 | ||
333 | static void kobil_close (struct usb_serial_port *port, struct file *filp) | 338 | static void kobil_close(struct tty_struct *tty, |
339 | struct usb_serial_port *port, struct file *filp) | ||
334 | { | 340 | { |
335 | dbg("%s - port %d", __func__, port->number); | 341 | dbg("%s - port %d", __func__, port->number); |
336 | 342 | ||
@@ -360,7 +366,7 @@ static void kobil_read_int_callback(struct urb *urb) | |||
360 | return; | 366 | return; |
361 | } | 367 | } |
362 | 368 | ||
363 | tty = port->tty; | 369 | tty = port->port.tty; |
364 | if (urb->actual_length) { | 370 | if (urb->actual_length) { |
365 | 371 | ||
366 | // BEGIN DEBUG | 372 | // BEGIN DEBUG |
@@ -395,7 +401,7 @@ static void kobil_write_callback( struct urb *purb ) | |||
395 | } | 401 | } |
396 | 402 | ||
397 | 403 | ||
398 | static int kobil_write (struct usb_serial_port *port, | 404 | static int kobil_write (struct tty_struct *tty, struct usb_serial_port *port, |
399 | const unsigned char *buf, int count) | 405 | const unsigned char *buf, int count) |
400 | { | 406 | { |
401 | int length = 0; | 407 | int length = 0; |
@@ -417,12 +423,9 @@ static int kobil_write (struct usb_serial_port *port, | |||
417 | 423 | ||
418 | // Copy data to buffer | 424 | // Copy data to buffer |
419 | memcpy (priv->buf + priv->filled, buf, count); | 425 | memcpy (priv->buf + priv->filled, buf, count); |
420 | |||
421 | usb_serial_debug_data(debug, &port->dev, __func__, count, priv->buf + priv->filled); | 426 | usb_serial_debug_data(debug, &port->dev, __func__, count, priv->buf + priv->filled); |
422 | |||
423 | priv->filled = priv->filled + count; | 427 | priv->filled = priv->filled + count; |
424 | 428 | ||
425 | |||
426 | // only send complete block. TWIN, KAAN SIM and adapter K use the same protocol. | 429 | // only send complete block. TWIN, KAAN SIM and adapter K use the same protocol. |
427 | if ( ((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) || | 430 | if ( ((priv->device_type != KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 2) && (priv->filled >= (priv->buf[1] + 3))) || |
428 | ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4))) ) { | 431 | ((priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID) && (priv->filled > 3) && (priv->filled >= (priv->buf[2] + 4))) ) { |
@@ -478,15 +481,17 @@ static int kobil_write (struct usb_serial_port *port, | |||
478 | } | 481 | } |
479 | 482 | ||
480 | 483 | ||
481 | static int kobil_write_room (struct usb_serial_port *port) | 484 | static int kobil_write_room (struct tty_struct *tty) |
482 | { | 485 | { |
483 | //dbg("%s - port %d", __func__, port->number); | 486 | //dbg("%s - port %d", __func__, port->number); |
487 | /* FIXME */ | ||
484 | return 8; | 488 | return 8; |
485 | } | 489 | } |
486 | 490 | ||
487 | 491 | ||
488 | static int kobil_tiocmget(struct usb_serial_port *port, struct file *file) | 492 | static int kobil_tiocmget(struct tty_struct *tty, struct file *file) |
489 | { | 493 | { |
494 | struct usb_serial_port *port = tty->driver_data; | ||
490 | struct kobil_private * priv; | 495 | struct kobil_private * priv; |
491 | int result; | 496 | int result; |
492 | unsigned char *transfer_buffer; | 497 | unsigned char *transfer_buffer; |
@@ -524,9 +529,10 @@ static int kobil_tiocmget(struct usb_serial_port *port, struct file *file) | |||
524 | return result; | 529 | return result; |
525 | } | 530 | } |
526 | 531 | ||
527 | static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, | 532 | static int kobil_tiocmset(struct tty_struct *tty, struct file *file, |
528 | unsigned int set, unsigned int clear) | 533 | unsigned int set, unsigned int clear) |
529 | { | 534 | { |
535 | struct usb_serial_port *port = tty->driver_data; | ||
530 | struct kobil_private * priv; | 536 | struct kobil_private * priv; |
531 | int result; | 537 | int result; |
532 | int dtr = 0; | 538 | int dtr = 0; |
@@ -590,12 +596,13 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, | |||
590 | return (result < 0) ? result : 0; | 596 | return (result < 0) ? result : 0; |
591 | } | 597 | } |
592 | 598 | ||
593 | static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old) | 599 | static void kobil_set_termios(struct tty_struct *tty, |
600 | struct usb_serial_port *port, struct ktermios *old) | ||
594 | { | 601 | { |
595 | struct kobil_private * priv; | 602 | struct kobil_private * priv; |
596 | int result; | 603 | int result; |
597 | unsigned short urb_val = 0; | 604 | unsigned short urb_val = 0; |
598 | int c_cflag = port->tty->termios->c_cflag; | 605 | int c_cflag = tty->termios->c_cflag; |
599 | speed_t speed; | 606 | speed_t speed; |
600 | void * settings; | 607 | void * settings; |
601 | 608 | ||
@@ -604,7 +611,7 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old | |||
604 | // This device doesn't support ioctl calls | 611 | // This device doesn't support ioctl calls |
605 | return; | 612 | return; |
606 | 613 | ||
607 | switch (speed = tty_get_baud_rate(port->tty)) { | 614 | switch (speed = tty_get_baud_rate(tty)) { |
608 | case 1200: | 615 | case 1200: |
609 | urb_val = SUSBCR_SBR_1200; | 616 | urb_val = SUSBCR_SBR_1200; |
610 | break; | 617 | break; |
@@ -634,8 +641,8 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old | |||
634 | urb_val |= SUSBCR_SPASB_NoParity; | 641 | urb_val |= SUSBCR_SPASB_NoParity; |
635 | strcat(settings, "No Parity"); | 642 | strcat(settings, "No Parity"); |
636 | } | 643 | } |
637 | port->tty->termios->c_cflag &= ~CMSPAR; | 644 | tty->termios->c_cflag &= ~CMSPAR; |
638 | tty_encode_baud_rate(port->tty, speed, speed); | 645 | tty_encode_baud_rate(tty, speed, speed); |
639 | 646 | ||
640 | result = usb_control_msg( port->serial->dev, | 647 | result = usb_control_msg( port->serial->dev, |
641 | usb_rcvctrlpipe(port->serial->dev, 0 ), | 648 | usb_rcvctrlpipe(port->serial->dev, 0 ), |
@@ -650,8 +657,9 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old | |||
650 | kfree(settings); | 657 | kfree(settings); |
651 | } | 658 | } |
652 | 659 | ||
653 | static int kobil_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) | 660 | static int kobil_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) |
654 | { | 661 | { |
662 | struct usb_serial_port *port = tty->driver_data; | ||
655 | struct kobil_private * priv = usb_get_serial_port_data(port); | 663 | struct kobil_private * priv = usb_get_serial_port_data(port); |
656 | unsigned char *transfer_buffer; | 664 | unsigned char *transfer_buffer; |
657 | int transfer_buffer_length = 8; | 665 | int transfer_buffer_length = 8; |
@@ -662,7 +670,7 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file * file, unsigne | |||
662 | return 0; | 670 | return 0; |
663 | 671 | ||
664 | switch (cmd) { | 672 | switch (cmd) { |
665 | case TCFLSH: // 0x540B | 673 | case TCFLSH: |
666 | transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL); | 674 | transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL); |
667 | if (! transfer_buffer) | 675 | if (! transfer_buffer) |
668 | return -ENOBUFS; | 676 | return -ENOBUFS; |
@@ -680,7 +688,7 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file * file, unsigne | |||
680 | 688 | ||
681 | dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __func__, port->number, result); | 689 | dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __func__, port->number, result); |
682 | kfree(transfer_buffer); | 690 | kfree(transfer_buffer); |
683 | return (result < 0) ? -EFAULT : 0; | 691 | return (result < 0) ? -EIO: 0; |
684 | default: | 692 | default: |
685 | return -ENOIOCTLCMD; | 693 | return -ENOIOCTLCMD; |
686 | } | 694 | } |