From mboxrd@z Thu Jan 1 00:00:00 1970 From: Greg Kroah-Hartman Subject: [PATCH] sound: USB: line6: use dynamic buffers Date: Sun, 28 Apr 2019 18:04:11 +0200 Message-ID: <20190428160411.GA12815@kroah.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org To: Jaroslav Kysela , Takashi Iwai Cc: Arnd Bergmann , alsa-devel@alsa-project.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org List-Id: alsa-devel@alsa-project.org The line6 driver uses a lot of USB buffers off of the stack, which is not allowed on many systems, causing the driver to crash on some of them. Fix this up by dynamically allocating the buffers with kmalloc() which allows for proper DMA-able memory. Reported-by: Christo Gouws Reported-by: Alan Stern Tested-by: Christo Gouws Cc: stable Signed-off-by: Greg Kroah-Hartman --- sound/usb/line6/driver.c | 60 ++++++++++++++++++++++++++------------------- sound/usb/line6/podhd.c | 21 +++++++++------ sound/usb/line6/toneport.c | 23 ++++++++++++----- 3 files changed, 64 insertions(+), 40 deletions(-) --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -351,12 +351,16 @@ int line6_read_data(struct usb_line6 *li { struct usb_device *usbdev = line6->usbdev; int ret; - unsigned char len; + unsigned char *len; unsigned count; if (address > 0xffff || datalen > 0xff) return -EINVAL; + len = kmalloc(sizeof(*len), GFP_KERNEL); + if (!len) + return -ENOMEM; + /* query the serial number: */ ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, @@ -365,7 +369,7 @@ int line6_read_data(struct usb_line6 *li if (ret < 0) { dev_err(line6->ifcdev, "read request failed (error %d)\n", ret); - return ret; + goto exit; } /* Wait for data length. We'll get 0xff until length arrives. */ @@ -375,28 +379,29 @@ int line6_read_data(struct usb_line6 *li ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x0012, 0x0000, &len, 1, + 0x0012, 0x0000, len, 1, LINE6_TIMEOUT * HZ); if (ret < 0) { dev_err(line6->ifcdev, "receive length failed (error %d)\n", ret); - return ret; + goto exit; } - if (len != 0xff) + if (*len != 0xff) break; } - if (len == 0xff) { + ret = -EIO; + if (*len == 0xff) { dev_err(line6->ifcdev, "read failed after %d retries\n", count); - return -EIO; - } else if (len != datalen) { + goto exit; + } else if (*len != datalen) { /* should be equal or something went wrong */ dev_err(line6->ifcdev, "length mismatch (expected %d, got %d)\n", - (int)datalen, (int)len); - return -EIO; + (int)datalen, (int)*len); + goto exit; } /* receive the result: */ @@ -405,12 +410,12 @@ int line6_read_data(struct usb_line6 *li 0x0013, 0x0000, data, datalen, LINE6_TIMEOUT * HZ); - if (ret < 0) { + if (ret < 0) dev_err(line6->ifcdev, "read failed (error %d)\n", ret); - return ret; - } - return 0; +exit: + kfree(len); + return ret; } EXPORT_SYMBOL_GPL(line6_read_data); @@ -422,12 +427,16 @@ int line6_write_data(struct usb_line6 *l { struct usb_device *usbdev = line6->usbdev; int ret; - unsigned char status; + unsigned char *status; int count; if (address > 0xffff || datalen > 0xffff) return -EINVAL; + status = kmalloc(sizeof(*status), GFP_KERNEL); + if (!status) + return -ENOMEM; + ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 0x0022, address, data, datalen, @@ -436,7 +445,7 @@ int line6_write_data(struct usb_line6 *l if (ret < 0) { dev_err(line6->ifcdev, "write request failed (error %d)\n", ret); - return ret; + goto exit; } for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) { @@ -447,28 +456,29 @@ int line6_write_data(struct usb_line6 *l USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x0012, 0x0000, - &status, 1, LINE6_TIMEOUT * HZ); + status, 1, LINE6_TIMEOUT * HZ); if (ret < 0) { dev_err(line6->ifcdev, "receiving status failed (error %d)\n", ret); - return ret; + goto exit; } - if (status != 0xff) + if (*status != 0xff) break; } - if (status == 0xff) { + if (*status == 0xff) { dev_err(line6->ifcdev, "write failed after %d retries\n", count); - return -EIO; - } else if (status != 0) { + ret = -EIO; + } else if (*status != 0) { dev_err(line6->ifcdev, "write failed (error %d)\n", ret); - return -EIO; + ret = -EIO; } - - return 0; +exit: + kfree(status); + return ret; } EXPORT_SYMBOL_GPL(line6_write_data); --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -225,28 +225,32 @@ static void podhd_startup_start_workqueu static int podhd_dev_start(struct usb_line6_podhd *pod) { int ret; - u8 init_bytes[8]; + u8 *init_bytes; int i; struct usb_device *usbdev = pod->line6.usbdev; + init_bytes = kmalloc(8, GFP_KERNEL); + if (!init_bytes) + return -ENOMEM; + ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 0x11, 0, NULL, 0, LINE6_TIMEOUT * HZ); if (ret < 0) { dev_err(pod->line6.ifcdev, "read request failed (error %d)\n", ret); - return ret; + goto exit; } /* NOTE: looks like some kind of ping message */ ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x11, 0x0, - &init_bytes, 3, LINE6_TIMEOUT * HZ); + init_bytes, 3, LINE6_TIMEOUT * HZ); if (ret < 0) { dev_err(pod->line6.ifcdev, "receive length failed (error %d)\n", ret); - return ret; + goto exit; } pod->firmware_version = @@ -255,7 +259,7 @@ static int podhd_dev_start(struct usb_li for (i = 0; i <= 16; i++) { ret = line6_read_data(&pod->line6, 0xf000 + 0x08 * i, init_bytes, 8); if (ret < 0) - return ret; + goto exit; } ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), @@ -263,10 +267,9 @@ static int podhd_dev_start(struct usb_li USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_DIR_OUT, 1, 0, NULL, 0, LINE6_TIMEOUT * HZ); - if (ret < 0) - return ret; - - return 0; +exit: + kfree(init_bytes); + return ret; } static void podhd_startup_workqueue(struct work_struct *work) --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -365,16 +365,21 @@ static bool toneport_has_source_select(s /* Setup Toneport device. */ -static void toneport_setup(struct usb_line6_toneport *toneport) +static int toneport_setup(struct usb_line6_toneport *toneport) { - u32 ticks; + u32 *ticks; struct usb_line6 *line6 = &toneport->line6; struct usb_device *usbdev = line6->usbdev; + ticks = kmalloc(sizeof(*ticks), GFP_KERNEL); + if (!ticks) + return -ENOMEM; + /* sync time on device with host: */ /* note: 32-bit timestamps overflow in year 2106 */ - ticks = (u32)ktime_get_real_seconds(); - line6_write_data(line6, 0x80c6, &ticks, 4); + *ticks = (u32)ktime_get_real_seconds(); + line6_write_data(line6, 0x80c6, ticks, 4); + kfree(ticks); /* enable device: */ toneport_send_cmd(usbdev, 0x0301, 0x0000); @@ -451,7 +456,9 @@ static int toneport_init(struct usb_line return err; } - toneport_setup(toneport); + err = toneport_setup(toneport); + if (err) + return err; /* register audio system: */ return snd_card_register(line6->card); @@ -463,7 +470,11 @@ static int toneport_init(struct usb_line */ static int toneport_reset_resume(struct usb_interface *interface) { - toneport_setup(usb_get_intfdata(interface)); + int err; + + err = toneport_setup(usb_get_intfdata(interface)); + if (err) + return err; return line6_resume(interface); } #endif From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: sound: USB: line6: use dynamic buffers From: Greg Kroah-Hartman Message-Id: <20190428160411.GA12815@kroah.com> Date: Sun, 28 Apr 2019 18:04:11 +0200 To: Jaroslav Kysela , Takashi Iwai Cc: Arnd Bergmann , alsa-devel@alsa-project.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org List-ID: VGhlIGxpbmU2IGRyaXZlciB1c2VzIGEgbG90IG9mIFVTQiBidWZmZXJzIG9mZiBvZiB0aGUgc3Rh Y2ssIHdoaWNoIGlzCm5vdCBhbGxvd2VkIG9uIG1hbnkgc3lzdGVtcywgY2F1c2luZyB0aGUgZHJp dmVyIHRvIGNyYXNoIG9uIHNvbWUgb2YKdGhlbS4gIEZpeCB0aGlzIHVwIGJ5IGR5bmFtaWNhbGx5 IGFsbG9jYXRpbmcgdGhlIGJ1ZmZlcnMgd2l0aCBrbWFsbG9jKCkKd2hpY2ggYWxsb3dzIGZvciBw cm9wZXIgRE1BLWFibGUgbWVtb3J5LgoKUmVwb3J0ZWQtYnk6IENocmlzdG8gR291d3MgPGdvdXdz LmNocmlzdG9AZ21haWwuY29tPgpSZXBvcnRlZC1ieTogQWxhbiBTdGVybiA8c3Rlcm5Acm93bGFu ZC5oYXJ2YXJkLmVkdT4KVGVzdGVkLWJ5OiBDaHJpc3RvIEdvdXdzIDxnb3V3cy5jaHJpc3RvQGdt YWlsLmNvbT4KQ2M6IHN0YWJsZSA8c3RhYmxlQHZnZXIua2VybmVsLm9yZz4KU2lnbmVkLW9mZi1i eTogR3JlZyBLcm9haC1IYXJ0bWFuIDxncmVna2hAbGludXhmb3VuZGF0aW9uLm9yZz4KLS0tCiBz b3VuZC91c2IvbGluZTYvZHJpdmVyLmMgICB8ICAgNjAgKysrKysrKysrKysrKysrKysrKysrKysr KystLS0tLS0tLS0tLS0tLS0tLS0tCiBzb3VuZC91c2IvbGluZTYvcG9kaGQuYyAgICB8ICAgMjEg KysrKysrKysrLS0tLS0tCiBzb3VuZC91c2IvbGluZTYvdG9uZXBvcnQuYyB8ICAgMjMgKysrKysr KysrKysrLS0tLS0KIDMgZmlsZXMgY2hhbmdlZCwgNjQgaW5zZXJ0aW9ucygrKSwgNDAgZGVsZXRp b25zKC0pCgotLS0gYS9zb3VuZC91c2IvbGluZTYvZHJpdmVyLmMKKysrIGIvc291bmQvdXNiL2xp bmU2L2RyaXZlci5jCkBAIC0zNTEsMTIgKzM1MSwxNiBAQCBpbnQgbGluZTZfcmVhZF9kYXRhKHN0 cnVjdCB1c2JfbGluZTYgKmxpCiB7CiAJc3RydWN0IHVzYl9kZXZpY2UgKnVzYmRldiA9IGxpbmU2 LT51c2JkZXY7CiAJaW50IHJldDsKLQl1bnNpZ25lZCBjaGFyIGxlbjsKKwl1bnNpZ25lZCBjaGFy ICpsZW47CiAJdW5zaWduZWQgY291bnQ7CiAKIAlpZiAoYWRkcmVzcyA+IDB4ZmZmZiB8fCBkYXRh bGVuID4gMHhmZikKIAkJcmV0dXJuIC1FSU5WQUw7CiAKKwlsZW4gPSBrbWFsbG9jKHNpemVvZigq bGVuKSwgR0ZQX0tFUk5FTCk7CisJaWYgKCFsZW4pCisJCXJldHVybiAtRU5PTUVNOworCiAJLyog cXVlcnkgdGhlIHNlcmlhbCBudW1iZXI6ICovCiAJcmV0ID0gdXNiX2NvbnRyb2xfbXNnKHVzYmRl diwgdXNiX3NuZGN0cmxwaXBlKHVzYmRldiwgMCksIDB4NjcsCiAJCQkgICAgICBVU0JfVFlQRV9W RU5ET1IgfCBVU0JfUkVDSVBfREVWSUNFIHwgVVNCX0RJUl9PVVQsCkBAIC0zNjUsNyArMzY5LDcg QEAgaW50IGxpbmU2X3JlYWRfZGF0YShzdHJ1Y3QgdXNiX2xpbmU2ICpsaQogCiAJaWYgKHJldCA8 IDApIHsKIAkJZGV2X2VycihsaW5lNi0+aWZjZGV2LCAicmVhZCByZXF1ZXN0IGZhaWxlZCAoZXJy b3IgJWQpXG4iLCByZXQpOwotCQlyZXR1cm4gcmV0OworCQlnb3RvIGV4aXQ7CiAJfQogCiAJLyog V2FpdCBmb3IgZGF0YSBsZW5ndGguIFdlJ2xsIGdldCAweGZmIHVudGlsIGxlbmd0aCBhcnJpdmVz LiAqLwpAQCAtMzc1LDI4ICszNzksMjkgQEAgaW50IGxpbmU2X3JlYWRfZGF0YShzdHJ1Y3QgdXNi X2xpbmU2ICpsaQogCQlyZXQgPSB1c2JfY29udHJvbF9tc2codXNiZGV2LCB1c2JfcmN2Y3RybHBp cGUodXNiZGV2LCAwKSwgMHg2NywKIAkJCQkgICAgICBVU0JfVFlQRV9WRU5ET1IgfCBVU0JfUkVD SVBfREVWSUNFIHwKIAkJCQkgICAgICBVU0JfRElSX0lOLAotCQkJCSAgICAgIDB4MDAxMiwgMHgw MDAwLCAmbGVuLCAxLAorCQkJCSAgICAgIDB4MDAxMiwgMHgwMDAwLCBsZW4sIDEsCiAJCQkJICAg ICAgTElORTZfVElNRU9VVCAqIEhaKTsKIAkJaWYgKHJldCA8IDApIHsKIAkJCWRldl9lcnIobGlu ZTYtPmlmY2RldiwKIAkJCQkicmVjZWl2ZSBsZW5ndGggZmFpbGVkIChlcnJvciAlZClcbiIsIHJl dCk7Ci0JCQlyZXR1cm4gcmV0OworCQkJZ290byBleGl0OwogCQl9CiAKLQkJaWYgKGxlbiAhPSAw eGZmKQorCQlpZiAoKmxlbiAhPSAweGZmKQogCQkJYnJlYWs7CiAJfQogCi0JaWYgKGxlbiA9PSAw eGZmKSB7CisJcmV0ID0gLUVJTzsKKwlpZiAoKmxlbiA9PSAweGZmKSB7CiAJCWRldl9lcnIobGlu ZTYtPmlmY2RldiwgInJlYWQgZmFpbGVkIGFmdGVyICVkIHJldHJpZXNcbiIsCiAJCQljb3VudCk7 Ci0JCXJldHVybiAtRUlPOwotCX0gZWxzZSBpZiAobGVuICE9IGRhdGFsZW4pIHsKKwkJZ290byBl eGl0OworCX0gZWxzZSBpZiAoKmxlbiAhPSBkYXRhbGVuKSB7CiAJCS8qIHNob3VsZCBiZSBlcXVh bCBvciBzb21ldGhpbmcgd2VudCB3cm9uZyAqLwogCQlkZXZfZXJyKGxpbmU2LT5pZmNkZXYsCiAJ CQkibGVuZ3RoIG1pc21hdGNoIChleHBlY3RlZCAlZCwgZ290ICVkKVxuIiwKLQkJCShpbnQpZGF0 YWxlbiwgKGludClsZW4pOwotCQlyZXR1cm4gLUVJTzsKKwkJCShpbnQpZGF0YWxlbiwgKGludCkq bGVuKTsKKwkJZ290byBleGl0OwogCX0KIAogCS8qIHJlY2VpdmUgdGhlIHJlc3VsdDogKi8KQEAg LTQwNSwxMiArNDEwLDEyIEBAIGludCBsaW5lNl9yZWFkX2RhdGEoc3RydWN0IHVzYl9saW5lNiAq bGkKIAkJCSAgICAgIDB4MDAxMywgMHgwMDAwLCBkYXRhLCBkYXRhbGVuLAogCQkJICAgICAgTElO RTZfVElNRU9VVCAqIEhaKTsKIAotCWlmIChyZXQgPCAwKSB7CisJaWYgKHJldCA8IDApCiAJCWRl dl9lcnIobGluZTYtPmlmY2RldiwgInJlYWQgZmFpbGVkIChlcnJvciAlZClcbiIsIHJldCk7Ci0J CXJldHVybiByZXQ7Ci0JfQogCi0JcmV0dXJuIDA7CitleGl0OgorCWtmcmVlKGxlbik7CisJcmV0 dXJuIHJldDsKIH0KIEVYUE9SVF9TWU1CT0xfR1BMKGxpbmU2X3JlYWRfZGF0YSk7CiAKQEAgLTQy MiwxMiArNDI3LDE2IEBAIGludCBsaW5lNl93cml0ZV9kYXRhKHN0cnVjdCB1c2JfbGluZTYgKmwK IHsKIAlzdHJ1Y3QgdXNiX2RldmljZSAqdXNiZGV2ID0gbGluZTYtPnVzYmRldjsKIAlpbnQgcmV0 OwotCXVuc2lnbmVkIGNoYXIgc3RhdHVzOworCXVuc2lnbmVkIGNoYXIgKnN0YXR1czsKIAlpbnQg Y291bnQ7CiAKIAlpZiAoYWRkcmVzcyA+IDB4ZmZmZiB8fCBkYXRhbGVuID4gMHhmZmZmKQogCQly ZXR1cm4gLUVJTlZBTDsKIAorCXN0YXR1cyA9IGttYWxsb2Moc2l6ZW9mKCpzdGF0dXMpLCBHRlBf S0VSTkVMKTsKKwlpZiAoIXN0YXR1cykKKwkJcmV0dXJuIC1FTk9NRU07CisKIAlyZXQgPSB1c2Jf Y29udHJvbF9tc2codXNiZGV2LCB1c2Jfc25kY3RybHBpcGUodXNiZGV2LCAwKSwgMHg2NywKIAkJ CSAgICAgIFVTQl9UWVBFX1ZFTkRPUiB8IFVTQl9SRUNJUF9ERVZJQ0UgfCBVU0JfRElSX09VVCwK IAkJCSAgICAgIDB4MDAyMiwgYWRkcmVzcywgZGF0YSwgZGF0YWxlbiwKQEAgLTQzNiw3ICs0NDUs NyBAQCBpbnQgbGluZTZfd3JpdGVfZGF0YShzdHJ1Y3QgdXNiX2xpbmU2ICpsCiAJaWYgKHJldCA8 IDApIHsKIAkJZGV2X2VycihsaW5lNi0+aWZjZGV2LAogCQkJIndyaXRlIHJlcXVlc3QgZmFpbGVk IChlcnJvciAlZClcbiIsIHJldCk7Ci0JCXJldHVybiByZXQ7CisJCWdvdG8gZXhpdDsKIAl9CiAK IAlmb3IgKGNvdW50ID0gMDsgY291bnQgPCBMSU5FNl9SRUFEX1dSSVRFX01BWF9SRVRSSUVTOyBj b3VudCsrKSB7CkBAIC00NDcsMjggKzQ1NiwyOSBAQCBpbnQgbGluZTZfd3JpdGVfZGF0YShzdHJ1 Y3QgdXNiX2xpbmU2ICpsCiAJCQkJICAgICAgVVNCX1RZUEVfVkVORE9SIHwgVVNCX1JFQ0lQX0RF VklDRSB8CiAJCQkJICAgICAgVVNCX0RJUl9JTiwKIAkJCQkgICAgICAweDAwMTIsIDB4MDAwMCwK LQkJCQkgICAgICAmc3RhdHVzLCAxLCBMSU5FNl9USU1FT1VUICogSFopOworCQkJCSAgICAgIHN0 YXR1cywgMSwgTElORTZfVElNRU9VVCAqIEhaKTsKIAogCQlpZiAocmV0IDwgMCkgewogCQkJZGV2 X2VycihsaW5lNi0+aWZjZGV2LAogCQkJCSJyZWNlaXZpbmcgc3RhdHVzIGZhaWxlZCAoZXJyb3Ig JWQpXG4iLCByZXQpOwotCQkJcmV0dXJuIHJldDsKKwkJCWdvdG8gZXhpdDsKIAkJfQogCi0JCWlm IChzdGF0dXMgIT0gMHhmZikKKwkJaWYgKCpzdGF0dXMgIT0gMHhmZikKIAkJCWJyZWFrOwogCX0K IAotCWlmIChzdGF0dXMgPT0gMHhmZikgeworCWlmICgqc3RhdHVzID09IDB4ZmYpIHsKIAkJZGV2 X2VycihsaW5lNi0+aWZjZGV2LCAid3JpdGUgZmFpbGVkIGFmdGVyICVkIHJldHJpZXNcbiIsCiAJ CQljb3VudCk7Ci0JCXJldHVybiAtRUlPOwotCX0gZWxzZSBpZiAoc3RhdHVzICE9IDApIHsKKwkJ cmV0ID0gLUVJTzsKKwl9IGVsc2UgaWYgKCpzdGF0dXMgIT0gMCkgewogCQlkZXZfZXJyKGxpbmU2 LT5pZmNkZXYsICJ3cml0ZSBmYWlsZWQgKGVycm9yICVkKVxuIiwgcmV0KTsKLQkJcmV0dXJuIC1F SU87CisJCXJldCA9IC1FSU87CiAJfQotCi0JcmV0dXJuIDA7CitleGl0OgorCWtmcmVlKHN0YXR1 cyk7CisJcmV0dXJuIHJldDsKIH0KIEVYUE9SVF9TWU1CT0xfR1BMKGxpbmU2X3dyaXRlX2RhdGEp OwogCi0tLSBhL3NvdW5kL3VzYi9saW5lNi9wb2RoZC5jCisrKyBiL3NvdW5kL3VzYi9saW5lNi9w b2RoZC5jCkBAIC0yMjUsMjggKzIyNSwzMiBAQCBzdGF0aWMgdm9pZCBwb2RoZF9zdGFydHVwX3N0 YXJ0X3dvcmtxdWV1CiBzdGF0aWMgaW50IHBvZGhkX2Rldl9zdGFydChzdHJ1Y3QgdXNiX2xpbmU2 X3BvZGhkICpwb2QpCiB7CiAJaW50IHJldDsKLQl1OCBpbml0X2J5dGVzWzhdOworCXU4ICppbml0 X2J5dGVzOwogCWludCBpOwogCXN0cnVjdCB1c2JfZGV2aWNlICp1c2JkZXYgPSBwb2QtPmxpbmU2 LnVzYmRldjsKIAorCWluaXRfYnl0ZXMgPSBrbWFsbG9jKDgsIEdGUF9LRVJORUwpOworCWlmICgh aW5pdF9ieXRlcykKKwkJcmV0dXJuIC1FTk9NRU07CisKIAlyZXQgPSB1c2JfY29udHJvbF9tc2co dXNiZGV2LCB1c2Jfc25kY3RybHBpcGUodXNiZGV2LCAwKSwKIAkJCQkJMHg2NywgVVNCX1RZUEVf VkVORE9SIHwgVVNCX1JFQ0lQX0RFVklDRSB8IFVTQl9ESVJfT1VULAogCQkJCQkweDExLCAwLAog CQkJCQlOVUxMLCAwLCBMSU5FNl9USU1FT1VUICogSFopOwogCWlmIChyZXQgPCAwKSB7CiAJCWRl dl9lcnIocG9kLT5saW5lNi5pZmNkZXYsICJyZWFkIHJlcXVlc3QgZmFpbGVkIChlcnJvciAlZClc biIsIHJldCk7Ci0JCXJldHVybiByZXQ7CisJCWdvdG8gZXhpdDsKIAl9CiAKIAkvKiBOT1RFOiBs b29rcyBsaWtlIHNvbWUga2luZCBvZiBwaW5nIG1lc3NhZ2UgKi8KIAlyZXQgPSB1c2JfY29udHJv bF9tc2codXNiZGV2LCB1c2JfcmN2Y3RybHBpcGUodXNiZGV2LCAwKSwgMHg2NywKIAkJCQkJVVNC X1RZUEVfVkVORE9SIHwgVVNCX1JFQ0lQX0RFVklDRSB8IFVTQl9ESVJfSU4sCiAJCQkJCTB4MTEs IDB4MCwKLQkJCQkJJmluaXRfYnl0ZXMsIDMsIExJTkU2X1RJTUVPVVQgKiBIWik7CisJCQkJCWlu aXRfYnl0ZXMsIDMsIExJTkU2X1RJTUVPVVQgKiBIWik7CiAJaWYgKHJldCA8IDApIHsKIAkJZGV2 X2Vycihwb2QtPmxpbmU2LmlmY2RldiwKIAkJCSJyZWNlaXZlIGxlbmd0aCBmYWlsZWQgKGVycm9y ICVkKVxuIiwgcmV0KTsKLQkJcmV0dXJuIHJldDsKKwkJZ290byBleGl0OwogCX0KIAogCXBvZC0+ ZmlybXdhcmVfdmVyc2lvbiA9CkBAIC0yNTUsNyArMjU5LDcgQEAgc3RhdGljIGludCBwb2RoZF9k ZXZfc3RhcnQoc3RydWN0IHVzYl9saQogCWZvciAoaSA9IDA7IGkgPD0gMTY7IGkrKykgewogCQly ZXQgPSBsaW5lNl9yZWFkX2RhdGEoJnBvZC0+bGluZTYsIDB4ZjAwMCArIDB4MDggKiBpLCBpbml0 X2J5dGVzLCA4KTsKIAkJaWYgKHJldCA8IDApCi0JCQlyZXR1cm4gcmV0OworCQkJZ290byBleGl0 OwogCX0KIAogCXJldCA9IHVzYl9jb250cm9sX21zZyh1c2JkZXYsIHVzYl9zbmRjdHJscGlwZSh1 c2JkZXYsIDApLApAQCAtMjYzLDEwICsyNjcsOSBAQCBzdGF0aWMgaW50IHBvZGhkX2Rldl9zdGFy dChzdHJ1Y3QgdXNiX2xpCiAJCQkJCVVTQl9UWVBFX1NUQU5EQVJEIHwgVVNCX1JFQ0lQX0RFVklD RSB8IFVTQl9ESVJfT1VULAogCQkJCQkxLCAwLAogCQkJCQlOVUxMLCAwLCBMSU5FNl9USU1FT1VU ICogSFopOwotCWlmIChyZXQgPCAwKQotCQlyZXR1cm4gcmV0OwotCi0JcmV0dXJuIDA7CitleGl0 OgorCWtmcmVlKGluaXRfYnl0ZXMpOworCXJldHVybiByZXQ7CiB9CiAKIHN0YXRpYyB2b2lkIHBv ZGhkX3N0YXJ0dXBfd29ya3F1ZXVlKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKLS0tIGEvc291 bmQvdXNiL2xpbmU2L3RvbmVwb3J0LmMKKysrIGIvc291bmQvdXNiL2xpbmU2L3RvbmVwb3J0LmMK QEAgLTM2NSwxNiArMzY1LDIxIEBAIHN0YXRpYyBib29sIHRvbmVwb3J0X2hhc19zb3VyY2Vfc2Vs ZWN0KHMKIC8qCiAJU2V0dXAgVG9uZXBvcnQgZGV2aWNlLgogKi8KLXN0YXRpYyB2b2lkIHRvbmVw b3J0X3NldHVwKHN0cnVjdCB1c2JfbGluZTZfdG9uZXBvcnQgKnRvbmVwb3J0KQorc3RhdGljIGlu dCB0b25lcG9ydF9zZXR1cChzdHJ1Y3QgdXNiX2xpbmU2X3RvbmVwb3J0ICp0b25lcG9ydCkKIHsK LQl1MzIgdGlja3M7CisJdTMyICp0aWNrczsKIAlzdHJ1Y3QgdXNiX2xpbmU2ICpsaW5lNiA9ICZ0 b25lcG9ydC0+bGluZTY7CiAJc3RydWN0IHVzYl9kZXZpY2UgKnVzYmRldiA9IGxpbmU2LT51c2Jk ZXY7CiAKKwl0aWNrcyA9IGttYWxsb2Moc2l6ZW9mKCp0aWNrcyksIEdGUF9LRVJORUwpOworCWlm ICghdGlja3MpCisJCXJldHVybiAtRU5PTUVNOworCiAJLyogc3luYyB0aW1lIG9uIGRldmljZSB3 aXRoIGhvc3Q6ICovCiAJLyogbm90ZTogMzItYml0IHRpbWVzdGFtcHMgb3ZlcmZsb3cgaW4geWVh ciAyMTA2ICovCi0JdGlja3MgPSAodTMyKWt0aW1lX2dldF9yZWFsX3NlY29uZHMoKTsKLQlsaW5l Nl93cml0ZV9kYXRhKGxpbmU2LCAweDgwYzYsICZ0aWNrcywgNCk7CisJKnRpY2tzID0gKHUzMilr dGltZV9nZXRfcmVhbF9zZWNvbmRzKCk7CisJbGluZTZfd3JpdGVfZGF0YShsaW5lNiwgMHg4MGM2 LCB0aWNrcywgNCk7CisJa2ZyZWUodGlja3MpOwogCiAJLyogZW5hYmxlIGRldmljZTogKi8KIAl0 b25lcG9ydF9zZW5kX2NtZCh1c2JkZXYsIDB4MDMwMSwgMHgwMDAwKTsKQEAgLTQ1MSw3ICs0NTYs OSBAQCBzdGF0aWMgaW50IHRvbmVwb3J0X2luaXQoc3RydWN0IHVzYl9saW5lCiAJCQlyZXR1cm4g ZXJyOwogCX0KIAotCXRvbmVwb3J0X3NldHVwKHRvbmVwb3J0KTsKKwllcnIgPSB0b25lcG9ydF9z ZXR1cCh0b25lcG9ydCk7CisJaWYgKGVycikKKwkJcmV0dXJuIGVycjsKIAogCS8qIHJlZ2lzdGVy IGF1ZGlvIHN5c3RlbTogKi8KIAlyZXR1cm4gc25kX2NhcmRfcmVnaXN0ZXIobGluZTYtPmNhcmQp OwpAQCAtNDYzLDcgKzQ3MCwxMSBAQCBzdGF0aWMgaW50IHRvbmVwb3J0X2luaXQoc3RydWN0IHVz Yl9saW5lCiAqLwogc3RhdGljIGludCB0b25lcG9ydF9yZXNldF9yZXN1bWUoc3RydWN0IHVzYl9p bnRlcmZhY2UgKmludGVyZmFjZSkKIHsKLQl0b25lcG9ydF9zZXR1cCh1c2JfZ2V0X2ludGZkYXRh KGludGVyZmFjZSkpOworCWludCBlcnI7CisKKwllcnIgPSB0b25lcG9ydF9zZXR1cCh1c2JfZ2V0 X2ludGZkYXRhKGludGVyZmFjZSkpOworCWlmIChlcnIpCisJCXJldHVybiBlcnI7CiAJcmV0dXJu IGxpbmU2X3Jlc3VtZShpbnRlcmZhY2UpOwogfQogI2VuZGlmCg==