diff -Nru fwupd-0.7.0/debian/changelog fwupd-0.7.0/debian/changelog --- fwupd-0.7.0/debian/changelog 2016-04-28 14:12:29.000000000 +0000 +++ fwupd-0.7.0/debian/changelog 2016-06-09 02:34:05.000000000 +0000 @@ -1,3 +1,9 @@ +fwupd (0.7.0-0ubuntu4.2) xenial-proposed; urgency=medium + + * Fix USB audio devices not working properly (LP: #1574079) + + -- Mario Limonciello Wed, 08 Jun 2016 21:31:00 -0500 + fwupd (0.7.0-0ubuntu4.1) xenial-proposed; urgency=medium * Add name and summary to Rival Steelseries device (LP: #1575248) diff -Nru fwupd-0.7.0/debian/patches/0001-Only-claim-the-DFU-interface-when-required.patch fwupd-0.7.0/debian/patches/0001-Only-claim-the-DFU-interface-when-required.patch --- fwupd-0.7.0/debian/patches/0001-Only-claim-the-DFU-interface-when-required.patch 1970-01-01 00:00:00.000000000 +0000 +++ fwupd-0.7.0/debian/patches/0001-Only-claim-the-DFU-interface-when-required.patch 2016-06-09 02:25:18.000000000 +0000 @@ -0,0 +1,219 @@ +From d0583ae3403b904658b4ac3c10330287ccbae6c9 Mon Sep 17 00:00:00 2001 +From: Richard Hughes +Date: Wed, 8 Jun 2016 16:06:08 +0100 +Subject: [PATCH] Only claim the DFU interface when required + +It appears that some expensive USB sound cards do not like the DFU interface +being claimed at the same time the kernel starts using a different endpoint. + +I suspect this is a device bug or limitation in some reference implementation +somewhere, but seeing as we only need the interface when verifying or writing +new firmware the sensible thing to do is not claim it until required. + +Fixes: https://github.com/hughsie/fwupd/issues/50 +--- + libdfu/dfu-device-private.h | 2 ++ + libdfu/dfu-device.c | 76 ++++++++++++++++++++++++++++++++++++--------- + libdfu/dfu-target.c | 4 +++ + src/fu-provider-dfu.c | 3 +- + 4 files changed, 69 insertions(+), 16 deletions(-) + +Index: fwupd/libdfu/dfu-device-private.h +=================================================================== +--- fwupd.orig/libdfu/dfu-device-private.h ++++ fwupd/libdfu/dfu-device-private.h +@@ -45,6 +45,8 @@ gboolean dfu_device_set_new_usb_dev (D + GUsbDevice *dev, + GCancellable *cancellable, + GError **error); ++gboolean dfu_device_ensure_interface (DfuDevice *device, ++ GError **error); + + G_END_DECLS + +Index: fwupd/libdfu/dfu-device.c +=================================================================== +--- fwupd.orig/libdfu/dfu-device.c ++++ fwupd/libdfu/dfu-device.c +@@ -62,6 +62,7 @@ typedef struct { + gboolean open_new_dev; /* if set new GUsbDevice */ + gboolean dfuse_supported; + gboolean done_upload_or_download; ++ gboolean claimed_interface; + gchar *display_name; + gchar *platform_id; + guint16 runtime_pid; +@@ -903,6 +904,40 @@ dfu_device_set_status (DfuDevice *device + } + + /** ++ * dfu_device_ensure_interface: ++ **/ ++gboolean ++dfu_device_ensure_interface (DfuDevice *device, GError **error) ++{ ++ DfuDevicePrivate *priv = GET_PRIVATE (device); ++ g_autoptr(GError) error_local = NULL; ++ ++ /* already done */ ++ if (priv->claimed_interface) ++ return TRUE; ++ ++ /* nothing set */ ++ if (priv->iface_number == 0xff) ++ return TRUE; ++ ++ /* claim, without detaching kernel driver */ ++ if (!g_usb_device_claim_interface (priv->dev, ++ (gint) priv->iface_number, ++ 0, &error_local)) { ++ g_set_error (error, ++ DFU_ERROR, ++ DFU_ERROR_INVALID_DEVICE, ++ "cannot claim interface %i: %s", ++ priv->iface_number, error_local->message); ++ return FALSE; ++ } ++ ++ /* success */ ++ priv->claimed_interface = TRUE; ++ return TRUE; ++} ++ ++/** + * dfu_device_refresh: + * @device: a #DfuDevice + * @cancellable: a #GCancellable, or %NULL +@@ -944,6 +979,10 @@ dfu_device_refresh (DfuDevice *device, G + return FALSE; + } + ++ /* ensure interface is claimed */ ++ if (!dfu_device_ensure_interface (device, error)) ++ return FALSE; ++ + if (!g_usb_device_control_transfer (priv->dev, + G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST, + G_USB_DEVICE_REQUEST_TYPE_CLASS, +@@ -1039,6 +1078,10 @@ dfu_device_detach (DfuDevice *device, GC + return FALSE; + } + ++ /* ensure interface is claimed */ ++ if (!dfu_device_ensure_interface (device, error)) ++ return FALSE; ++ + /* inform UI there's going to be a detach:attach */ + dfu_device_set_state (device, DFU_STATE_APP_DETACH); + +@@ -1112,6 +1155,10 @@ dfu_device_abort (DfuDevice *device, GCa + return FALSE; + } + ++ /* ensure interface is claimed */ ++ if (!dfu_device_ensure_interface (device, error)) ++ return FALSE; ++ + if (!g_usb_device_control_transfer (priv->dev, + G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, + G_USB_DEVICE_REQUEST_TYPE_CLASS, +@@ -1176,6 +1223,10 @@ dfu_device_clear_status (DfuDevice *devi + return FALSE; + } + ++ /* ensure interface is claimed */ ++ if (!dfu_device_ensure_interface (device, error)) ++ return FALSE; ++ + if (!g_usb_device_control_transfer (priv->dev, + G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, + G_USB_DEVICE_REQUEST_TYPE_CLASS, +@@ -1275,21 +1326,6 @@ dfu_device_open (DfuDevice *device, DfuD + return FALSE; + } + +- /* claim the correct interface if set */ +- if (priv->iface_number != 0xff) { +- if (!g_usb_device_claim_interface (priv->dev, +- (gint) priv->iface_number, +- 0, +- &error_local)) { +- g_set_error (error, +- DFU_ERROR, +- DFU_ERROR_INVALID_DEVICE, +- "cannot claim interface %i: %s", +- priv->iface_number, error_local->message); +- return FALSE; +- } +- } +- + /* get product name if it exists */ + idx = g_usb_device_get_product_index (priv->dev); + if (idx != 0x00) +@@ -1369,6 +1405,7 @@ dfu_device_close (DfuDevice *device, GEr + error_local->message); + return FALSE; + } ++ priv->claimed_interface = FALSE; + priv->open_new_dev = FALSE; + return TRUE; + } +@@ -1393,6 +1430,7 @@ dfu_device_set_new_usb_dev (DfuDevice *d + g_debug ("invalidating backing GUsbDevice"); + g_clear_object (&priv->dev); + g_ptr_array_set_size (priv->targets, 0); ++ priv->claimed_interface = FALSE; + return TRUE; + } + +@@ -1687,6 +1725,10 @@ dfu_device_upload (DfuDevice *device, + return NULL; + } + ++ /* ensure interface is claimed */ ++ if (!dfu_device_ensure_interface (device, error)) ++ return FALSE; ++ + /* create ahead of time */ + firmware = dfu_firmware_new (); + dfu_firmware_set_vid (firmware, priv->runtime_vid); +@@ -1804,6 +1846,10 @@ dfu_device_download (DfuDevice *device, + return FALSE; + } + ++ /* ensure interface is claimed */ ++ if (!dfu_device_ensure_interface (device, error)) ++ return FALSE; ++ + /* do we allow wildcard VID:PID matches */ + if ((flags & DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID) == 0) { + if (dfu_firmware_get_vid (firmware) == 0xffff) { +Index: fwupd/libdfu/dfu-target.c +=================================================================== +--- fwupd.orig/libdfu/dfu-target.c ++++ fwupd/libdfu/dfu-target.c +@@ -565,6 +565,10 @@ dfu_target_use_alt_setting (DfuTarget *t + g_return_val_if_fail (DFU_IS_TARGET (target), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + ++ /* ensure interface is claimed */ ++ if (!dfu_device_ensure_interface (priv->device, error)) ++ return FALSE; ++ + /* use the correct setting */ + dev = dfu_device_get_usb_dev (priv->device); + if (dfu_device_get_mode (priv->device) == DFU_MODE_DFU) { +Index: fwupd/src/fu-provider-dfu.c +=================================================================== +--- fwupd.orig/src/fu-provider-dfu.c ++++ fwupd/src/fu-provider-dfu.c +@@ -152,7 +152,8 @@ fu_provider_dfu_device_added_cb (DfuCont + fu_provider_dfu_device_update (provider_dfu, dev, device); + + /* open device to get display name */ +- if (!dfu_device_open (device, DFU_DEVICE_OPEN_FLAG_NONE, NULL, &error)) { ++ if (!dfu_device_open (device, DFU_DEVICE_OPEN_FLAG_NO_AUTO_REFRESH, ++ NULL, &error)) { + g_warning ("Failed to open DFU device: %s", error->message); + return; + } diff -Nru fwupd-0.7.0/debian/patches/0001-trivial-Prevent-critical-warning-when-verifying.patch fwupd-0.7.0/debian/patches/0001-trivial-Prevent-critical-warning-when-verifying.patch --- fwupd-0.7.0/debian/patches/0001-trivial-Prevent-critical-warning-when-verifying.patch 1970-01-01 00:00:00.000000000 +0000 +++ fwupd-0.7.0/debian/patches/0001-trivial-Prevent-critical-warning-when-verifying.patch 2016-06-09 02:25:28.000000000 +0000 @@ -0,0 +1,22 @@ +From 4580ed128b709faa5ad9a2b1b53f7b16651f2a75 Mon Sep 17 00:00:00 2001 +From: Richard Hughes +Date: Thu, 2 Jun 2016 08:50:59 +0100 +Subject: [PATCH 1/2] trivial: Prevent critical warning when verifying + +--- + src/fu-provider-dfu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: fwupd/src/fu-provider-dfu.c +=================================================================== +--- fwupd.orig/src/fu-provider-dfu.c ++++ fwupd/src/fu-provider-dfu.c +@@ -371,7 +371,7 @@ fu_provider_dfu_verify (FuProvider *prov + checksum_type = fu_provider_get_checksum_type (flags); + hash = g_compute_checksum_for_bytes (checksum_type, blob_fw); + fu_device_set_checksum (dev, hash); +- fu_device_set_checksum_kind (device, checksum_type); ++ fu_device_set_checksum_kind (dev, checksum_type); + fu_provider_set_status (provider, FWUPD_STATUS_IDLE); + return TRUE; + } diff -Nru fwupd-0.7.0/debian/patches/series fwupd-0.7.0/debian/patches/series --- fwupd-0.7.0/debian/patches/series 2016-04-28 14:10:44.000000000 +0000 +++ fwupd-0.7.0/debian/patches/series 2016-06-09 02:23:09.000000000 +0000 @@ -2,3 +2,5 @@ endian_fix.patch 0001-Set-the-system-s-DMI-product-name-as-the-DisplayName.patch 0001-Add-summary-and-name-field-for-Rival-SteelSeries.patch +0001-trivial-Prevent-critical-warning-when-verifying.patch +0001-Only-claim-the-DFU-interface-when-required.patch