Re: [BUG] cdc-acm: no data available after port open

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Jun 13, 2016 at 11:02:19AM +0200, Oliver Neukum wrote:
> On Mon, 2016-06-13 at 00:37 +0200, Ladislav Michl wrote:
> > On Sun, Jun 12, 2016 at 11:03:45PM +0200, Ladislav Michl wrote:
> > > Once ttyACM0 starts behave strangely, read() returns only what's in buffer before
> > > ttyACM0 was opened and then hangs infinitely. As this bug is hard to trigger, has
> > > anyone clue where to start debugging?
> > 
> > Forgot to mention, once this happens "usb 3-1.4: clear tt 1 (9061) error -75"
> > starts showing in the syslog. Also "cdc_acm 3-1.4.3:1.0: failed to set dtr/rts",
> > but this one is there normally.
> 
> The translation transactor in the hub is reporting an error.
> That should be reported to the driver, but there is no good
> error handling.

Hmm, assuming that error comes from ehci-q.c:qtd_copy_status() there
is one more disturbing FIXME:

static int qtd_copy_status (
	struct ehci_hcd *ehci,
	struct urb *urb,
	size_t length,
	u32 token
)
{
	int	status = -EINPROGRESS;

	/* count IN/OUT bytes, not SETUP (even short packets) */
	if (likely (QTD_PID (token) != 2))
		urb->actual_length += length - QTD_LENGTH (token);

	/* don't modify error codes */
	if (unlikely(urb->unlinked))
		return status;

	/* force cleanup after short read; not always an error */
	if (unlikely (IS_SHORT_READ (token)))
		status = -EREMOTEIO;

	/* serious "can't proceed" faults reported by the hardware */
	if (token & QTD_STS_HALT) {
		if (token & QTD_STS_BABBLE) {
			/* FIXME "must" disable babbling device's port too */
			status = -EOVERFLOW;
		/* CERR nonzero + halt --> stall */
		} else if (QTD_CERR(token)) {
			status = -EPIPE;

		/* In theory, more than one of the following bits can be set
		 * since they are sticky and the transaction is retried.
		 * Which to test first is rather arbitrary.
		 */
		} else if (token & QTD_STS_MMF) {
			/* fs/ls interrupt xfer missed the complete-split */
			status = -EPROTO;
		} else if (token & QTD_STS_DBE) {
			status = (QTD_PID (token) == 1) /* IN ? */
				? -ENOSR  /* hc couldn't read data */
				: -ECOMM; /* hc couldn't write data */
		} else if (token & QTD_STS_XACT) {
			/* timeout, bad CRC, wrong PID, etc */
			ehci_dbg(ehci, "devpath %s ep%d%s 3strikes\n",
				urb->dev->devpath,
				usb_pipeendpoint(urb->pipe),
				usb_pipein(urb->pipe) ? "in" : "out");
			status = -EPROTO;
		} else {	/* unknown */
			status = -EPROTO;
		}
	}

	return status;
}

> static void acm_read_bulk_callback(struct urb *urb)
> {
>         struct acm_rb *rb = urb->context;
>         struct acm *acm = rb->instance;
>         unsigned long flags;
>         int status = urb->status;
> 
>         dev_vdbg(&acm->data->dev, "%s - urb %d, len %d\n", __func__,
>                                         rb->index, urb->actual_length);
> 
>         if (!acm->dev) {
>                 set_bit(rb->index, &acm->read_urbs_free);
>                 dev_dbg(&acm->data->dev, "%s - disconnected\n", __func__);
>                 return;
>         }
> 
>         if (status) {
>                 set_bit(rb->index, &acm->read_urbs_free);
>                 dev_dbg(&acm->data->dev, "%s - non-zero urb status: %d\n",
>                                                         __func__, status);
>                 if ((status != -ENOENT) || (urb->actual_length == 0))
>                         return;
>         }
> 
> Can you please switch on dynamic debugging for cdc_acm to see what
> is being reported?

Yes, just recompiled with CONFIG_DYNAMIC_DEBUG. It'll take some until
that behaviour shows up.

Thanks,
	ladis
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux