On Fri, Jun 15, 2001 at 01:24:31AM +0200, Georg Acher wrote:
> On Thu, Jun 14, 2001 at 11:11:03PM +0200, Vojtech Pavlik wrote:
> <...>
> > Perhaps there is indeed something with flow control, and perhaps we
> > indeed need to be able to receive more than the 64 bytes in a frame, but
> > still if there is any method to do that other than enabling FSBR, we
> > need to try it.
> <...>
> I don't know anything about how the buffering of read data is actually done
> in the devices, but what about submitting a bulk read URB with a length of,
> say, 256bytes?
Yes, that's what I've been thinking about. Back when I wrote the ACM
driver I thought the maxpacket size is the max size of a bulk transfer.
Which is of course wrong. I think 1024 bytes will be a nicer number.
> If the device actually has more than 64bytes buffered, it is possible that
> one URB can read it all. The Anchor chips for example have an optional
> double buffering mode for bulk endpoints, allowing back-to-back transfers
> with zero delay.
Yes, I hope so.
Pete: Can you try this patch instead of removing NO_FSBR?
(Looking through acm.c ... guess it'll need a facelift ...)
--
Vojtech Pavlik
SuSE Labs
--- linux/drivers/usb/acm.old Fri Jun 15 08:48:32 2001
+++ linux/drivers/usb/acm.c Fri Jun 15 08:57:39 2001
@@ -1,10 +1,10 @@
/*
- * acm.c Version 0.19
+ * acm.c Version 0.20
*
- * Copyright (c) 1999 Armin Fuerst <[EMAIL PROTECTED]>
- * Copyright (c) 1999 Pavel Machek <[EMAIL PROTECTED]>
- * Copyright (c) 1999 Johannes Erdfelt <[EMAIL PROTECTED]>
- * Copyright (c) 2000 Vojtech Pavlik <[EMAIL PROTECTED]>
+ * Copyright (c) 1999 Armin Fuerst <[EMAIL PROTECTED]>
+ * Copyright (c) 1999 Pavel Machek <[EMAIL PROTECTED]>
+ * Copyright (c) 1999 Johannes Erdfelt <[EMAIL PROTECTED]>
+ * Copyright (c) 2000-2001 Vojtech Pavlik <[EMAIL PROTECTED]>
*
* USB Abstract Control Model driver for USB modems and ISDN adapters
*
@@ -22,6 +22,7 @@
* v0.17 - added new style probing
* v0.18 - fixed new style probing for devices with more configurations
* v0.19 - fixed CLOCAL handling (thanks to Richard Shih-Ping Chan)
+ * v0.20 - trying to workaround a problem with 3Com ISDN TA
*/
/*
@@ -59,7 +60,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v0.18"
+#define DRIVER_VERSION "v0.20"
#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"
#define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN
adapters"
@@ -123,6 +124,12 @@
#define ACM_CTRL_OVERRUN 0x40
/*
+ * Transfer buffer sizes, both Rx and Tx.
+ */
+
+#define ACM_BUFFER_SIZE 1024
+
+/*
* Line speed and caracter encoding.
*/
@@ -146,7 +153,6 @@
struct tq_struct tqueue; /* task queue for line
discipline waking up */
unsigned int ctrlin; /* input control lines (DCD,
DSR, RI, break, overruns) */
unsigned int ctrlout; /* output control lines (DTR,
RTS) */
- 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 */
@@ -359,7 +365,7 @@
if (acm->writeurb.status == -EINPROGRESS) return 0;
if (!count) return 0;
- count = (count > acm->writesize) ? acm->writesize : count;
+ count = (count > ACM_BUFFER_SIZE) ? ACM_BUFFER_SIZE : count;
if (from_user)
copy_from_user(acm->writeurb.transfer_buffer, buf, count);
@@ -379,7 +385,7 @@
{
struct acm *acm = tty->driver_data;
if (!ACM_READY(acm)) return -EINVAL;
- return acm->writeurb.status == -EINPROGRESS ? 0 : acm->writesize;
+ return acm->writeurb.status == -EINPROGRESS ? 0 : ACM_BUFFER_SIZE;
}
static int acm_tty_chars_in_buffer(struct tty_struct *tty)
@@ -509,7 +515,7 @@
struct usb_config_descriptor *cfacm;
struct usb_interface_descriptor *ifcom, *ifdata;
struct usb_endpoint_descriptor *epctrl, *epread, *epwrite;
- int readsize, ctrlsize, minor, i;
+ int ctrlsize, minor, i;
unsigned char *buf;
for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
@@ -566,8 +572,6 @@
memset(acm, 0, sizeof(struct acm));
ctrlsize = epctrl->wMaxPacketSize;
- readsize = epread->wMaxPacketSize;
- acm->writesize = epwrite->wMaxPacketSize;
acm->iface = cfacm->interface;
acm->minor = minor;
acm->dev = dev;
@@ -575,7 +579,7 @@
acm->tqueue.routine = acm_softint;
acm->tqueue.data = acm;
- if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize,
GFP_KERNEL))) {
+ if (!(buf = kmalloc(ctrlsize + 2 * ACM_BUFFER_SIZE, GFP_KERNEL))) {
err("out of memory");
kfree(acm);
return NULL;
@@ -585,11 +589,11 @@
buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
FILL_BULK_URB(&acm->readurb, dev, usb_rcvbulkpipe(dev,
epread->bEndpointAddress),
- buf += ctrlsize, readsize, acm_read_bulk, acm);
+ buf += ctrlsize, ACM_BUFFER_SIZE, acm_read_bulk, acm);
acm->readurb.transfer_flags |= USB_NO_FSBR;
FILL_BULK_URB(&acm->writeurb, dev, usb_sndbulkpipe(dev,
epwrite->bEndpointAddress),
- buf += readsize, acm->writesize, acm_write_bulk, acm);
+ buf += ACM_BUFFER_SIZE, ACM_BUFFER_SIZE, acm_write_bulk, acm);
acm->writeurb.transfer_flags |= USB_NO_FSBR;
printk(KERN_INFO "ttyACM%d: USB ACM device\n", minor);