[Midnightbsd-cvs] src [12251] trunk/sys/dev/usb/usb_generic.c: Fix a lost completion event issue towards libusb(3).
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sat Aug 10 10:49:39 EDT 2019
Revision: 12251
http://svnweb.midnightbsd.org/src/?rev=12251
Author: laffer1
Date: 2019-08-10 10:49:39 -0400 (Sat, 10 Aug 2019)
Log Message:
-----------
Fix a lost completion event issue towards libusb(3).
Modified Paths:
--------------
trunk/sys/dev/usb/usb_generic.c
Modified: trunk/sys/dev/usb/usb_generic.c
===================================================================
--- trunk/sys/dev/usb/usb_generic.c 2019-08-10 14:45:57 UTC (rev 12250)
+++ trunk/sys/dev/usb/usb_generic.c 2019-08-10 14:49:39 UTC (rev 12251)
@@ -1,5 +1,5 @@
/* $MidnightBSD$ */
-/* $FreeBSD: stable/10/sys/dev/usb/usb_generic.c 305734 2016-09-12 10:17:25Z hselasky $ */
+/* $FreeBSD: stable/10/sys/dev/usb/usb_generic.c 348857 2019-06-10 13:37:38Z hselasky $ */
/*-
* Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
*
@@ -183,7 +183,8 @@
struct usb_endpoint_descriptor *ed = ep->edesc;
uint8_t type;
- DPRINTFN(6, "flag=0x%x\n", fflags);
+ DPRINTFN(1, "flag=0x%x pid=%d name=%s\n", fflags,
+ curthread->td_proc->p_pid, curthread->td_proc->p_comm);
mtx_lock(f->priv_mtx);
switch (usbd_get_speed(f->udev)) {
@@ -213,8 +214,10 @@
static void
ugen_close(struct usb_fifo *f, int fflags)
{
- DPRINTFN(6, "flag=0x%x\n", fflags);
+ DPRINTFN(1, "flag=0x%x pid=%d name=%s\n", fflags,
+ curthread->td_proc->p_pid, curthread->td_proc->p_comm);
+
/* cleanup */
mtx_lock(f->priv_mtx);
@@ -1216,6 +1219,40 @@
}
static int
+ugen_fs_copy_out_cancelled(struct usb_fs_endpoint *fs_ep_uptr)
+{
+ struct usb_fs_endpoint fs_ep;
+ int error;
+
+ error = copyin(fs_ep_uptr, &fs_ep, sizeof(fs_ep));
+ if (error)
+ return (error);
+
+ fs_ep.status = USB_ERR_CANCELLED;
+ fs_ep.aFrames = 0;
+ fs_ep.isoc_time_complete = 0;
+
+ /* update "aFrames" */
+ error = copyout(&fs_ep.aFrames, &fs_ep_uptr->aFrames,
+ sizeof(fs_ep.aFrames));
+ if (error)
+ goto done;
+
+ /* update "isoc_time_complete" */
+ error = copyout(&fs_ep.isoc_time_complete,
+ &fs_ep_uptr->isoc_time_complete,
+ sizeof(fs_ep.isoc_time_complete));
+ if (error)
+ goto done;
+
+ /* update "status" */
+ error = copyout(&fs_ep.status, &fs_ep_uptr->status,
+ sizeof(fs_ep.status));
+done:
+ return (error);
+}
+
+static int
ugen_fs_copy_out(struct usb_fifo *f, uint8_t ep_index)
{
struct usb_device_request *req;
@@ -1240,8 +1277,13 @@
return (EINVAL);
mtx_lock(f->priv_mtx);
- if (usbd_transfer_pending(xfer)) {
+ if (!xfer->flags_int.transferring &&
+ !xfer->flags_int.started) {
mtx_unlock(f->priv_mtx);
+ DPRINTF("Returning fake cancel event\n");
+ return (ugen_fs_copy_out_cancelled(f->fs_ep_ptr + ep_index));
+ } else if (usbd_transfer_pending(xfer)) {
+ mtx_unlock(f->priv_mtx);
return (EBUSY); /* should not happen */
}
mtx_unlock(f->priv_mtx);
@@ -1361,6 +1403,7 @@
sizeof(fs_ep.isoc_time_complete));
if (error)
goto done;
+
/* update "status" */
error = copyout(&fs_ep.status, &fs_ep_uptr->status,
sizeof(fs_ep.status));
@@ -1449,12 +1492,15 @@
xfer = f->fs_xfer[u.pstart->ep_index];
if (usbd_transfer_pending(xfer)) {
usbd_transfer_stop(xfer);
+
/*
* Check if the USB transfer was stopped
- * before it was even started. Else a cancel
- * callback will be pending.
+ * before it was even started and fake a
+ * cancel event.
*/
- if (!xfer->flags_int.transferring) {
+ if (!xfer->flags_int.transferring &&
+ !xfer->flags_int.started) {
+ DPRINTF("Issuing fake completion event\n");
ugen_fs_set_complete(xfer->priv_sc,
USB_P2U(xfer->priv_fifo));
}
More information about the Midnightbsd-cvs
mailing list