patch-2.3.42 linux/drivers/usb/acm.c
Next file: linux/drivers/usb/ov511.c
Previous file: linux/drivers/usb/Makefile
Back to the patch index
Back to the overall index
- Lines: 97
- Date:
Mon Jan 31 10:09:22 2000
- Orig file:
v2.3.41/linux/drivers/usb/acm.c
- Orig date:
Fri Jan 21 18:19:17 2000
diff -u --recursive --new-file v2.3.41/linux/drivers/usb/acm.c linux/drivers/usb/acm.c
@@ -1,5 +1,5 @@
/*
- * acm.c Version 0.14
+ * acm.c Version 0.15
*
* Copyright (c) 1999 Armin Fuerst <fuerst@in.tum.de>
* Copyright (c) 1999 Pavel Machek <pavel@suse.cz>
@@ -17,6 +17,7 @@
* v0.12 - added TIOCM ioctls, added break handling, made struct acm kmalloced
* v0.13 - added termios, added hangup
* v0.14 - sized down struct acm
+ * v0.15 - fixed flow control again - characters could be lost
*/
/*
@@ -137,6 +138,7 @@
unsigned int writesize; /* max packet size for the output bulk endpoint */
unsigned int used; /* someone has this acm's device open */
unsigned int minor; /* acm minor number */
+ unsigned char throttle; /* throttled by tty layer */
unsigned char clocal; /* termios CLOCAL */
};
@@ -210,8 +212,6 @@
dr->request, dr->index, dr->length, data[0], data[1]);
return;
}
-
- return;
}
static void acm_read_bulk(struct urb *urb)
@@ -219,24 +219,25 @@
struct acm *acm = urb->context;
struct tty_struct *tty = acm->tty;
unsigned char *data = urb->transfer_buffer;
- int i;
+ int i = 0;
if (!ACM_READY(acm)) return;
- if (!urb->status) {
-
- for (i = 0; i < urb->actual_length; i++)
+ if (!urb->status & !acm->throttle) {
+ for (i = 0; i < urb->actual_length && !acm->throttle; i++)
tty_insert_flip_char(tty, data[i], 0);
-
tty_flip_buffer_push(tty);
-
} else
dbg("nonzero read bulk status received: %d", urb->status);
- if (usb_submit_urb(urb))
- dbg("failed resubmitting read urb");
-
- return;
+ if (!acm->throttle) {
+ urb->actual_length = 0;
+ if (usb_submit_urb(urb))
+ dbg("failed resubmitting read urb");
+ } else {
+ memmove(data, data + i, urb->actual_length - i);
+ urb->actual_length -= i;
+ }
}
static void acm_write_bulk(struct urb *urb)
@@ -253,8 +254,6 @@
(tty->ldisc.write_wakeup)(tty);
wake_up_interruptible(&tty->write_wait);
-
- return;
}
/*
@@ -347,15 +346,16 @@
{
struct acm *acm = tty->driver_data;
if (!ACM_READY(acm)) return;
- usb_unlink_urb(&acm->readurb);
+ acm->throttle = 1;
}
static void acm_tty_unthrottle(struct tty_struct *tty)
{
struct acm *acm = tty->driver_data;
if (!ACM_READY(acm)) return;
- if (usb_submit_urb(&acm->readurb))
- dbg("usb_submit_urb(read bulk) in unthrottle() failed");
+ acm->throttle = 0;
+ if (acm->readurb.status != -EINPROGRESS)
+ acm_read_bulk(&acm->readurb);
}
static void acm_tty_break_ctl(struct tty_struct *tty, int state)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)