Lines 297-302
Link Here
|
297 |
#include <linux/spinlock.h> |
297 |
#include <linux/spinlock.h> |
298 |
#include <linux/list.h> |
298 |
#include <linux/list.h> |
299 |
#include <linux/smp_lock.h> |
299 |
#include <linux/smp_lock.h> |
|
|
300 |
#include <linux/spinlock.h> |
300 |
#include <linux/usb.h> |
301 |
#include <linux/usb.h> |
301 |
|
302 |
|
302 |
#ifdef CONFIG_USB_SERIAL_DEBUG |
303 |
#ifdef CONFIG_USB_SERIAL_DEBUG |
Lines 347-356
Link Here
|
347 |
}; |
348 |
}; |
348 |
#endif |
349 |
#endif |
349 |
|
350 |
|
|
|
351 |
/* |
352 |
* The post kludge structures and variables. |
353 |
*/ |
354 |
#define POST_BSIZE 100 /* little below 128 in total */ |
355 |
struct usb_serial_post_job { |
356 |
struct list_head link; |
357 |
struct usb_serial_port *port; |
358 |
int len; |
359 |
char buff[POST_BSIZE]; |
360 |
}; |
361 |
static spinlock_t post_lock = SPIN_LOCK_UNLOCKED; /* Also covers ->ref */ |
362 |
static struct list_head post_list = LIST_HEAD_INIT(post_list); |
363 |
static struct tq_struct post_task; |
350 |
|
364 |
|
351 |
/* local function prototypes */ |
365 |
/* local function prototypes */ |
352 |
static int serial_open (struct tty_struct *tty, struct file * filp); |
366 |
static int serial_open (struct tty_struct *tty, struct file * filp); |
353 |
static void serial_close (struct tty_struct *tty, struct file * filp); |
367 |
static void serial_close (struct tty_struct *tty, struct file * filp); |
|
|
368 |
static int __serial_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count); |
354 |
static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count); |
369 |
static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count); |
355 |
static int serial_write_room (struct tty_struct *tty); |
370 |
static int serial_write_room (struct tty_struct *tty); |
356 |
static int serial_chars_in_buffer (struct tty_struct *tty); |
371 |
static int serial_chars_in_buffer (struct tty_struct *tty); |
Lines 448-453
Link Here
|
448 |
return; |
463 |
return; |
449 |
} |
464 |
} |
450 |
|
465 |
|
|
|
466 |
/* |
467 |
* The post kludge. |
468 |
* |
469 |
* Our component drivers are hideously buggy and written by people |
470 |
* who have difficulty understanding the concept of spinlocks. |
471 |
* There were so many races and lockups that Greg K-H made a watershed |
472 |
* decision to provide what is essentially a single-threaded sandbox |
473 |
* for component drivers, protected by a semaphore. It helped a lot, but |
474 |
* for one little problem: when tty->low_latency is set, line disciplines |
475 |
* can call ->write from an interrupt, where the semaphore oopses. |
476 |
* |
477 |
* Rather than open the whole can of worms again, we just post writes |
478 |
* into a helper which can sleep. |
479 |
* |
480 |
* Kernel 2.6 has a proper fix, reportedly. |
481 |
* |
482 |
* XXX Nothing prevents this from looping forever. |
483 |
*/ |
484 |
static void post_helper(void *arg) |
485 |
{ |
486 |
struct usb_serial_post_job *job; |
487 |
struct usb_serial_port *port; |
488 |
struct usb_serial *serial; |
489 |
unsigned int flags; |
490 |
|
491 |
spin_lock_irqsave(&post_lock, flags); |
492 |
while (!list_empty(&post_list)) { |
493 |
job = list_entry(post_list.next, struct usb_serial_post_job, link); |
494 |
list_del(&job->link); |
495 |
spin_unlock_irqrestore(&post_lock, flags); |
496 |
|
497 |
port = job->port; |
498 |
serial = get_usb_serial (port, __FUNCTION__); |
499 |
|
500 |
down(&port->sem); |
501 |
if (port->tty != NULL) |
502 |
__serial_write(port, 0, job->buff, job->len); |
503 |
up(&port->sem); |
504 |
|
505 |
kfree(job); |
506 |
spin_lock_irqsave(&post_lock, flags); |
507 |
if (--serial->ref == 0) |
508 |
kfree(serial); |
509 |
} |
510 |
spin_unlock_irqrestore(&post_lock, flags); |
511 |
} |
512 |
|
451 |
#ifdef USES_EZUSB_FUNCTIONS |
513 |
#ifdef USES_EZUSB_FUNCTIONS |
452 |
/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */ |
514 |
/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */ |
453 |
#define CPUCS_REG 0x7F92 |
515 |
#define CPUCS_REG 0x7F92 |
Lines 576-598
Link Here
|
576 |
|
638 |
|
577 |
/* if disconnect beat us to the punch here, there's nothing to do */ |
639 |
/* if disconnect beat us to the punch here, there's nothing to do */ |
578 |
if (tty->driver_data) { |
640 |
if (tty->driver_data) { |
|
|
641 |
/* post_helper(NULL); */ /* Correct, but unimportant for echo.*/ |
579 |
__serial_close(port, filp); |
642 |
__serial_close(port, filp); |
580 |
} |
643 |
} |
581 |
|
644 |
|
582 |
up (&port->sem); |
645 |
up (&port->sem); |
583 |
} |
646 |
} |
584 |
|
647 |
|
585 |
static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count) |
648 |
static int __serial_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count) |
586 |
{ |
649 |
{ |
587 |
struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
|
|
588 |
struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
650 |
struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
589 |
int retval = -EINVAL; |
651 |
int retval = -EINVAL; |
590 |
|
652 |
|
591 |
if (!serial) |
653 |
if (!serial) |
592 |
return -ENODEV; |
654 |
return -ENODEV; |
593 |
|
655 |
|
594 |
down (&port->sem); |
|
|
595 |
|
596 |
dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); |
656 |
dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); |
597 |
|
657 |
|
598 |
if (!port->open_count) { |
658 |
if (!port->open_count) { |
Lines 607-616
Link Here
|
607 |
retval = generic_write(port, from_user, buf, count); |
667 |
retval = generic_write(port, from_user, buf, count); |
608 |
|
668 |
|
609 |
exit: |
669 |
exit: |
610 |
up (&port->sem); |
|
|
611 |
return retval; |
670 |
return retval; |
612 |
} |
671 |
} |
613 |
|
672 |
|
|
|
673 |
static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count) |
674 |
{ |
675 |
struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
676 |
struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); |
677 |
struct usb_serial_post_job *job; |
678 |
unsigned long flags; |
679 |
int rc; |
680 |
|
681 |
if (!in_interrupt()) { |
682 |
/* |
683 |
* Run post_list to reduce a possiblity of reordered writes. |
684 |
* Tasks can make keventd to sleep, sometimes for a long time. |
685 |
*/ |
686 |
post_helper(NULL); |
687 |
|
688 |
down(&port->sem); |
689 |
rc = __serial_write(port, from_user, buf, count); |
690 |
up(&port->sem); |
691 |
return rc; |
692 |
} |
693 |
|
694 |
if (from_user) { |
695 |
/* |
696 |
* This is a BUG-able offense because we cannot |
697 |
* pagefault while in_interrupt, but we want to see |
698 |
* something in dmesg rather than just blinking LEDs. |
699 |
*/ |
700 |
err("user data in interrupt write"); |
701 |
return -EINVAL; |
702 |
} |
703 |
|
704 |
job = kmalloc(sizeof(struct usb_serial_post_job), GFP_ATOMIC); |
705 |
if (job == NULL) |
706 |
return -ENOMEM; |
707 |
|
708 |
job->port = port; |
709 |
if ((job->len = count) >= POST_BSIZE) { |
710 |
static int rate = 0; |
711 |
/* |
712 |
* Data loss due to extreme circumstances. |
713 |
* It's a ususal thing on serial to lose characters, isn't it? |
714 |
* Neener, neener! Actually, it's probably an echo loop anyway. |
715 |
* Only happens when getty starts talking to Visor. |
716 |
*/ |
717 |
if (++rate % 1000 < 5) |
718 |
err("too much data (%d)", count); |
719 |
job->len = POST_BSIZE; |
720 |
} |
721 |
memcpy(job->buff, buf, job->len); |
722 |
|
723 |
spin_lock_irqsave(&post_lock, flags); |
724 |
list_add_tail(&job->link, &post_list); |
725 |
serial->ref++; /* Protect the port->sem from kfree() */ |
726 |
schedule_task(&post_task); |
727 |
spin_unlock_irqrestore(&post_lock, flags); |
728 |
|
729 |
return count; |
730 |
} |
731 |
|
614 |
static int serial_write_room (struct tty_struct *tty) |
732 |
static int serial_write_room (struct tty_struct *tty) |
615 |
{ |
733 |
{ |
616 |
struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
734 |
struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; |
Lines 620-625
Link Here
|
620 |
if (!serial) |
738 |
if (!serial) |
621 |
return -ENODEV; |
739 |
return -ENODEV; |
622 |
|
740 |
|
|
|
741 |
if (in_interrupt()) |
742 |
return POST_BSIZE; |
743 |
|
623 |
down (&port->sem); |
744 |
down (&port->sem); |
624 |
|
745 |
|
625 |
dbg("%s - port %d", __FUNCTION__, port->number); |
746 |
dbg("%s - port %d", __FUNCTION__, port->number); |
Lines 1128-1133
Link Here
|
1128 |
int num_ports; |
1249 |
int num_ports; |
1129 |
int max_endpoints; |
1250 |
int max_endpoints; |
1130 |
const struct usb_device_id *id_pattern = NULL; |
1251 |
const struct usb_device_id *id_pattern = NULL; |
|
|
1252 |
unsigned long flags; |
1131 |
|
1253 |
|
1132 |
/* loop through our list of known serial converters, and see if this |
1254 |
/* loop through our list of known serial converters, and see if this |
1133 |
device matches. */ |
1255 |
device matches. */ |
Lines 1338-1348
Link Here
|
1338 |
init_MUTEX (&port->sem); |
1460 |
init_MUTEX (&port->sem); |
1339 |
} |
1461 |
} |
1340 |
|
1462 |
|
|
|
1463 |
spin_lock_irqsave(&post_lock, flags); |
1464 |
serial->ref = 1; |
1465 |
spin_unlock_irqrestore(&post_lock, flags); |
1466 |
|
1341 |
/* if this device type has a startup function, call it */ |
1467 |
/* if this device type has a startup function, call it */ |
1342 |
if (type->startup) { |
1468 |
if (type->startup) { |
1343 |
i = type->startup (serial); |
1469 |
i = type->startup (serial); |
1344 |
if (i < 0) |
1470 |
if (i < 0) |
1345 |
goto probe_error; |
1471 |
goto startup_error; |
1346 |
if (i > 0) |
1472 |
if (i > 0) |
1347 |
return serial; |
1473 |
return serial; |
1348 |
} |
1474 |
} |
Lines 1357-1362
Link Here
|
1357 |
return serial; /* success */ |
1483 |
return serial; /* success */ |
1358 |
|
1484 |
|
1359 |
|
1485 |
|
|
|
1486 |
startup_error: |
1487 |
spin_lock_irqsave(&post_lock, flags); |
1488 |
if (serial->ref != 1) { |
1489 |
err("bug in component startup: ref %d\n", serial->ref); |
1490 |
} |
1491 |
spin_unlock_irqrestore(&post_lock, flags); |
1360 |
probe_error: |
1492 |
probe_error: |
1361 |
for (i = 0; i < num_bulk_in; ++i) { |
1493 |
for (i = 0; i < num_bulk_in; ++i) { |
1362 |
port = &serial->port[i]; |
1494 |
port = &serial->port[i]; |
Lines 1392-1397
Link Here
|
1392 |
{ |
1524 |
{ |
1393 |
struct usb_serial *serial = (struct usb_serial *) ptr; |
1525 |
struct usb_serial *serial = (struct usb_serial *) ptr; |
1394 |
struct usb_serial_port *port; |
1526 |
struct usb_serial_port *port; |
|
|
1527 |
unsigned long flags; |
1395 |
int i; |
1528 |
int i; |
1396 |
|
1529 |
|
1397 |
dbg ("%s", __FUNCTION__); |
1530 |
dbg ("%s", __FUNCTION__); |
Lines 1452-1458
Link Here
|
1452 |
return_serial (serial); |
1585 |
return_serial (serial); |
1453 |
|
1586 |
|
1454 |
/* free up any memory that we allocated */ |
1587 |
/* free up any memory that we allocated */ |
1455 |
kfree (serial); |
1588 |
spin_lock_irqsave(&post_lock, flags); |
|
|
1589 |
if (--serial->ref == 0) |
1590 |
kfree(serial); |
1591 |
spin_unlock_irqrestore(&post_lock, flags); |
1456 |
|
1592 |
|
1457 |
} else { |
1593 |
} else { |
1458 |
info("device disconnected"); |
1594 |
info("device disconnected"); |
Lines 1504-1509
Link Here
|
1504 |
for (i = 0; i < SERIAL_TTY_MINORS; ++i) { |
1640 |
for (i = 0; i < SERIAL_TTY_MINORS; ++i) { |
1505 |
serial_table[i] = NULL; |
1641 |
serial_table[i] = NULL; |
1506 |
} |
1642 |
} |
|
|
1643 |
post_task.routine = post_helper; |
1507 |
|
1644 |
|
1508 |
/* register the tty driver */ |
1645 |
/* register the tty driver */ |
1509 |
serial_tty_driver.init_termios = tty_std_termios; |
1646 |
serial_tty_driver.init_termios = tty_std_termios; |