Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 49600 | Differences between
and this patch

Collapse All | Expand All

(-)linux-2.4.20-20.7.5/drivers/usb/serial/usbserial.c (-7 / +144 lines)
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;
(-)linux-2.4.20-20.7.5/drivers/usb/serial/usb-serial.h (+3 lines)
Lines 151-156 Link Here
151
	__u16				product;
151
	__u16				product;
152
	struct usb_serial_port		port[MAX_NUM_PORTS];
152
	struct usb_serial_port		port[MAX_NUM_PORTS];
153
	void *				private;
153
	void *				private;
154
#ifndef __GENKSYMS__
155
	int				ref;
156
#endif
154
};
157
};
155
158
156
159

Return to bug 49600