From e0bd4233ccf23151f4adfa14f45f328ae57c7c20 Mon Sep 17 00:00:00 2001 From: Nils Philippsen Date: Jun 09 2015 01:24:44 +0000 Subject: backport USB3 xhci patch from upstream master (#1228954) --- diff --git a/sane-backends-1.0.24-usb3-xhci.patch b/sane-backends-1.0.24-usb3-xhci.patch new file mode 100644 index 0000000..c06d676 --- /dev/null +++ b/sane-backends-1.0.24-usb3-xhci.patch @@ -0,0 +1,170 @@ +From ccba990b2c2a39b35290370adad2acf8a4d8dc7e Mon Sep 17 00:00:00 2001 +From: Nils Philippsen +Date: Mon, 8 Jun 2015 17:51:25 +0200 +Subject: [PATCH] patch: usb3-xhci + +Squashed commit of the following: + +commit 73cb422f860a84aca7a19114936ead1794d77890 +Author: m. allan noah +Date: Tue Dec 16 10:23:55 2014 -0500 + + sanei_usb: Linux USB3/xhci workarounds + + add calls to sanei_usb_set_altinterface in sanei_usb_close and + sanei_usb_clear_halt- hopefully work around USB3/xhci problems + in Linux. Also, remove some unused code, and fix debug messages. + + (cherry picked from commit 014b45d920f1fb630e1a31bb01f1da02ea2a6a87) +--- + sanei/sanei_usb.c | 56 ++++++++++++++++++++++++++++++++----------------------- + 1 file changed, 33 insertions(+), 23 deletions(-) + +diff --git a/sanei/sanei_usb.c b/sanei/sanei_usb.c +index 491ceeb..3777ae8 100644 +--- a/sanei/sanei_usb.c ++++ b/sanei/sanei_usb.c +@@ -154,6 +154,7 @@ typedef struct + SANE_Int control_in_ep; + SANE_Int control_out_ep; + SANE_Int interface_nr; ++ SANE_Int alt_setting; + SANE_Int missing; + #ifdef HAVE_LIBUSB + usb_dev_handle *libusb_handle; +@@ -633,6 +634,7 @@ static void usbcall_scan_devices(void) + device.product = pDevDesc->idProduct; + device.method = sanei_usb_method_usbcalls; + device.interface_nr = interface; ++ device.alt_setting = 0; + DBG (4, "%s: found usbcalls device (0x%04x/0x%04x) as device number %s\n", __func__, + pDevDesc->idVendor, pDevDesc->idProduct,device.devname); + store_device(device); +@@ -819,7 +821,7 @@ static void libusb_scan_devices(void) + "scanner (%d/%d)\n", __func__, dev->descriptor.idVendor, + dev->descriptor.idProduct, interface, + dev->descriptor.bDeviceClass, +- dev->config[0].interface[interface].altsetting != 0 ++ dev->config[0].interface[interface].num_altsetting != 0 + ? dev->config[0].interface[interface].altsetting[0]. + bInterfaceClass : -1); + } +@@ -843,6 +845,7 @@ static void libusb_scan_devices(void) + device.product = dev->descriptor.idProduct; + device.method = sanei_usb_method_libusb; + device.interface_nr = interface; ++ device.alt_setting = 0; + DBG (4, + "%s: found libusb device (0x%04x/0x%04x) interface " + "%d at %s\n", __func__, +@@ -989,7 +992,7 @@ static void libusb_scan_devices(void) + "%s: device 0x%04x/0x%04x, interface %d " + "doesn't look like a scanner (%d/%d)\n", __func__, + vid, pid, interface, desc.bDeviceClass, +- (config0->interface[interface].altsetting != 0) ++ (config0->interface[interface].num_altsetting != 0) + ? config0->interface[interface].altsetting[0].bInterfaceClass : -1); + } + +@@ -1016,6 +1019,7 @@ static void libusb_scan_devices(void) + device.product = pid; + device.method = sanei_usb_method_libusb; + device.interface_nr = interface; ++ device.alt_setting = 0; + DBG (4, + "%s: found libusb-1.0 device (0x%04x/0x%04x) interface " + "%d at %s\n", __func__, +@@ -2126,22 +2130,24 @@ sanei_usb_close (SANE_Int dn) + else + #ifdef HAVE_LIBUSB + { +-#if 0 +- /* Should only be done in case of a stall */ +- usb_clear_halt (devices[dn].libusb_handle, devices[dn].bulk_in_ep); +- usb_clear_halt (devices[dn].libusb_handle, devices[dn].bulk_out_ep); +- usb_clear_halt (devices[dn].libusb_handle, devices[dn].iso_in_ep); +- /* be careful, we don't know if we are in DATA0 stage now */ +- usb_resetep (devices[dn].libusb_handle, devices[dn].bulk_in_ep); +- usb_resetep (devices[dn].libusb_handle, devices[dn].bulk_out_ep); +- usb_resetep (devices[dn].libusb_handle, devices[dn].iso_in_ep); +-#endif /* 0 */ ++ /* This call seems to be required by Linux xhci driver ++ * even though it should be a no-op. Without it, the ++ * host or driver does not reset it's data toggle bit. ++ * We intentionally ignore the return val */ ++ sanei_usb_set_altinterface (dn, devices[dn].alt_setting); ++ + usb_release_interface (devices[dn].libusb_handle, + devices[dn].interface_nr); + usb_close (devices[dn].libusb_handle); + } + #elif defined(HAVE_LIBUSB_1_0) + { ++ /* This call seems to be required by Linux xhci driver ++ * even though it should be a no-op. Without it, the ++ * host or driver does not reset it's data toggle bit. ++ * We intentionally ignore the return val */ ++ sanei_usb_set_altinterface (dn, devices[dn].alt_setting); ++ + libusb_release_interface (devices[dn].lu_handle, + devices[dn].interface_nr); + libusb_close (devices[dn].lu_handle); +@@ -2166,7 +2172,6 @@ sanei_usb_set_timeout (SANE_Int timeout) + SANE_Status + sanei_usb_clear_halt (SANE_Int dn) + { +-#ifdef HAVE_LIBUSB + int ret; + + if (dn >= device_number || dn < 0) +@@ -2175,6 +2180,14 @@ sanei_usb_clear_halt (SANE_Int dn) + return SANE_STATUS_INVAL; + } + ++#ifdef HAVE_LIBUSB ++ ++ /* This call seems to be required by Linux xhci driver ++ * even though it should be a no-op. Without it, the ++ * host or driver does not send the clear to the device. ++ * We intentionally ignore the return val */ ++ sanei_usb_set_altinterface (dn, devices[dn].alt_setting); ++ + ret = usb_clear_halt (devices[dn].libusb_handle, devices[dn].bulk_in_ep); + if (ret){ + DBG (1, "sanei_usb_clear_halt: BULK_IN ret=%d\n", ret); +@@ -2187,18 +2200,13 @@ sanei_usb_clear_halt (SANE_Int dn) + return SANE_STATUS_INVAL; + } + +- /* be careful, we don't know if we are in DATA0 stage now +- ret = usb_resetep (devices[dn].libusb_handle, devices[dn].bulk_in_ep); +- ret = usb_resetep (devices[dn].libusb_handle, devices[dn].bulk_out_ep); +- */ + #elif defined(HAVE_LIBUSB_1_0) +- int ret; + +- if (dn >= device_number || dn < 0) +- { +- DBG (1, "sanei_usb_clear_halt: dn >= device number || dn < 0\n"); +- return SANE_STATUS_INVAL; +- } ++ /* This call seems to be required by Linux xhci driver ++ * even though it should be a no-op. Without it, the ++ * host or driver does not send the clear to the device. ++ * We intentionally ignore the return val */ ++ sanei_usb_set_altinterface (dn, devices[dn].alt_setting); + + ret = libusb_clear_halt (devices[dn].lu_handle, devices[dn].bulk_in_ep); + if (ret){ +@@ -3036,6 +3044,8 @@ sanei_usb_set_altinterface (SANE_Int dn, SANE_Int alternate) + + DBG (5, "sanei_usb_set_altinterface: alternate = %d\n", alternate); + ++ devices[dn].alt_setting = alternate; ++ + if (devices[dn].method == sanei_usb_method_scanner_driver) + { + #if defined(__linux__) +-- +2.4.2 + diff --git a/sane-backends.spec b/sane-backends.spec index c1fee3e..1e2b435 100644 --- a/sane-backends.spec +++ b/sane-backends.spec @@ -80,6 +80,8 @@ Patch8: sane-backends-1.0.24-format-security.patch # Update lib/snprintf.c to latest from LPRng to resolve # license issue (#1102520) Patch9: sane-backends-1.0.24-snprintf-cleanroom.patch +# Upstream commit 73cb422f860a84aca7a19114936ead1794d77890 +Patch10: sane-backends-1.0.24-usb3-xhci.patch URL: http://www.sane-project.org @@ -198,6 +200,7 @@ This package contains backend drivers to access digital cameras through SANE. %patch7 -p1 -b .scsi-permissions %patch8 -p1 -b .format-security %patch9 -p1 -b .snprintf-cleanroom +%patch10 -p1 -b .usb3-xhci %build CFLAGS="%optflags -fno-strict-aliasing" @@ -321,6 +324,7 @@ udevadm hwdb --update >/dev/null 2>&1 || : %changelog * Tue Jun 09 2015 Nils Philippsen - reformat and rename snprintf-cleanroom patch +- backport USB3 xhci patch from upstream master (#1228954) * Mon Jun 08 2015 Nils Philippsen - apply format-security patch, drop format-security2 patch