diff options
Diffstat (limited to 'drivers/usb/serial/oti6858.c')
-rw-r--r-- | drivers/usb/serial/oti6858.c | 255 |
1 files changed, 118 insertions, 137 deletions
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index a9625c180dc3..81db5715ee25 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -25,7 +25,8 @@ | |||
25 | * it under the terms of the GNU General Public License as published by | 25 | * it under the terms of the GNU General Public License as published by |
26 | * the Free Software Foundation; either version 2 of the License. | 26 | * the Free Software Foundation; either version 2 of the License. |
27 | * | 27 | * |
28 | * See Documentation/usb/usb-serial.txt for more information on using this driver | 28 | * See Documentation/usb/usb-serial.txt for more information on using this |
29 | * driver | ||
29 | * | 30 | * |
30 | * TODO: | 31 | * TODO: |
31 | * - implement correct flushing for ioctls and oti6858_close() | 32 | * - implement correct flushing for ioctls and oti6858_close() |
@@ -49,7 +50,7 @@ | |||
49 | #include <linux/spinlock.h> | 50 | #include <linux/spinlock.h> |
50 | #include <linux/usb.h> | 51 | #include <linux/usb.h> |
51 | #include <linux/usb/serial.h> | 52 | #include <linux/usb/serial.h> |
52 | #include <asm/uaccess.h> | 53 | #include <linux/uaccess.h> |
53 | #include "oti6858.h" | 54 | #include "oti6858.h" |
54 | 55 | ||
55 | #define OTI6858_DESCRIPTION \ | 56 | #define OTI6858_DESCRIPTION \ |
@@ -135,27 +136,28 @@ struct oti6858_control_pkt { | |||
135 | 136 | ||
136 | #define OTI6858_CTRL_PKT_SIZE sizeof(struct oti6858_control_pkt) | 137 | #define OTI6858_CTRL_PKT_SIZE sizeof(struct oti6858_control_pkt) |
137 | #define OTI6858_CTRL_EQUALS_PENDING(a, priv) \ | 138 | #define OTI6858_CTRL_EQUALS_PENDING(a, priv) \ |
138 | ( ((a)->divisor == (priv)->pending_setup.divisor) \ | 139 | (((a)->divisor == (priv)->pending_setup.divisor) \ |
139 | && ((a)->control == (priv)->pending_setup.control) \ | 140 | && ((a)->control == (priv)->pending_setup.control) \ |
140 | && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt) ) | 141 | && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt)) |
141 | 142 | ||
142 | /* function prototypes */ | 143 | /* function prototypes */ |
143 | static int oti6858_open(struct usb_serial_port *port, struct file *filp); | 144 | static int oti6858_open(struct tty_struct *tty, |
144 | static void oti6858_close(struct usb_serial_port *port, struct file *filp); | 145 | struct usb_serial_port *port, struct file *filp); |
145 | static void oti6858_set_termios(struct usb_serial_port *port, | 146 | static void oti6858_close(struct tty_struct *tty, |
146 | struct ktermios *old); | 147 | struct usb_serial_port *port, struct file *filp); |
147 | static int oti6858_ioctl(struct usb_serial_port *port, struct file *file, | 148 | static void oti6858_set_termios(struct tty_struct *tty, |
149 | struct usb_serial_port *port, struct ktermios *old); | ||
150 | static int oti6858_ioctl(struct tty_struct *tty, struct file *file, | ||
148 | unsigned int cmd, unsigned long arg); | 151 | unsigned int cmd, unsigned long arg); |
149 | static void oti6858_read_int_callback(struct urb *urb); | 152 | static void oti6858_read_int_callback(struct urb *urb); |
150 | static void oti6858_read_bulk_callback(struct urb *urb); | 153 | static void oti6858_read_bulk_callback(struct urb *urb); |
151 | static void oti6858_write_bulk_callback(struct urb *urb); | 154 | static void oti6858_write_bulk_callback(struct urb *urb); |
152 | static int oti6858_write(struct usb_serial_port *port, | 155 | static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, |
153 | const unsigned char *buf, int count); | 156 | const unsigned char *buf, int count); |
154 | static int oti6858_write_room(struct usb_serial_port *port); | 157 | static int oti6858_write_room(struct tty_struct *tty); |
155 | static void oti6858_break_ctl(struct usb_serial_port *port, int break_state); | 158 | static int oti6858_chars_in_buffer(struct tty_struct *tty); |
156 | static int oti6858_chars_in_buffer(struct usb_serial_port *port); | 159 | static int oti6858_tiocmget(struct tty_struct *tty, struct file *file); |
157 | static int oti6858_tiocmget(struct usb_serial_port *port, struct file *file); | 160 | static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, |
158 | static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file, | ||
159 | unsigned int set, unsigned int clear); | 161 | unsigned int set, unsigned int clear); |
160 | static int oti6858_startup(struct usb_serial *serial); | 162 | static int oti6858_startup(struct usb_serial *serial); |
161 | static void oti6858_shutdown(struct usb_serial *serial); | 163 | static void oti6858_shutdown(struct usb_serial *serial); |
@@ -184,7 +186,6 @@ static struct usb_serial_driver oti6858_device = { | |||
184 | .close = oti6858_close, | 186 | .close = oti6858_close, |
185 | .write = oti6858_write, | 187 | .write = oti6858_write, |
186 | .ioctl = oti6858_ioctl, | 188 | .ioctl = oti6858_ioctl, |
187 | .break_ctl = oti6858_break_ctl, | ||
188 | .set_termios = oti6858_set_termios, | 189 | .set_termios = oti6858_set_termios, |
189 | .tiocmget = oti6858_tiocmget, | 190 | .tiocmget = oti6858_tiocmget, |
190 | .tiocmset = oti6858_tiocmset, | 191 | .tiocmset = oti6858_tiocmset, |
@@ -220,7 +221,7 @@ struct oti6858_private { | |||
220 | struct delayed_work delayed_setup_work; | 221 | struct delayed_work delayed_setup_work; |
221 | 222 | ||
222 | wait_queue_head_t intr_wait; | 223 | wait_queue_head_t intr_wait; |
223 | struct usb_serial_port *port; /* USB port with which associated */ | 224 | struct usb_serial_port *port; /* USB port with which associated */ |
224 | }; | 225 | }; |
225 | 226 | ||
226 | #undef dbg | 227 | #undef dbg |
@@ -229,7 +230,8 @@ struct oti6858_private { | |||
229 | 230 | ||
230 | static void setup_line(struct work_struct *work) | 231 | static void setup_line(struct work_struct *work) |
231 | { | 232 | { |
232 | struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_setup_work.work); | 233 | struct oti6858_private *priv = container_of(work, |
234 | struct oti6858_private, delayed_setup_work.work); | ||
233 | struct usb_serial_port *port = priv->port; | 235 | struct usb_serial_port *port = priv->port; |
234 | struct oti6858_control_pkt *new_setup; | 236 | struct oti6858_control_pkt *new_setup; |
235 | unsigned long flags; | 237 | unsigned long flags; |
@@ -237,10 +239,12 @@ static void setup_line(struct work_struct *work) | |||
237 | 239 | ||
238 | dbg("%s(port = %d)", __func__, port->number); | 240 | dbg("%s(port = %d)", __func__, port->number); |
239 | 241 | ||
240 | if ((new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) { | 242 | new_setup = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL); |
243 | if (new_setup == NULL) { | ||
241 | dev_err(&port->dev, "%s(): out of memory!\n", __func__); | 244 | dev_err(&port->dev, "%s(): out of memory!\n", __func__); |
242 | /* we will try again */ | 245 | /* we will try again */ |
243 | schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); | 246 | schedule_delayed_work(&priv->delayed_setup_work, |
247 | msecs_to_jiffies(2)); | ||
244 | return; | 248 | return; |
245 | } | 249 | } |
246 | 250 | ||
@@ -256,7 +260,8 @@ static void setup_line(struct work_struct *work) | |||
256 | dev_err(&port->dev, "%s(): error reading status\n", __func__); | 260 | dev_err(&port->dev, "%s(): error reading status\n", __func__); |
257 | kfree(new_setup); | 261 | kfree(new_setup); |
258 | /* we will try again */ | 262 | /* we will try again */ |
259 | schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); | 263 | schedule_delayed_work(&priv->delayed_setup_work, |
264 | msecs_to_jiffies(2)); | ||
260 | return; | 265 | return; |
261 | } | 266 | } |
262 | 267 | ||
@@ -297,7 +302,8 @@ static void setup_line(struct work_struct *work) | |||
297 | 302 | ||
298 | void send_data(struct work_struct *work) | 303 | void send_data(struct work_struct *work) |
299 | { | 304 | { |
300 | struct oti6858_private *priv = container_of(work, struct oti6858_private, delayed_write_work.work); | 305 | struct oti6858_private *priv = container_of(work, |
306 | struct oti6858_private, delayed_write_work.work); | ||
301 | struct usb_serial_port *port = priv->port; | 307 | struct usb_serial_port *port = priv->port; |
302 | int count = 0, result; | 308 | int count = 0, result; |
303 | unsigned long flags; | 309 | unsigned long flags; |
@@ -308,7 +314,8 @@ void send_data(struct work_struct *work) | |||
308 | spin_lock_irqsave(&priv->lock, flags); | 314 | spin_lock_irqsave(&priv->lock, flags); |
309 | if (priv->flags.write_urb_in_use) { | 315 | if (priv->flags.write_urb_in_use) { |
310 | spin_unlock_irqrestore(&priv->lock, flags); | 316 | spin_unlock_irqrestore(&priv->lock, flags); |
311 | schedule_delayed_work(&priv->delayed_write_work, msecs_to_jiffies(2)); | 317 | schedule_delayed_work(&priv->delayed_write_work, |
318 | msecs_to_jiffies(2)); | ||
312 | return; | 319 | return; |
313 | } | 320 | } |
314 | priv->flags.write_urb_in_use = 1; | 321 | priv->flags.write_urb_in_use = 1; |
@@ -359,8 +366,8 @@ void send_data(struct work_struct *work) | |||
359 | 366 | ||
360 | static int oti6858_startup(struct usb_serial *serial) | 367 | static int oti6858_startup(struct usb_serial *serial) |
361 | { | 368 | { |
362 | struct usb_serial_port *port = serial->port[0]; | 369 | struct usb_serial_port *port = serial->port[0]; |
363 | struct oti6858_private *priv; | 370 | struct oti6858_private *priv; |
364 | int i; | 371 | int i; |
365 | 372 | ||
366 | for (i = 0; i < serial->num_ports; ++i) { | 373 | for (i = 0; i < serial->num_ports; ++i) { |
@@ -375,8 +382,8 @@ static int oti6858_startup(struct usb_serial *serial) | |||
375 | 382 | ||
376 | spin_lock_init(&priv->lock); | 383 | spin_lock_init(&priv->lock); |
377 | init_waitqueue_head(&priv->intr_wait); | 384 | init_waitqueue_head(&priv->intr_wait); |
378 | // INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); | 385 | /* INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */ |
379 | // INIT_WORK(&priv->write_work, send_data, serial->port[i]); | 386 | /* INIT_WORK(&priv->write_work, send_data, serial->port[i]); */ |
380 | priv->port = port; | 387 | priv->port = port; |
381 | INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); | 388 | INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); |
382 | INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); | 389 | INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); |
@@ -395,7 +402,7 @@ static int oti6858_startup(struct usb_serial *serial) | |||
395 | return -ENOMEM; | 402 | return -ENOMEM; |
396 | } | 403 | } |
397 | 404 | ||
398 | static int oti6858_write(struct usb_serial_port *port, | 405 | static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, |
399 | const unsigned char *buf, int count) | 406 | const unsigned char *buf, int count) |
400 | { | 407 | { |
401 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 408 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
@@ -413,8 +420,9 @@ static int oti6858_write(struct usb_serial_port *port, | |||
413 | return count; | 420 | return count; |
414 | } | 421 | } |
415 | 422 | ||
416 | static int oti6858_write_room(struct usb_serial_port *port) | 423 | static int oti6858_write_room(struct tty_struct *tty) |
417 | { | 424 | { |
425 | struct usb_serial_port *port = tty->driver_data; | ||
418 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 426 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
419 | int room = 0; | 427 | int room = 0; |
420 | unsigned long flags; | 428 | unsigned long flags; |
@@ -428,8 +436,9 @@ static int oti6858_write_room(struct usb_serial_port *port) | |||
428 | return room; | 436 | return room; |
429 | } | 437 | } |
430 | 438 | ||
431 | static int oti6858_chars_in_buffer(struct usb_serial_port *port) | 439 | static int oti6858_chars_in_buffer(struct tty_struct *tty) |
432 | { | 440 | { |
441 | struct usb_serial_port *port = tty->driver_data; | ||
433 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 442 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
434 | int chars = 0; | 443 | int chars = 0; |
435 | unsigned long flags; | 444 | unsigned long flags; |
@@ -443,8 +452,8 @@ static int oti6858_chars_in_buffer(struct usb_serial_port *port) | |||
443 | return chars; | 452 | return chars; |
444 | } | 453 | } |
445 | 454 | ||
446 | static void oti6858_set_termios(struct usb_serial_port *port, | 455 | static void oti6858_set_termios(struct tty_struct *tty, |
447 | struct ktermios *old_termios) | 456 | struct usb_serial_port *port, struct ktermios *old_termios) |
448 | { | 457 | { |
449 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 458 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
450 | unsigned long flags; | 459 | unsigned long flags; |
@@ -455,22 +464,22 @@ static void oti6858_set_termios(struct usb_serial_port *port, | |||
455 | 464 | ||
456 | dbg("%s(port = %d)", __func__, port->number); | 465 | dbg("%s(port = %d)", __func__, port->number); |
457 | 466 | ||
458 | if (!port->tty || !port->tty->termios) { | 467 | if (!tty) { |
459 | dbg("%s(): no tty structures", __func__); | 468 | dbg("%s(): no tty structures", __func__); |
460 | return; | 469 | return; |
461 | } | 470 | } |
462 | 471 | ||
463 | spin_lock_irqsave(&priv->lock, flags); | 472 | spin_lock_irqsave(&priv->lock, flags); |
464 | if (!priv->flags.termios_initialized) { | 473 | if (!priv->flags.termios_initialized) { |
465 | *(port->tty->termios) = tty_std_termios; | 474 | *(tty->termios) = tty_std_termios; |
466 | port->tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; | 475 | tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; |
476 | tty->termios->c_ispeed = 38400; | ||
477 | tty->termios->c_ospeed = 38400; | ||
467 | priv->flags.termios_initialized = 1; | 478 | priv->flags.termios_initialized = 1; |
468 | port->tty->termios->c_ispeed = 38400; | ||
469 | port->tty->termios->c_ospeed = 38400; | ||
470 | } | 479 | } |
471 | spin_unlock_irqrestore(&priv->lock, flags); | 480 | spin_unlock_irqrestore(&priv->lock, flags); |
472 | 481 | ||
473 | cflag = port->tty->termios->c_cflag; | 482 | cflag = tty->termios->c_cflag; |
474 | 483 | ||
475 | spin_lock_irqsave(&priv->lock, flags); | 484 | spin_lock_irqsave(&priv->lock, flags); |
476 | divisor = priv->pending_setup.divisor; | 485 | divisor = priv->pending_setup.divisor; |
@@ -480,19 +489,19 @@ static void oti6858_set_termios(struct usb_serial_port *port, | |||
480 | 489 | ||
481 | frame_fmt &= ~FMT_DATA_BITS_MASK; | 490 | frame_fmt &= ~FMT_DATA_BITS_MASK; |
482 | switch (cflag & CSIZE) { | 491 | switch (cflag & CSIZE) { |
483 | case CS5: | 492 | case CS5: |
484 | frame_fmt |= FMT_DATA_BITS_5; | 493 | frame_fmt |= FMT_DATA_BITS_5; |
485 | break; | 494 | break; |
486 | case CS6: | 495 | case CS6: |
487 | frame_fmt |= FMT_DATA_BITS_6; | 496 | frame_fmt |= FMT_DATA_BITS_6; |
488 | break; | 497 | break; |
489 | case CS7: | 498 | case CS7: |
490 | frame_fmt |= FMT_DATA_BITS_7; | 499 | frame_fmt |= FMT_DATA_BITS_7; |
491 | break; | 500 | break; |
492 | default: | 501 | default: |
493 | case CS8: | 502 | case CS8: |
494 | frame_fmt |= FMT_DATA_BITS_8; | 503 | frame_fmt |= FMT_DATA_BITS_8; |
495 | break; | 504 | break; |
496 | } | 505 | } |
497 | 506 | ||
498 | /* manufacturer claims that this device can work with baud rates | 507 | /* manufacturer claims that this device can work with baud rates |
@@ -500,7 +509,7 @@ static void oti6858_set_termios(struct usb_serial_port *port, | |||
500 | * guarantee that any other baud rate will work (especially | 509 | * guarantee that any other baud rate will work (especially |
501 | * the higher ones) | 510 | * the higher ones) |
502 | */ | 511 | */ |
503 | br = tty_get_baud_rate(port->tty); | 512 | br = tty_get_baud_rate(tty); |
504 | if (br == 0) { | 513 | if (br == 0) { |
505 | divisor = 0; | 514 | divisor = 0; |
506 | } else { | 515 | } else { |
@@ -511,23 +520,21 @@ static void oti6858_set_termios(struct usb_serial_port *port, | |||
511 | new_divisor = (96000000 + 8 * br) / (16 * br); | 520 | new_divisor = (96000000 + 8 * br) / (16 * br); |
512 | real_br = 96000000 / (16 * new_divisor); | 521 | real_br = 96000000 / (16 * new_divisor); |
513 | divisor = cpu_to_le16(new_divisor); | 522 | divisor = cpu_to_le16(new_divisor); |
514 | tty_encode_baud_rate(port->tty, real_br, real_br); | 523 | tty_encode_baud_rate(tty, real_br, real_br); |
515 | } | 524 | } |
516 | 525 | ||
517 | frame_fmt &= ~FMT_STOP_BITS_MASK; | 526 | frame_fmt &= ~FMT_STOP_BITS_MASK; |
518 | if ((cflag & CSTOPB) != 0) { | 527 | if ((cflag & CSTOPB) != 0) |
519 | frame_fmt |= FMT_STOP_BITS_2; | 528 | frame_fmt |= FMT_STOP_BITS_2; |
520 | } else { | 529 | else |
521 | frame_fmt |= FMT_STOP_BITS_1; | 530 | frame_fmt |= FMT_STOP_BITS_1; |
522 | } | ||
523 | 531 | ||
524 | frame_fmt &= ~FMT_PARITY_MASK; | 532 | frame_fmt &= ~FMT_PARITY_MASK; |
525 | if ((cflag & PARENB) != 0) { | 533 | if ((cflag & PARENB) != 0) { |
526 | if ((cflag & PARODD) != 0) { | 534 | if ((cflag & PARODD) != 0) |
527 | frame_fmt |= FMT_PARITY_ODD; | 535 | frame_fmt |= FMT_PARITY_ODD; |
528 | } else { | 536 | else |
529 | frame_fmt |= FMT_PARITY_EVEN; | 537 | frame_fmt |= FMT_PARITY_EVEN; |
530 | } | ||
531 | } else { | 538 | } else { |
532 | frame_fmt |= FMT_PARITY_NONE; | 539 | frame_fmt |= FMT_PARITY_NONE; |
533 | } | 540 | } |
@@ -564,7 +571,8 @@ static void oti6858_set_termios(struct usb_serial_port *port, | |||
564 | spin_unlock_irqrestore(&priv->lock, flags); | 571 | spin_unlock_irqrestore(&priv->lock, flags); |
565 | } | 572 | } |
566 | 573 | ||
567 | static int oti6858_open(struct usb_serial_port *port, struct file *filp) | 574 | static int oti6858_open(struct tty_struct *tty, |
575 | struct usb_serial_port *port, struct file *filp) | ||
568 | { | 576 | { |
569 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 577 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
570 | struct ktermios tmp_termios; | 578 | struct ktermios tmp_termios; |
@@ -578,10 +586,11 @@ static int oti6858_open(struct usb_serial_port *port, struct file *filp) | |||
578 | usb_clear_halt(serial->dev, port->write_urb->pipe); | 586 | usb_clear_halt(serial->dev, port->write_urb->pipe); |
579 | usb_clear_halt(serial->dev, port->read_urb->pipe); | 587 | usb_clear_halt(serial->dev, port->read_urb->pipe); |
580 | 588 | ||
581 | if (port->open_count != 1) | 589 | if (port->port.count != 1) |
582 | return 0; | 590 | return 0; |
583 | 591 | ||
584 | if ((buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL)) == NULL) { | 592 | buf = kmalloc(OTI6858_CTRL_PKT_SIZE, GFP_KERNEL); |
593 | if (buf == NULL) { | ||
585 | dev_err(&port->dev, "%s(): out of memory!\n", __func__); | 594 | dev_err(&port->dev, "%s(): out of memory!\n", __func__); |
586 | return -ENOMEM; | 595 | return -ENOMEM; |
587 | } | 596 | } |
@@ -617,18 +626,19 @@ static int oti6858_open(struct usb_serial_port *port, struct file *filp) | |||
617 | if (result != 0) { | 626 | if (result != 0) { |
618 | dev_err(&port->dev, "%s(): usb_submit_urb() failed" | 627 | dev_err(&port->dev, "%s(): usb_submit_urb() failed" |
619 | " with error %d\n", __func__, result); | 628 | " with error %d\n", __func__, result); |
620 | oti6858_close(port, NULL); | 629 | oti6858_close(tty, port, NULL); |
621 | return -EPROTO; | 630 | return -EPROTO; |
622 | } | 631 | } |
623 | 632 | ||
624 | /* setup termios */ | 633 | /* setup termios */ |
625 | if (port->tty) | 634 | if (tty) |
626 | oti6858_set_termios(port, &tmp_termios); | 635 | oti6858_set_termios(tty, port, &tmp_termios); |
627 | 636 | ||
628 | return 0; | 637 | return 0; |
629 | } | 638 | } |
630 | 639 | ||
631 | static void oti6858_close(struct usb_serial_port *port, struct file *filp) | 640 | static void oti6858_close(struct tty_struct *tty, |
641 | struct usb_serial_port *port, struct file *filp) | ||
632 | { | 642 | { |
633 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 643 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
634 | unsigned long flags; | 644 | unsigned long flags; |
@@ -641,7 +651,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) | |||
641 | spin_lock_irqsave(&priv->lock, flags); | 651 | spin_lock_irqsave(&priv->lock, flags); |
642 | timeout = 30 * HZ; /* PL2303_CLOSING_WAIT */ | 652 | timeout = 30 * HZ; /* PL2303_CLOSING_WAIT */ |
643 | init_waitqueue_entry(&wait, current); | 653 | init_waitqueue_entry(&wait, current); |
644 | add_wait_queue(&port->tty->write_wait, &wait); | 654 | add_wait_queue(&tty->write_wait, &wait); |
645 | dbg("%s(): entering wait loop", __func__); | 655 | dbg("%s(): entering wait loop", __func__); |
646 | for (;;) { | 656 | for (;;) { |
647 | set_current_state(TASK_INTERRUPTIBLE); | 657 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -654,7 +664,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) | |||
654 | spin_lock_irqsave(&priv->lock, flags); | 664 | spin_lock_irqsave(&priv->lock, flags); |
655 | } | 665 | } |
656 | set_current_state(TASK_RUNNING); | 666 | set_current_state(TASK_RUNNING); |
657 | remove_wait_queue(&port->tty->write_wait, &wait); | 667 | remove_wait_queue(&tty->write_wait, &wait); |
658 | dbg("%s(): after wait loop", __func__); | 668 | dbg("%s(): after wait loop", __func__); |
659 | 669 | ||
660 | /* clear out any remaining data in the buffer */ | 670 | /* clear out any remaining data in the buffer */ |
@@ -669,7 +679,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) | |||
669 | /* data is in the buffer to compute a delay */ | 679 | /* data is in the buffer to compute a delay */ |
670 | /* that is not unnecessarily long) */ | 680 | /* that is not unnecessarily long) */ |
671 | /* FIXME | 681 | /* FIXME |
672 | bps = tty_get_baud_rate(port->tty); | 682 | bps = tty_get_baud_rate(tty); |
673 | if (bps > 1200) | 683 | if (bps > 1200) |
674 | timeout = max((HZ*2560)/bps,HZ/10); | 684 | timeout = max((HZ*2560)/bps,HZ/10); |
675 | else | 685 | else |
@@ -690,7 +700,7 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) | |||
690 | usb_kill_urb(port->interrupt_in_urb); | 700 | usb_kill_urb(port->interrupt_in_urb); |
691 | 701 | ||
692 | /* | 702 | /* |
693 | if (port->tty && (port->tty->termios->c_cflag) & HUPCL) { | 703 | if (tty && (tty->termios->c_cflag) & HUPCL) { |
694 | // drop DTR and RTS | 704 | // drop DTR and RTS |
695 | spin_lock_irqsave(&priv->lock, flags); | 705 | spin_lock_irqsave(&priv->lock, flags); |
696 | priv->pending_setup.control &= ~CONTROL_MASK; | 706 | priv->pending_setup.control &= ~CONTROL_MASK; |
@@ -699,9 +709,10 @@ static void oti6858_close(struct usb_serial_port *port, struct file *filp) | |||
699 | */ | 709 | */ |
700 | } | 710 | } |
701 | 711 | ||
702 | static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file, | 712 | static int oti6858_tiocmset(struct tty_struct *tty, struct file *file, |
703 | unsigned int set, unsigned int clear) | 713 | unsigned int set, unsigned int clear) |
704 | { | 714 | { |
715 | struct usb_serial_port *port = tty->driver_data; | ||
705 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 716 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
706 | unsigned long flags; | 717 | unsigned long flags; |
707 | u8 control; | 718 | u8 control; |
@@ -724,16 +735,16 @@ static int oti6858_tiocmset(struct usb_serial_port *port, struct file *file, | |||
724 | if ((clear & TIOCM_DTR) != 0) | 735 | if ((clear & TIOCM_DTR) != 0) |
725 | control &= ~CONTROL_DTR_HIGH; | 736 | control &= ~CONTROL_DTR_HIGH; |
726 | 737 | ||
727 | if (control != priv->pending_setup.control) { | 738 | if (control != priv->pending_setup.control) |
728 | priv->pending_setup.control = control; | 739 | priv->pending_setup.control = control; |
729 | } | ||
730 | spin_unlock_irqrestore(&priv->lock, flags); | ||
731 | 740 | ||
741 | spin_unlock_irqrestore(&priv->lock, flags); | ||
732 | return 0; | 742 | return 0; |
733 | } | 743 | } |
734 | 744 | ||
735 | static int oti6858_tiocmget(struct usb_serial_port *port, struct file *file) | 745 | static int oti6858_tiocmget(struct tty_struct *tty, struct file *file) |
736 | { | 746 | { |
747 | struct usb_serial_port *port = tty->driver_data; | ||
737 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 748 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
738 | unsigned long flags; | 749 | unsigned long flags; |
739 | unsigned pin_state; | 750 | unsigned pin_state; |
@@ -779,7 +790,8 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) | |||
779 | spin_unlock_irqrestore(&priv->lock, flags); | 790 | spin_unlock_irqrestore(&priv->lock, flags); |
780 | 791 | ||
781 | while (1) { | 792 | while (1) { |
782 | wait_event_interruptible(priv->intr_wait, priv->status.pin_state != prev); | 793 | wait_event_interruptible(priv->intr_wait, |
794 | priv->status.pin_state != prev); | ||
783 | if (signal_pending(current)) | 795 | if (signal_pending(current)) |
784 | return -ERESTARTSYS; | 796 | return -ERESTARTSYS; |
785 | 797 | ||
@@ -789,12 +801,11 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) | |||
789 | 801 | ||
790 | changed = prev ^ status; | 802 | changed = prev ^ status; |
791 | /* FIXME: check if this is correct (active high/low) */ | 803 | /* FIXME: check if this is correct (active high/low) */ |
792 | if ( ((arg & TIOCM_RNG) && (changed & PIN_RI)) || | 804 | if (((arg & TIOCM_RNG) && (changed & PIN_RI)) || |
793 | ((arg & TIOCM_DSR) && (changed & PIN_DSR)) || | 805 | ((arg & TIOCM_DSR) && (changed & PIN_DSR)) || |
794 | ((arg & TIOCM_CD) && (changed & PIN_DCD)) || | 806 | ((arg & TIOCM_CD) && (changed & PIN_DCD)) || |
795 | ((arg & TIOCM_CTS) && (changed & PIN_CTS))) { | 807 | ((arg & TIOCM_CTS) && (changed & PIN_CTS))) |
796 | return 0; | 808 | return 0; |
797 | } | ||
798 | prev = status; | 809 | prev = status; |
799 | } | 810 | } |
800 | 811 | ||
@@ -802,56 +813,25 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) | |||
802 | return 0; | 813 | return 0; |
803 | } | 814 | } |
804 | 815 | ||
805 | static int oti6858_ioctl(struct usb_serial_port *port, struct file *file, | 816 | static int oti6858_ioctl(struct tty_struct *tty, struct file *file, |
806 | unsigned int cmd, unsigned long arg) | 817 | unsigned int cmd, unsigned long arg) |
807 | { | 818 | { |
808 | void __user *user_arg = (void __user *) arg; | 819 | struct usb_serial_port *port = tty->driver_data; |
809 | unsigned int x; | ||
810 | 820 | ||
811 | dbg("%s(port = %d, cmd = 0x%04x, arg = 0x%08lx)", | 821 | dbg("%s(port = %d, cmd = 0x%04x, arg = 0x%08lx)", |
812 | __func__, port->number, cmd, arg); | 822 | __func__, port->number, cmd, arg); |
813 | 823 | ||
814 | switch (cmd) { | 824 | switch (cmd) { |
815 | case TIOCMBIS: | 825 | case TIOCMIWAIT: |
816 | if (copy_from_user(&x, user_arg, sizeof(x))) | 826 | dbg("%s(): TIOCMIWAIT", __func__); |
817 | return -EFAULT; | 827 | return wait_modem_info(port, arg); |
818 | return oti6858_tiocmset(port, NULL, x, 0); | 828 | default: |
819 | 829 | dbg("%s(): 0x%04x not supported", __func__, cmd); | |
820 | case TIOCMBIC: | 830 | break; |
821 | if (copy_from_user(&x, user_arg, sizeof(x))) | ||
822 | return -EFAULT; | ||
823 | return oti6858_tiocmset(port, NULL, 0, x); | ||
824 | |||
825 | case TIOCMIWAIT: | ||
826 | dbg("%s(): TIOCMIWAIT", __func__); | ||
827 | return wait_modem_info(port, arg); | ||
828 | |||
829 | default: | ||
830 | dbg("%s(): 0x%04x not supported", __func__, cmd); | ||
831 | break; | ||
832 | } | 831 | } |
833 | |||
834 | return -ENOIOCTLCMD; | 832 | return -ENOIOCTLCMD; |
835 | } | 833 | } |
836 | 834 | ||
837 | static void oti6858_break_ctl(struct usb_serial_port *port, int break_state) | ||
838 | { | ||
839 | int state; | ||
840 | |||
841 | dbg("%s(port = %d)", __func__, port->number); | ||
842 | |||
843 | state = (break_state == 0) ? 0 : 1; | ||
844 | dbg("%s(): turning break %s", __func__, state ? "on" : "off"); | ||
845 | |||
846 | /* FIXME */ | ||
847 | /* | ||
848 | result = usb_control_msg (serial->dev, usb_sndctrlpipe (serial->dev, 0), | ||
849 | BREAK_REQUEST, BREAK_REQUEST_TYPE, state, | ||
850 | 0, NULL, 0, 100); | ||
851 | if (result != 0) | ||
852 | dbg("%s(): error sending break", __func__); | ||
853 | */ | ||
854 | } | ||
855 | 835 | ||
856 | static void oti6858_shutdown(struct usb_serial *serial) | 836 | static void oti6858_shutdown(struct usb_serial *serial) |
857 | { | 837 | { |
@@ -964,7 +944,7 @@ static void oti6858_read_int_callback(struct urb *urb) | |||
964 | spin_lock_irqsave(&priv->lock, flags); | 944 | spin_lock_irqsave(&priv->lock, flags); |
965 | if (priv->flags.write_urb_in_use == 0 | 945 | if (priv->flags.write_urb_in_use == 0 |
966 | && oti6858_buf_data_avail(priv->buf) != 0) { | 946 | && oti6858_buf_data_avail(priv->buf) != 0) { |
967 | schedule_delayed_work(&priv->delayed_write_work,0); | 947 | schedule_delayed_work(&priv->delayed_write_work, 0); |
968 | resubmit = 0; | 948 | resubmit = 0; |
969 | } | 949 | } |
970 | spin_unlock_irqrestore(&priv->lock, flags); | 950 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -973,7 +953,7 @@ static void oti6858_read_int_callback(struct urb *urb) | |||
973 | if (resubmit) { | 953 | if (resubmit) { |
974 | int result; | 954 | int result; |
975 | 955 | ||
976 | // dbg("%s(): submitting interrupt urb", __func__); | 956 | /* dbg("%s(): submitting interrupt urb", __func__); */ |
977 | urb->dev = port->serial->dev; | 957 | urb->dev = port->serial->dev; |
978 | result = usb_submit_urb(urb, GFP_ATOMIC); | 958 | result = usb_submit_urb(urb, GFP_ATOMIC); |
979 | if (result != 0) { | 959 | if (result != 0) { |
@@ -1002,14 +982,16 @@ static void oti6858_read_bulk_callback(struct urb *urb) | |||
1002 | spin_unlock_irqrestore(&priv->lock, flags); | 982 | spin_unlock_irqrestore(&priv->lock, flags); |
1003 | 983 | ||
1004 | if (status != 0) { | 984 | if (status != 0) { |
1005 | if (!port->open_count) { | 985 | if (!port->port.count) { |
1006 | dbg("%s(): port is closed, exiting", __func__); | 986 | dbg("%s(): port is closed, exiting", __func__); |
1007 | return; | 987 | return; |
1008 | } | 988 | } |
1009 | /* | 989 | /* |
1010 | if (status == -EPROTO) { | 990 | if (status == -EPROTO) { |
1011 | // PL2303 mysteriously fails with -EPROTO reschedule the read | 991 | * PL2303 mysteriously fails with -EPROTO reschedule |
1012 | dbg("%s - caught -EPROTO, resubmitting the urb", __func__); | 992 | the read * |
993 | dbg("%s - caught -EPROTO, resubmitting the urb", | ||
994 | __func__); | ||
1013 | result = usb_submit_urb(urb, GFP_ATOMIC); | 995 | result = usb_submit_urb(urb, GFP_ATOMIC); |
1014 | if (result) | 996 | if (result) |
1015 | dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); | 997 | dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); |
@@ -1020,14 +1002,14 @@ static void oti6858_read_bulk_callback(struct urb *urb) | |||
1020 | return; | 1002 | return; |
1021 | } | 1003 | } |
1022 | 1004 | ||
1023 | tty = port->tty; | 1005 | tty = port->port.tty; |
1024 | if (tty != NULL && urb->actual_length > 0) { | 1006 | if (tty != NULL && urb->actual_length > 0) { |
1025 | tty_insert_flip_string(tty, data, urb->actual_length); | 1007 | tty_insert_flip_string(tty, data, urb->actual_length); |
1026 | tty_flip_buffer_push(tty); | 1008 | tty_flip_buffer_push(tty); |
1027 | } | 1009 | } |
1028 | 1010 | ||
1029 | // schedule the interrupt urb if we are still open */ | 1011 | /* schedule the interrupt urb if we are still open */ |
1030 | if (port->open_count != 0) { | 1012 | if (port->port.count != 0) { |
1031 | port->interrupt_in_urb->dev = port->serial->dev; | 1013 | port->interrupt_in_urb->dev = port->serial->dev; |
1032 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 1014 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); |
1033 | if (result != 0) { | 1015 | if (result != 0) { |
@@ -1078,7 +1060,7 @@ static void oti6858_write_bulk_callback(struct urb *urb) | |||
1078 | 1060 | ||
1079 | priv->flags.write_urb_in_use = 0; | 1061 | priv->flags.write_urb_in_use = 0; |
1080 | 1062 | ||
1081 | // schedule the interrupt urb if we are still open */ | 1063 | /* schedule the interrupt urb if we are still open */ |
1082 | port->interrupt_in_urb->dev = port->serial->dev; | 1064 | port->interrupt_in_urb->dev = port->serial->dev; |
1083 | dbg("%s(): submitting interrupt urb", __func__); | 1065 | dbg("%s(): submitting interrupt urb", __func__); |
1084 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 1066 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); |
@@ -1153,7 +1135,7 @@ static unsigned int oti6858_buf_data_avail(struct oti6858_buf *pb) | |||
1153 | { | 1135 | { |
1154 | if (pb == NULL) | 1136 | if (pb == NULL) |
1155 | return 0; | 1137 | return 0; |
1156 | return ((pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size); | 1138 | return (pb->buf_size + pb->buf_put - pb->buf_get) % pb->buf_size; |
1157 | } | 1139 | } |
1158 | 1140 | ||
1159 | /* | 1141 | /* |
@@ -1166,7 +1148,7 @@ static unsigned int oti6858_buf_space_avail(struct oti6858_buf *pb) | |||
1166 | { | 1148 | { |
1167 | if (pb == NULL) | 1149 | if (pb == NULL) |
1168 | return 0; | 1150 | return 0; |
1169 | return ((pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size); | 1151 | return (pb->buf_size + pb->buf_get - pb->buf_put - 1) % pb->buf_size; |
1170 | } | 1152 | } |
1171 | 1153 | ||
1172 | /* | 1154 | /* |
@@ -1253,13 +1235,12 @@ static int __init oti6858_init(void) | |||
1253 | { | 1235 | { |
1254 | int retval; | 1236 | int retval; |
1255 | 1237 | ||
1256 | if ((retval = usb_serial_register(&oti6858_device)) == 0) { | 1238 | retval = usb_serial_register(&oti6858_device); |
1257 | if ((retval = usb_register(&oti6858_driver)) != 0) | 1239 | if (retval == 0) { |
1240 | retval = usb_register(&oti6858_driver); | ||
1241 | if (retval) | ||
1258 | usb_serial_deregister(&oti6858_device); | 1242 | usb_serial_deregister(&oti6858_device); |
1259 | else | ||
1260 | return 0; | ||
1261 | } | 1243 | } |
1262 | |||
1263 | return retval; | 1244 | return retval; |
1264 | } | 1245 | } |
1265 | 1246 | ||