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);