From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752748Ab3HUKV3 (ORCPT ); Wed, 21 Aug 2013 06:21:29 -0400 Received: from m50-132.163.com ([123.125.50.132]:47300 "EHLO m50-132.163.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752516Ab3HUKV0 (ORCPT ); Wed, 21 Aug 2013 06:21:26 -0400 Date: Wed, 21 Aug 2013 18:06:02 +0800 From: "liujunliang_ljl" To: "Francois Romieu" Cc: "gregkh" , "sunhecheng" , "linux-usb" , "netdev" , "linux-kernel" References: <201308201841116403992@163.com>, <20130820204606.GB26241@electric-eye.fr.zoreil.com> Subject: Re: Re: [PATCH-SR9700] Merge USB 1.1 Ethernet Adapter SR9700 DeviceDriver into the Linux Kernel Message-ID: <201308211805574844059@163.com> X-mailer: Foxmail 6, 15, 201, 22 [cn] Mime-Version: 1.0 Content-Type: text/plain; charset="gb2312" X-CM-TRANSID: DNGowEDpaHL8kBRS0WQeAQ--.683S2 X-Coremail-Antispam: 1Uf129KBjvAXoWfAr17ZFyxKr45trWDtry7KFg_yoW5XFW7Ao Z3XFsxAw18JryxAr95W3s7X398XFyDKw43Ar43XrWDXFy3XF1DKrW3W398C345XayS9rn5 Zw18ta93AFZYvrWrn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjxUISfODUUUU X-CM-SenderInfo: xolxy3pqolt0hjboyzi6rwjhhfrp/1tbiLx6AX1EAGSGGHwAAse Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by mail.home.local id r7LALXek022001 Dear Francois Romieu : 1, all the format problems have been fixed 2, sr9700.h registers definition is re-written 3, Thanks for your detail checking and I have beed scripts/checkpatch.pl the patch and please check it. [PATCH] : diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 287cc62..a94b196 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -272,6 +272,14 @@ config USB_NET_DM9601 This option adds support for Davicom DM9601 based USB 1.1 10/100 Ethernet adapters. +config USB_NET_SR9700 + tristate "CoreChip-sz SR9700 based USB 1.1 10/100 ethernet devices" + depends on USB_USBNET + select CRC32 + help + This option adds support for CoreChip-sz SR9700 based USB 1.1 + 10/100 Ethernet adapters. + config USB_NET_SMSC75XX tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" depends on USB_USBNET diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 9ab5c9d..bba87a2 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_USB_NET_AX88179_178A) += ax88179_178a.o obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o obj-$(CONFIG_USB_NET_DM9601) += dm9601.o +obj-$(CONFIG_USB_NET_SR9700) += sr9700.o obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o obj-$(CONFIG_USB_NET_GL620A) += gl620a.o diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c new file mode 100644 index 0000000..9c8f167 --- /dev/null +++ b/drivers/net/usb/sr9700.c @@ -0,0 +1,536 @@ +/* + * CoreChip-sz SR9700 one chip USB 1.1 Ethernet Devices + * + * Author : liujl + * + * Based on dm9601.c + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sr9700.h" + +static int sr_read(struct usbnet *dev, u8 reg, u16 length, void *data) +{ + int err; + + err = usbnet_read_cmd(dev, SR_RD_REGS, SR_REQ_RD_REG, + 0, reg, data, length); + if ((err != length) && (err >= 0)) + err = -EINVAL; + return err; +} + +static int sr_write(struct usbnet *dev, u8 reg, u16 length, void *data) +{ + int err; + + err = usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG, + 0, reg, data, length); + if ((err >= 0) && (err < length)) + err = -EINVAL; + return err; +} + +static int sr_read_reg(struct usbnet *dev, u8 reg, u8 *value) +{ + return sr_read(dev, reg, 1, value); +} + +static int sr_write_reg(struct usbnet *dev, u8 reg, u8 value) +{ + return usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG, + value, reg, NULL, 0); +} + +static void sr_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) +{ + usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG, + 0, reg, data, length); +} + +static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value) +{ + usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG, + value, reg, NULL, 0); +} + +static int sr_share_read_word(struct usbnet *dev, int phy, u8 reg, __le16 *value) +{ + int ret, i; + + mutex_lock(&dev->phy_mutex); + + sr_write_reg(dev, EPAR, phy ? (reg | 0x40) : reg); + sr_write_reg(dev, EPCR, phy ? 0xc : 0x4); + + for (i = 0; i < SR_SHARE_TIMEOUT; i++) { + u8 tmp = 0; + + udelay(1); + ret = sr_read_reg(dev, EPCR, &tmp); + if (ret < 0) + goto out_unlock; + + /* ready */ + if ((tmp & EPCR_ERRE) == 0) + break; + } + + if (i >= SR_SHARE_TIMEOUT) { + netdev_err(dev->net, "%s read timed out!\n", phy ? "phy" : "eeprom"); + ret = -EIO; + goto out_unlock; + } + + sr_write_reg(dev, EPCR, 0x0); + ret = sr_read(dev, EPDR, 2, value); + + netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n", + phy, reg, *value, ret); + + out_unlock: + mutex_unlock(&dev->phy_mutex); + return ret; +} + +static int sr_share_write_word(struct usbnet *dev, int phy, u8 reg, __le16 value) +{ + int ret, i; + + mutex_lock(&dev->phy_mutex); + + ret = sr_write(dev, EPDR, 2, &value); + if (ret < 0) + goto out_unlock; + + sr_write_reg(dev, EPAR, phy ? (reg | 0x40) : reg); + sr_write_reg(dev, EPCR, phy ? 0x1a : 0x12); + + for (i = 0; i < SR_SHARE_TIMEOUT; i++) { + u8 tmp = 0; + + udelay(1); + ret = sr_read_reg(dev, EPCR, &tmp); + if (ret < 0) + goto out_unlock; + + /* ready */ + if ((tmp & EPCR_ERRE) == 0) + break; + } + + if (i >= SR_SHARE_TIMEOUT) { + netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom"); + ret = -EIO; + goto out_unlock; + } + + sr_write_reg(dev, EPCR, 0x0); + +out_unlock: + mutex_unlock(&dev->phy_mutex); + return ret; +} + +static int sr_read_eeprom_word(struct usbnet *dev, u8 offset, void *value) +{ + return sr_share_read_word(dev, 0, offset, value); +} + +static int sr9700_get_eeprom_len(struct net_device *dev) +{ + return SR_EEPROM_LEN; +} + +static int sr9700_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, u8 *data) +{ + struct usbnet *dev = netdev_priv(net); + __le16 *ebuf = (__le16 *) data; + int ret = 0; + int i; + + /* access is 16bit */ + if ((eeprom->offset % 2) || (eeprom->len % 2)) + return -EINVAL; + + for (i = 0; i < eeprom->len / 2; i++) + ret = sr_read_eeprom_word(dev, eeprom->offset / 2 + i, &ebuf[i]); + + return ret; +} + +static int sr_mdio_read(struct net_device *netdev, int phy_id, int loc) +{ + struct usbnet *dev = netdev_priv(netdev); + __le16 res; + int rc = 0; + + if (phy_id) { + netdev_dbg(dev->net, "Only internal phy supported\n"); + return 0; + } + + /* Access NSR_LINKST bit for link status instead of MII_BMSR */ + if (loc == MII_BMSR) { + u8 value; + + sr_read_reg(dev, NSR, &value); + if (value & NSR_LINKST) + rc = 1; + } + sr_share_read_word(dev, 1, loc, &res); + if (rc == 1) + return le16_to_cpu(res) | BMSR_LSTATUS; + else + return le16_to_cpu(res) & ~BMSR_LSTATUS; + + netdev_dbg(dev->net, + "sr_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", + phy_id, loc, le16_to_cpu(res)); + + return le16_to_cpu(res); +} + +static void sr_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) +{ + struct usbnet *dev = netdev_priv(netdev); + __le16 res = cpu_to_le16(val); + + if (phy_id) { + netdev_dbg(dev->net, "Only internal phy supported\n"); + return; + } + + netdev_dbg(dev->net, "sr_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", + phy_id, loc, val); + + sr_share_write_word(dev, 1, loc, res); +} + +static u32 sr9700_get_link(struct net_device *net) +{ + struct usbnet *dev = netdev_priv(net); + int rc = 0; + u8 value = 0; + + /* Get the Link Status directly */ + sr_read_reg(dev, NSR, &value); + if (value & NSR_LINKST) + rc = 1; + + return rc; +} + +static int sr9700_ioctl(struct net_device *net, struct ifreq *rq, int cmd) +{ + struct usbnet *dev = netdev_priv(net); + + return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); +} + +static const struct ethtool_ops sr9700_ethtool_ops = { + .get_drvinfo = usbnet_get_drvinfo, + .get_link = sr9700_get_link, + .get_msglevel = usbnet_get_msglevel, + .set_msglevel = usbnet_set_msglevel, + .get_eeprom_len = sr9700_get_eeprom_len, + .get_eeprom = sr9700_get_eeprom, + .get_settings = usbnet_get_settings, + .set_settings = usbnet_set_settings, + .nway_reset = usbnet_nway_reset, +}; + +static void sr9700_set_multicast(struct net_device *net) +{ + struct usbnet *dev = netdev_priv(net); + /* We use the 20 byte dev->data for our 8 byte filter buffer + * to avoid allocating memory that is tricky to free later + */ + u8 *hashes = (u8 *) &dev->data; + /* rx_ctl setting : enable, disable_long, disable_crc */ + u8 rx_ctl = RCR_RXEN | RCR_DIS_CRC | RCR_DIS_LONG; + + memset(hashes, 0x00, SR_MCAST_SIZE); + hashes[SR_MCAST_SIZE - 1] |= SR_MCAST_ADDR_FLAG; /* broadcast address */ + + if (net->flags & IFF_PROMISC) { + rx_ctl |= RCR_PRMSC; + } else if (net->flags & IFF_ALLMULTI || + netdev_mc_count(net) > SR_MCAST_MAX) { + rx_ctl |= RCR_RUNT; + } else if (!netdev_mc_empty(net)) { + struct netdev_hw_addr *ha; + netdev_for_each_mc_addr(ha, net) { + u32 crc = ether_crc(ETH_ALEN, ha->addr) >> 26; + hashes[crc >> 3] |= 1 << (crc & 0x7); + } + } + + sr_write_async(dev, MAR, SR_MCAST_SIZE, hashes); + sr_write_reg_async(dev, RCR, rx_ctl); +} + +static int sr9700_set_mac_address(struct net_device *net, void *p) +{ + struct sockaddr *addr = p; + struct usbnet *dev = netdev_priv(net); + + if (!is_valid_ether_addr(addr->sa_data)) { + netdev_err(net, "not setting invalid mac address %pM\n", + addr->sa_data); + return -EINVAL; + } + + memcpy(net->dev_addr, addr->sa_data, net->addr_len); + sr_write_async(dev, PAR, 6, dev->net->dev_addr); + + return 0; +} + +static const struct net_device_ops sr9700_netdev_ops = { + .ndo_open = usbnet_open, + .ndo_stop = usbnet_stop, + .ndo_start_xmit = usbnet_start_xmit, + .ndo_tx_timeout = usbnet_tx_timeout, + .ndo_change_mtu = usbnet_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_do_ioctl = sr9700_ioctl, + .ndo_set_rx_mode = sr9700_set_multicast, + .ndo_set_mac_address = sr9700_set_mac_address, +}; + +static int sr9700_bind(struct usbnet *dev, struct usb_interface *intf) +{ + int ret; + + ret = usbnet_get_endpoints(dev, intf); + if (ret) + goto out; + + dev->net->netdev_ops = &sr9700_netdev_ops; + dev->net->ethtool_ops = &sr9700_ethtool_ops; + dev->net->hard_header_len += SR_TX_OVERHEAD; + dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; + dev->rx_urb_size = 3072; /* bulkin buffer is preferably not less than 3K */ + + dev->mii.dev = dev->net; + dev->mii.mdio_read = sr_mdio_read; + dev->mii.mdio_write = sr_mdio_write; + dev->mii.phy_id_mask = 0x1f; + dev->mii.reg_num_mask = 0x1f; + + /* reset the sr9700 */ + sr_write_reg(dev, NCR, 1); + udelay(20); + + /* read MAC + * After Chip Power on, the Chip will reload the MAC from EEPROM automatically to PAR + * In case there is no EEPROM externally, a default MAC address is stored in PAR for making chip work properly + */ + if (sr_read(dev, PAR, ETH_ALEN, dev->net->dev_addr) < 0) { + netdev_err(dev->net, "Error reading MAC address\n"); + ret = -ENODEV; + goto out; + } + + /* power up and reset phy */ + sr_write_reg(dev, PRR, 1); + mdelay(20); /* at least 10ms, here 20ms for safe */ + sr_write_reg(dev, PRR, 0); + udelay(2 * 1000); /* at least 1ms, here 2ms for reading right register */ + + /* receive broadcast packets */ + sr9700_set_multicast(dev->net); + + sr_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); + sr_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); + mii_nway_restart(&dev->mii); + +out: + return ret; +} + +static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +{ + int len; + struct sk_buff *sr_skb; + + /* format: + b0: rx status + b1: packet length (incl crc) low + b2: packet length (incl crc) high + b3..n-4: packet data + bn-3..bn: ethernet crc + */ + + if (unlikely(skb->len < SR_RX_OVERHEAD)) { + netdev_err(dev->net, "unexpected tiny rx frame\n"); + return 0; + } + + /* Each packet contains multiple skbs */ + while (skb->len > SR_RX_OVERHEAD) { + if (skb->data[0] != 0x40) + return 0; + + /* ignore the CRC length */ + len = (skb->data[1] | (skb->data[2] << 8)) - 4; + + if (len > ETH_FRAME_LEN) + return 0; + + /* the last skb of current packet */ + if (skb->len == (len + SR_RX_OVERHEAD)) { + skb_pull(skb, 3); + skb->len = len; + skb->tail = skb->data + len; + skb->truesize = len + sizeof(struct sk_buff); + return 2; + } + + /* skb_clone is used for address align */ + sr_skb = skb_clone(skb, GFP_ATOMIC); + if (sr_skb) { + sr_skb->len = len; + sr_skb->data = skb->data + 3; + sr_skb->tail = skb->data + len; + sr_skb->truesize = len + sizeof(struct sk_buff); + usbnet_skb_return(dev, sr_skb); + } else { + return 0; + } + + skb_pull(skb, len + SR_RX_OVERHEAD); + }; + + return 0; +} + +static struct sk_buff *sr9700_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) +{ + int len; + + /* format: + b0: packet length low + b1: packet length high + b3..n: packet data + */ + + len = skb->len; + + if (skb_headroom(skb) < SR_TX_OVERHEAD) { + struct sk_buff *skb2; + + skb2 = skb_copy_expand(skb, SR_TX_OVERHEAD, 0, flags); + dev_kfree_skb_any(skb); + skb = skb2; + if (!skb) + return NULL; + } + + __skb_push(skb, SR_TX_OVERHEAD); + + /* usbnet adds padding if length is a multiple of packet size + * if so, adjust length value in header + */ + if ((skb->len % dev->maxpacket) == 0) + len++; + + skb->data[0] = len; + skb->data[1] = len >> 8; + + return skb; +} + +static void sr9700_status(struct usbnet *dev, struct urb *urb) +{ + int link; + u8 *buf; + + /* format: + b0: net status + b1: tx status 1 + b2: tx status 2 + b3: rx status + b4: rx overflow + b5: rx count + b6: tx count + b7: gpr + */ + + if (urb->actual_length < 8) + return; + + buf = urb->transfer_buffer; + + link = !!(buf[0] & 0x40); + if (netif_carrier_ok(dev->net) != link) { + usbnet_link_change(dev, link, 1); + netdev_dbg(dev->net, "Link Status is: %d\n", link); + } +} + +static int sr9700_link_reset(struct usbnet *dev) +{ + struct ethtool_cmd ecmd; + + mii_check_media(&dev->mii, 1, 1); + mii_ethtool_gset(&dev->mii, &ecmd); + + netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n", + ecmd.speed, ecmd.duplex); + + return 0; +} + +static const struct driver_info sr9700_driver_info = { + .description = "CoreChip SR9700 USB Ethernet", + .flags = FLAG_ETHER, + .bind = sr9700_bind, + .rx_fixup = sr9700_rx_fixup, + .tx_fixup = sr9700_tx_fixup, + .status = sr9700_status, + .link_reset = sr9700_link_reset, + .reset = sr9700_link_reset, +}; + +static const struct usb_device_id products[] = { + { + USB_DEVICE(0x0fe6, 0x9700), /* SR9700 device */ + .driver_info = (unsigned long)&sr9700_driver_info, + }, + {}, /* END */ +}; + +MODULE_DEVICE_TABLE(usb, products); + +static struct usb_driver sr9700_usb_driver = { + .name = "sr9700", + .id_table = products, + .probe = usbnet_probe, + .disconnect = usbnet_disconnect, + .suspend = usbnet_suspend, + .resume = usbnet_resume, + .disable_hub_initiated_lpm = 1, +}; + +module_usb_driver(sr9700_usb_driver); + +MODULE_AUTHOR("liujl "); +MODULE_DESCRIPTION("SR9700 one chip USB 1.1 USB to Ethernet device from http://www.corechip-sz.com/"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/usb/sr9700.h b/drivers/net/usb/sr9700.h new file mode 100644 index 0000000..f1968ae --- /dev/null +++ b/drivers/net/usb/sr9700.h @@ -0,0 +1,172 @@ +/* + * CoreChip-sz SR9700 one chip USB 1.1 Ethernet Devices + * + * Author : liujl + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#ifndef _SR9700_H +#define _SR9700_H + +/* sr9700 spec. register table on Linux platform */ + +/* Network Control Reg */ +#define NCR 0x00 +#define NCR_RST (1 << 0) +#define NCR_LBK (3 << 1) +#define NCR_FDX (1 << 3) +#define NCR_WAKEEN (1 << 6) +/* Network Status Reg */ +#define NSR 0x01 +#define NSR_RXRDY (1 << 0) +#define NSR_RXOV (1 << 1) +#define NSR_TX1END (1 << 2) +#define NSR_TX2END (1 << 3) +#define NSR_TXFULL (1 << 4) +#define NSR_WAKEST (1 << 5) +#define NSR_LINKST (1 << 6) +#define NSR_SPEED (1 << 7) +/* Tx Control Reg */ +#define TCR 0x02 +#define TCR_CRC_DIS (1 << 1) +#define TCR_PAD_DIS (1 << 2) +#define TCR_LC_CARE (1 << 3) +#define TCR_CRS_CARE (1 << 4) +#define TCR_EXCECM (1 << 5) +#define TCR_LF_EN (1 << 6) +/* Tx Status Reg for Packet Index 1 */ +#define TSR1 0x03 +#define TSR1_EC (1 << 2) +#define TSR1_COL (1 << 3) +#define TSR1_LC (1 << 4) +#define TSR1_NC (1 << 5) +#define TSR1_LOC (1 << 6) +#define TSR1_TLF (1 << 7) +/* Tx Status Reg for Packet Index 2 */ +#define TSR2 0x04 +#define TSR2_EC (1 << 2) +#define TSR2_COL (1 << 3) +#define TSR2_LC (1 << 4) +#define TSR2_NC (1 << 5) +#define TSR2_LOC (1 << 6) +#define TSR2_TLF (1 << 7) +/* Rx Control Reg*/ +#define RCR 0x05 +#define RCR_RXEN (1 << 0) +#define RCR_PRMSC (1 << 1) +#define RCR_RUNT (1 << 2) +#define RCR_ALL (1 << 3) +#define RCR_DIS_CRC (1 << 4) +#define RCR_DIS_LONG (1 << 5) +/* Rx Status Reg */ +#define RSR 0x06 +#define RSR_AE (1 << 2) +#define RSR_MF (1 << 6) +#define RSR_RF (1 << 7) +/* Rx Overflow Counter Reg */ +#define ROCR 0x07 +#define ROCR_ROC (0x7F << 0) +#define ROCR_RXFU (1 << 7) +/* Back Pressure Threshold Reg */ +#define BPTR 0x08 +#define BPTR_JPT (0x0F << 0) +#define BPTR_BPHW (0x0F << 4) +/* Flow Control Threshold Reg */ +#define FCTR 0x09 +#define FCTR_LWOT (0x0F << 0) +#define FCTR_HWOT (0x0F << 4) +/* rx/tx Flow Control Reg */ +#define FCR 0x0A +#define FCR_FLCE (1 << 0) +#define FCR_BKPA (1 << 4) +#define FCR_TXPEN (1 << 5) +#define FCR_TXPF (1 << 6) +#define FCR_TXP0 (1 << 7) +/* Eeprom & Phy Control Reg */ +#define EPCR 0x0B +#define EPCR_ERRE (1 << 0) +#define EPCR_ERPRW (1 << 1) +#define EPCR_ERPRR (1 << 2) +#define EPCR_EPOS (1 << 3) +#define EPCR_WEP (1 << 4) +/* Eeprom & Phy Address Reg */ +#define EPAR 0x0C +#define EPAR_EROA (0x3F << 0) +#define EPAR_PHY_ADR (0x03 << 6) +/* Eeprom & Phy Data Reg */ +#define EPDR 0x0D /* 0x0D ~ 0x0E for Data Reg Low & High */ +/* Wakeup Control Reg */ +#define WCR 0x0F +#define WCR_MAGICST (1 << 0) +#define WCR_LINKST (1 << 2) +#define WCR_MAGICEN (1 << 3) +#define WCR_LINKEN (1 << 5) +/* Physical Address Reg */ +#define PAR 0x10 /* 0x10 ~ 0x15 6 bytes for PAR */ +/* Multicast Address Reg */ +#define MAR 0x16 /* 0x16 ~ 0x1D 8 bytes for MAR */ +/* 0x1e unused */ +/* Phy Reset Reg */ +#define PRR 0x1F +#define PRR_PHY_RST (1 << 0) +/* Tx sdram Write Pointer Address Low */ +#define TWPAL 0x20 +/* Tx sdram Write Pointer Address High */ +#define TWPAH 0x21 +/* Tx sdram Read Pointer Address Low */ +#define TRPAL 0x22 +/* Tx sdram Read Pointer Address High */ +#define TRPAH 0x23 +/* Rx sdram Write Pointer Address Low */ +#define RWPAL 0x24 +/* Rx sdram Write Pointer Address High */ +#define RWPAH 0x25 +/* Rx sdram Read Pointer Address Low */ +#define RRPAL 0x26 +/* Rx sdram Read Pointer Address High */ +#define RRPAH 0x27 +/* Vendor ID register */ +#define VID 0x28 /* 0x28 ~ 0x29 2 bytes for VID */ +/* Product ID register */ +#define PID 0x2A /* 0x2A ~ 0x2B 2 bytes for PID */ +/* CHIP Revision register */ +#define CHIPR 0x2C +/* 0x2D --> 0xEF unused */ +/* USB Device Address */ +#define USBDA 0xF0 +#define USBDA_USBFA (0x7F << 0) +/* RX packet Counter Reg */ +#define RXC 0xF1 +/* Tx packet Counter & USB Status Reg */ +#define TXC_USBS 0xF2 +#define TXC_USBS_TXC0 (1 << 0) +#define TXC_USBS_TXC1 (1 << 1) +#define TXC_USBS_TXC2 (1 << 2) +#define TXC_USBS_EP1RDY (1 << 5) +#define TXC_USBS_SUSFLAG (1 << 6) +#define TXC_USBS_RXFAULT (1 << 7) +/* USB Control register */ +#define USBC 0xF4 +#define USBC_EP3NAK (1 << 4) +#define USBC_EP3ACK (1 << 5) + +/* Register access commands and flags */ +#define SR_RD_REGS 0x00 +#define SR_WR_REGS 0x01 +#define SR_WR_REG 0x03 +#define SR_REQ_RD_REG (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE) +#define SR_REQ_WR_REG (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) + +/* parameters */ +#define SR_SHARE_TIMEOUT 1000 +#define SR_EEPROM_LEN 256 +#define SR_MCAST_SIZE 8 +#define SR_MCAST_ADDR_FLAG 0x80 +#define SR_MCAST_MAX 64 +#define SR_TX_OVERHEAD 2 /* 2bytes header */ +#define SR_RX_OVERHEAD 7 /* 3bytes header + 4crc tail */ + +#endif /* _SR9700_H */ 2013-08-21 liujunliang_ljl 发件人: Francois Romieu 发送时间: 2013-08-21 04:46:12 收件人: liujunliang_ljl 抄送: gregkh; sunhecheng; linux-usb; netdev; linux-kernel 主题: Re: [PATCH-SR9700] Merge USB 1.1 Ethernet Adapter SR9700 DeviceDriver into the Linux Kernel liujunliang_ljl : [...] > We want to merge SR9700 device driver into the Linux Kernel. The following > is the Linux 3.10.7 version patch for SR9700, Please give us the assessment > and support. Welcome. Go ahead. [...] > diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c > new file mode 100644 > index 0000000..6a6429a > --- /dev/null > +++ b/drivers/net/usb/sr9700.c [...] > +static int sr_read(struct usbnet *dev, u8 reg, u16 length, void *data) > +{ > + int err; > + > + err = usbnet_read_cmd(dev, SR_RD_REGS, SR_REQ_RD_REG, > + 0, reg, data, length); err = usbnet_read_cmd(dev, SR_RD_REGS, SR_REQ_RD_REG, 0, reg, data, length); > + if(err != length && err >= 0) ^^ missing space > + err = -EINVAL; > + return err; > +} > + > +static int sr_write(struct usbnet *dev, u8 reg, u16 length, void *data) > +{ > + int err; > + > + err = usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG, > + 0, reg, data, length); See above. > + if (err >= 0 && err < length) > + err = -EINVAL; > + > + return err; > +} > + > +static int sr_read_reg(struct usbnet *dev, u8 reg, u8 *value) > +{ > + return sr_read(dev, reg, 1, value); > +} > + > +static int sr_write_reg(struct usbnet *dev, u8 reg, u8 value) > +{ > + return usbnet_write_cmd(dev, SR_WR_REGS, SR_REQ_WR_REG, > + value, reg, NULL, 0); Sic. > +} > + > +static void sr_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) > +{ > + usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG, > + 0, reg, data, length); Sic. > +} > + > +static void sr_write_reg_async(struct usbnet *dev, u8 reg, u8 value) > +{ > + usbnet_write_cmd_async(dev, SR_WR_REGS, SR_REQ_WR_REG, > + value, reg, NULL, 0); Sic. > +} > + > +static int sr_share_read_word(struct usbnet *dev, int phy, u8 reg, __le16 *value) > +{ > + int ret, i; > + > + mutex_lock(&dev->phy_mutex); > + > + sr_write_reg(dev, EPAR, phy ? (reg | 0x40) : reg); > + sr_write_reg(dev, EPCR, phy ? 0xc : 0x4); > + > + for (i = 0; i < SR_SHARE_TIMEOUT; i++) { > + u8 tmp = 0; > + > + udelay(1); > + ret = sr_read_reg(dev, EPCR, &tmp); > + if (ret < 0) > + goto out; goto out_unlock; > + > + /* ready */ > + if ((tmp & 1) == 0) if ((tmp & EPCR_ERRE) == 0) > + break; > + } > + > + if (i >= SR_SHARE_TIMEOUT) { > + netdev_err(dev->net, "%s read timed out!", phy ? "phy" : "eeprom"); > + ret = -EIO; > + goto out; > + } > + > + sr_write_reg(dev, EPCR, 0x0); > + ret = sr_read(dev, EPDR, 2, value); > + > + netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d", > + phy, reg, *value, ret); > + > + out: ^ please remove space. > + mutex_unlock(&dev->phy_mutex); > + return ret; > +} > + > +static int sr_share_write_word(struct usbnet *dev, int phy, u8 reg, __le16 value) > +{ > + int ret, i; > + > + mutex_lock(&dev->phy_mutex); > + > + ret = sr_write(dev, EPDR, 2, &value); > + if (ret < 0) > + goto out; > + > + sr_write_reg(dev, EPAR, phy ? (reg | 0x40) : reg); > + sr_write_reg(dev, EPCR, phy ? 0x1a : 0x12); > + > + for (i = 0; i < SR_SHARE_TIMEOUT; i++) { > + u8 tmp = 0; > + > + udelay(1); > + ret = sr_read_reg(dev, EPCR, &tmp); > + if (ret < 0) > + goto out; > + > + /* ready */ > + if ((tmp & 1) == 0) > + break; > + } The 11 lines above are identical in sr_share_read_word. Please refactor. [...] > +static int sr_mdio_read(struct net_device *netdev, int phy_id, int loc) > +{ > + struct usbnet *dev = netdev_priv(netdev); > + > + __le16 res; Excess empty line. > + int rc = 0; > + > + if (phy_id) { > + netdev_dbg(dev->net, "Only internal phy supported"); > + return 0; > + } > + > + /* Access NSR_LINKST bit for link status instead of MII_BMSR */ > + if(loc == MII_BMSR){ ^^ ^^ Missing spaces. > + u8 value; Excess tabs and missing empty line. > + sr_read_reg(dev, NSR, &value); > + if(value & NSR_LINKST) { Excess tabs, missing spaces, useless "{". > + rc = 1; > + } > + } > + sr_share_read_word(dev, 1, loc, &res); > + if(rc == 1) > + return (le16_to_cpu(res) | BMSR_LSTATUS); > + else > + return (le16_to_cpu(res) & ~BMSR_LSTATUS); Excess "(" (aka "return is not a function"). [...] > +/*-------------------------------------------------------------------------------------------*/ Just say no. [...] > +static void sr9700_set_multicast(struct net_device *net) > +{ > + struct usbnet *dev = netdev_priv(net); > + /* We use the 20 byte dev->data for our 8 byte filter buffer > + * to avoid allocating memory that is tricky to free later */ > + u8 *hashes = (u8 *) & dev->data; ^extraneous space > + u8 rx_ctl = 0x31; // enable, disable_long, disable_crc u8 rx_ctl = RCR_ALL | RCR_DIS_CRC | RCR_DIS_LONG; > + > + memset(hashes, 0x00, SR_MCAST_SIZE); > + hashes[SR_MCAST_SIZE - 1] |= 0x80; /* broadcast address */ Use #define. > + > + if (net->flags & IFF_PROMISC) { ^^^^^^^^ should use tab, not space > + rx_ctl |= 0x02; ^^^... sic > + } else if (net->flags & IFF_ALLMULTI || > + netdev_mc_count(net) > SR_MCAST_MAX) { > + rx_ctl |= 0x04; > + } else if (!netdev_mc_empty(net)) { > + struct netdev_hw_addr *ha; > + > + netdev_for_each_mc_addr(ha, net) { > + u32 crc = ether_crc(ETH_ALEN, ha->addr) >> 26; > + hashes[crc >> 3] |= 1 << (crc & 0x7); > + } > + } ^^^... etc. > + > + sr_write_async(dev, MAR, SR_MCAST_SIZE, hashes); > + sr_write_reg_async(dev, RCR, rx_ctl); > +} > + > +static int sr9700_set_mac_address(struct net_device *net, void *p) > +{ > + struct sockaddr *addr = p; > + struct usbnet *dev = netdev_priv(net); Long declaration lines first please. > + > + if (!is_valid_ether_addr(addr->sa_data)) { > + dev_err(&net->dev, "not setting invalid mac address %pM\n", > + addr->sa_data); dev_err(&net->dev, "not setting invalid mac address %pM\n", addr->sa_data); [...] > +static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb) > +{ > + int len; > + struct sk_buff *sr_skb; > + > + /* format: > + b0: rx status > + b1: packet length (incl crc) low > + b2: packet length (incl crc) high > + b3..n-4: packet data > + bn-3..bn: ethernet crc > + */ > + > + if (unlikely(skb->len < SR_RX_OVERHEAD)) { > + dev_err(&dev->udev->dev, "unexpected tiny rx frame\n"); > + return 0; > + } > + > + /* > + * Each packet contains multiple skbs > + */ > + while (skb->len > SR_RX_OVERHEAD) > + { K&R please. [...] > +static struct usb_driver sr9700_usb_driver = { > + .name = "sr9700", > + .id_table = products, > + .probe = usbnet_probe, > + .disconnect = usbnet_disconnect, > + .suspend = usbnet_suspend, > + .resume = usbnet_resume, > + .disable_hub_initiated_lpm = 1, Use =. [...] > diff --git a/drivers/net/usb/sr9700.h b/drivers/net/usb/sr9700.h > new file mode 100644 > index 0000000..d9fe82d > --- /dev/null > +++ b/drivers/net/usb/sr9700.h > @@ -0,0 +1,152 @@ > +/* > + * CoreChip-sz SR9700 one chip USB 1.1 Ethernet Devices > + * > + * Author : liujl > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * version 2 as published by the Free Software Foundation. > + */ > + > +/* sr9700 spec. register table on android platform */ > +/* Registers */ > +#define NCR 0x00 > +#define NSR 0x01 [...] > +/* Bit definition for registers */ > +// Network Control Reg > +#define NCR_RST (1 << 0) > +#define NCR_LBK (3 << 1) > +#define NCR_FDX (1 << 3) > +#define NCR_WAKEEN (1 << 6) You may group these with the register declarations above. Use an offset to improve readability and separate registers from fields. See drivers/net/ethernet/broadcom/tg3.h for instance. -- Ueimor 翳簕.n+壏煯壄+%娝遍荻w簕.n+壏{炳G珴妠ay蕠跈,jf"穐殢飦戧鐉_璁(殠娸"濟mG珴⒏?櫒璀&x忈秈O曟瑉窔v豝m 鹅⒏?朓 From mboxrd@z Thu Jan 1 00:00:00 1970 From: "liujunliang_ljl" Subject: Re: Re: [PATCH-SR9700] Merge USB 1.1 Ethernet Adapter SR9700 DeviceDriver into the Linux Kernel Date: Wed, 21 Aug 2013 18:06:02 +0800 Message-ID: <201308211805574844059@163.com> References: <201308201841116403992@163.com>, <20130820204606.GB26241@electric-eye.fr.zoreil.com> Mime-Version: 1.0 Content-Type: text/plain; charset="gb2312" Content-Transfer-Encoding: base64 Cc: "gregkh" , "sunhecheng" , "linux-usb" , "netdev" , "linux-kernel" To: "Francois Romieu" Return-path: Sender: linux-kernel-owner@vger.kernel.org List-Id: netdev.vger.kernel.org RGVhciBGcmFuY29pcyBSb21pZXUgOg0KDQoJMSwgYWxsIHRoZSBmb3JtYXQgcHJvYmxlbXMgaGF2 ZSBiZWVuIGZpeGVkDQoJDQoJMiwgc3I5NzAwLmggcmVnaXN0ZXJzIGRlZmluaXRpb24gaXMgcmUt d3JpdHRlbg0KDQoJMywgVGhhbmtzIGZvciB5b3VyIGRldGFpbCBjaGVja2luZyBhbmQgSSBoYXZl IGJlZWQgc2NyaXB0cy9jaGVja3BhdGNoLnBsIHRoZSBwYXRjaCBhbmQgcGxlYXNlIGNoZWNrIGl0 Lg0KDQpbUEFUQ0hdIDoNCmRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC91c2IvS2NvbmZpZyBiL2Ry aXZlcnMvbmV0L3VzYi9LY29uZmlnDQppbmRleCAyODdjYzYyLi5hOTRiMTk2IDEwMDY0NA0KLS0t IGEvZHJpdmVycy9uZXQvdXNiL0tjb25maWcNCisrKyBiL2RyaXZlcnMvbmV0L3VzYi9LY29uZmln DQpAQCAtMjcyLDYgKzI3MiwxNCBAQCBjb25maWcgVVNCX05FVF9ETTk2MDENCiAJICBUaGlzIG9w dGlvbiBhZGRzIHN1cHBvcnQgZm9yIERhdmljb20gRE05NjAxIGJhc2VkIFVTQiAxLjENCiAJICAx MC8xMDAgRXRoZXJuZXQgYWRhcHRlcnMuDQogDQorY29uZmlnIFVTQl9ORVRfU1I5NzAwDQorCXRy aXN0YXRlICJDb3JlQ2hpcC1zeiBTUjk3MDAgYmFzZWQgVVNCIDEuMSAxMC8xMDAgZXRoZXJuZXQg ZGV2aWNlcyINCisJZGVwZW5kcyBvbiBVU0JfVVNCTkVUDQorCXNlbGVjdCBDUkMzMg0KKwloZWxw DQorCSAgVGhpcyBvcHRpb24gYWRkcyBzdXBwb3J0IGZvciBDb3JlQ2hpcC1zeiBTUjk3MDAgYmFz ZWQgVVNCIDEuMQ0KKwkgIDEwLzEwMCBFdGhlcm5ldCBhZGFwdGVycy4NCisNCiBjb25maWcgVVNC X05FVF9TTVNDNzVYWA0KIAl0cmlzdGF0ZSAiU01TQyBMQU43NVhYIGJhc2VkIFVTQiAyLjAgZ2ln YWJpdCBldGhlcm5ldCBkZXZpY2VzIg0KIAlkZXBlbmRzIG9uIFVTQl9VU0JORVQNCmRpZmYgLS1n aXQgYS9kcml2ZXJzL25ldC91c2IvTWFrZWZpbGUgYi9kcml2ZXJzL25ldC91c2IvTWFrZWZpbGUN CmluZGV4IDlhYjVjOWQuLmJiYTg3YTIgMTAwNjQ0DQotLS0gYS9kcml2ZXJzL25ldC91c2IvTWFr ZWZpbGUNCisrKyBiL2RyaXZlcnMvbmV0L3VzYi9NYWtlZmlsZQ0KQEAgLTE0LDYgKzE0LDcgQEAg b2JqLSQoQ09ORklHX1VTQl9ORVRfQVg4ODE3OV8xNzhBKSAgICAgICs9IGF4ODgxNzlfMTc4YS5v DQogb2JqLSQoQ09ORklHX1VTQl9ORVRfQ0RDRVRIRVIpCSs9IGNkY19ldGhlci5vDQogb2JqLSQo Q09ORklHX1VTQl9ORVRfQ0RDX0VFTSkJKz0gY2RjX2VlbS5vDQogb2JqLSQoQ09ORklHX1VTQl9O RVRfRE05NjAxKQkrPSBkbTk2MDEubw0KK29iai0kKENPTkZJR19VU0JfTkVUX1NSOTcwMCkJKz0g c3I5NzAwLm8NCiBvYmotJChDT05GSUdfVVNCX05FVF9TTVNDNzVYWCkJKz0gc21zYzc1eHgubw0K IG9iai0kKENPTkZJR19VU0JfTkVUX1NNU0M5NVhYKQkrPSBzbXNjOTV4eC5vDQogb2JqLSQoQ09O RklHX1VTQl9ORVRfR0w2MjBBKQkrPSBnbDYyMGEubw0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0 L3VzYi9zcjk3MDAuYyBiL2RyaXZlcnMvbmV0L3VzYi9zcjk3MDAuYw0KbmV3IGZpbGUgbW9kZSAx MDA2NDQNCmluZGV4IDAwMDAwMDAuLjljOGYxNjcNCi0tLSAvZGV2L251bGwNCisrKyBiL2RyaXZl cnMvbmV0L3VzYi9zcjk3MDAuYw0KQEAgLTAsMCArMSw1MzYgQEANCisvKg0KKyAqIENvcmVDaGlw LXN6IFNSOTcwMCBvbmUgY2hpcCBVU0IgMS4xIEV0aGVybmV0IERldmljZXMNCisgKg0KKyAqIEF1 dGhvciA6IGxpdWpsIDxsaXVqdW5saWFuZ19samxAMTYzLmNvbT4NCisgKg0KKyAqIEJhc2VkIG9u IGRtOTYwMS5jDQorICoNCisgKiBUaGlzIGZpbGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIHRlcm1z IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQ0KKyAqIHZlcnNpb24gMi4gIFRoaXMg cHJvZ3JhbSBpcyBsaWNlbnNlZCAiYXMgaXMiIHdpdGhvdXQgYW55IHdhcnJhbnR5IG9mIGFueQ0K KyAqIGtpbmQsIHdoZXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLg0KKyAqLw0KKw0KKyNpbmNsdWRl IDxsaW51eC9tb2R1bGUuaD4NCisjaW5jbHVkZSA8bGludXgvc2NoZWQuaD4NCisjaW5jbHVkZSA8 bGludXgvc3RkZGVmLmg+DQorI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4NCisjaW5jbHVkZSA8bGlu dXgvbmV0ZGV2aWNlLmg+DQorI2luY2x1ZGUgPGxpbnV4L2V0aGVyZGV2aWNlLmg+DQorI2luY2x1 ZGUgPGxpbnV4L2V0aHRvb2wuaD4NCisjaW5jbHVkZSA8bGludXgvbWlpLmg+DQorI2luY2x1ZGUg PGxpbnV4L3VzYi5oPg0KKyNpbmNsdWRlIDxsaW51eC9jcmMzMi5oPg0KKyNpbmNsdWRlIDxsaW51 eC91c2IvdXNibmV0Lmg+DQorDQorI2luY2x1ZGUgInNyOTcwMC5oIg0KKw0KK3N0YXRpYyBpbnQg c3JfcmVhZChzdHJ1Y3QgdXNibmV0ICpkZXYsIHU4IHJlZywgdTE2IGxlbmd0aCwgdm9pZCAqZGF0 YSkNCit7DQorCWludCBlcnI7DQorDQorCWVyciA9IHVzYm5ldF9yZWFkX2NtZChkZXYsIFNSX1JE X1JFR1MsIFNSX1JFUV9SRF9SRUcsDQorCQkJCQkwLCByZWcsIGRhdGEsIGxlbmd0aCk7DQorCWlm ICgoZXJyICE9IGxlbmd0aCkgJiYgKGVyciA+PSAwKSkNCisJCWVyciA9IC1FSU5WQUw7DQorCXJl dHVybiBlcnI7DQorfQ0KKw0KK3N0YXRpYyBpbnQgc3Jfd3JpdGUoc3RydWN0IHVzYm5ldCAqZGV2 LCB1OCByZWcsIHUxNiBsZW5ndGgsIHZvaWQgKmRhdGEpDQorew0KKwlpbnQgZXJyOw0KKw0KKwll cnIgPSB1c2JuZXRfd3JpdGVfY21kKGRldiwgU1JfV1JfUkVHUywgU1JfUkVRX1dSX1JFRywNCisJ CQkJCTAsIHJlZywgZGF0YSwgbGVuZ3RoKTsNCisJaWYgKChlcnIgPj0gMCkgJiYgKGVyciA8IGxl bmd0aCkpDQorCQllcnIgPSAtRUlOVkFMOw0KKwlyZXR1cm4gZXJyOw0KK30NCisNCitzdGF0aWMg aW50IHNyX3JlYWRfcmVnKHN0cnVjdCB1c2JuZXQgKmRldiwgdTggcmVnLCB1OCAqdmFsdWUpDQor ew0KKwlyZXR1cm4gc3JfcmVhZChkZXYsIHJlZywgMSwgdmFsdWUpOw0KK30NCisNCitzdGF0aWMg aW50IHNyX3dyaXRlX3JlZyhzdHJ1Y3QgdXNibmV0ICpkZXYsIHU4IHJlZywgdTggdmFsdWUpDQor ew0KKwlyZXR1cm4gdXNibmV0X3dyaXRlX2NtZChkZXYsIFNSX1dSX1JFR1MsIFNSX1JFUV9XUl9S RUcsDQorCQkJCQl2YWx1ZSwgcmVnLCBOVUxMLCAwKTsNCit9DQorDQorc3RhdGljIHZvaWQgc3Jf d3JpdGVfYXN5bmMoc3RydWN0IHVzYm5ldCAqZGV2LCB1OCByZWcsIHUxNiBsZW5ndGgsIHZvaWQg KmRhdGEpDQorew0KKwl1c2JuZXRfd3JpdGVfY21kX2FzeW5jKGRldiwgU1JfV1JfUkVHUywgU1Jf UkVRX1dSX1JFRywNCisJCQkJCTAsIHJlZywgZGF0YSwgbGVuZ3RoKTsNCit9DQorDQorc3RhdGlj IHZvaWQgc3Jfd3JpdGVfcmVnX2FzeW5jKHN0cnVjdCB1c2JuZXQgKmRldiwgdTggcmVnLCB1OCB2 YWx1ZSkNCit7DQorCXVzYm5ldF93cml0ZV9jbWRfYXN5bmMoZGV2LCBTUl9XUl9SRUdTLCBTUl9S RVFfV1JfUkVHLA0KKwkJCQkJdmFsdWUsIHJlZywgTlVMTCwgMCk7DQorfQ0KKw0KK3N0YXRpYyBp bnQgc3Jfc2hhcmVfcmVhZF93b3JkKHN0cnVjdCB1c2JuZXQgKmRldiwgaW50IHBoeSwgdTggcmVn LCBfX2xlMTYgKnZhbHVlKQ0KK3sNCisJaW50IHJldCwgaTsNCisNCisJbXV0ZXhfbG9jaygmZGV2 LT5waHlfbXV0ZXgpOw0KKw0KKwlzcl93cml0ZV9yZWcoZGV2LCBFUEFSLCBwaHkgPyAocmVnIHwg MHg0MCkgOiByZWcpOw0KKwlzcl93cml0ZV9yZWcoZGV2LCBFUENSLCBwaHkgPyAweGMgOiAweDQp Ow0KKw0KKwlmb3IgKGkgPSAwOyBpIDwgU1JfU0hBUkVfVElNRU9VVDsgaSsrKSB7DQorCQl1OCB0 bXAgPSAwOw0KKw0KKwkJdWRlbGF5KDEpOw0KKwkJcmV0ID0gc3JfcmVhZF9yZWcoZGV2LCBFUENS LCAmdG1wKTsNCisJCWlmIChyZXQgPCAwKQ0KKwkJCWdvdG8gb3V0X3VubG9jazsNCisNCisJCS8q IHJlYWR5ICovDQorCQlpZiAoKHRtcCAmIEVQQ1JfRVJSRSkgPT0gMCkNCisJCQlicmVhazsNCisJ fQ0KKw0KKwlpZiAoaSA+PSBTUl9TSEFSRV9USU1FT1VUKSB7DQorCQluZXRkZXZfZXJyKGRldi0+ bmV0LCAiJXMgcmVhZCB0aW1lZCBvdXQhXG4iLCBwaHkgPyAicGh5IiA6ICJlZXByb20iKTsNCisJ CXJldCA9IC1FSU87DQorCQlnb3RvIG91dF91bmxvY2s7DQorCX0NCisNCisJc3Jfd3JpdGVfcmVn KGRldiwgRVBDUiwgMHgwKTsNCisJcmV0ID0gc3JfcmVhZChkZXYsIEVQRFIsIDIsIHZhbHVlKTsN CisNCisJbmV0ZGV2X2RiZyhkZXYtPm5ldCwgInJlYWQgc2hhcmVkICVkIDB4JTAyeCByZXR1cm5l ZCAweCUwNHgsICVkXG4iLA0KKwkgICAgICAgcGh5LCByZWcsICp2YWx1ZSwgcmV0KTsNCisNCisg b3V0X3VubG9jazoNCisJbXV0ZXhfdW5sb2NrKCZkZXYtPnBoeV9tdXRleCk7DQorCXJldHVybiBy ZXQ7DQorfQ0KKw0KK3N0YXRpYyBpbnQgc3Jfc2hhcmVfd3JpdGVfd29yZChzdHJ1Y3QgdXNibmV0 ICpkZXYsIGludCBwaHksIHU4IHJlZywgX19sZTE2IHZhbHVlKQ0KK3sNCisJaW50IHJldCwgaTsN CisNCisJbXV0ZXhfbG9jaygmZGV2LT5waHlfbXV0ZXgpOw0KKw0KKwlyZXQgPSBzcl93cml0ZShk ZXYsIEVQRFIsIDIsICZ2YWx1ZSk7DQorCWlmIChyZXQgPCAwKQ0KKwkJZ290byBvdXRfdW5sb2Nr Ow0KKw0KKwlzcl93cml0ZV9yZWcoZGV2LCBFUEFSLCBwaHkgPyAocmVnIHwgMHg0MCkgOiByZWcp Ow0KKwlzcl93cml0ZV9yZWcoZGV2LCBFUENSLCBwaHkgPyAweDFhIDogMHgxMik7DQorDQorCWZv ciAoaSA9IDA7IGkgPCBTUl9TSEFSRV9USU1FT1VUOyBpKyspIHsNCisJCXU4IHRtcCA9IDA7DQor DQorCQl1ZGVsYXkoMSk7DQorCQlyZXQgPSBzcl9yZWFkX3JlZyhkZXYsIEVQQ1IsICZ0bXApOw0K KwkJaWYgKHJldCA8IDApDQorCQkJZ290byBvdXRfdW5sb2NrOw0KKw0KKwkJLyogcmVhZHkgKi8N CisJCWlmICgodG1wICYgRVBDUl9FUlJFKSA9PSAwKQ0KKwkJCWJyZWFrOw0KKwl9DQorDQorCWlm IChpID49IFNSX1NIQVJFX1RJTUVPVVQpIHsNCisJCW5ldGRldl9lcnIoZGV2LT5uZXQsICIlcyB3 cml0ZSB0aW1lZCBvdXQhXG4iLCBwaHkgPyAicGh5IiA6ICJlZXByb20iKTsNCisJCXJldCA9IC1F SU87DQorCQlnb3RvIG91dF91bmxvY2s7DQorCX0NCisNCisJc3Jfd3JpdGVfcmVnKGRldiwgRVBD UiwgMHgwKTsNCisNCitvdXRfdW5sb2NrOg0KKwltdXRleF91bmxvY2soJmRldi0+cGh5X211dGV4 KTsNCisJcmV0dXJuIHJldDsNCit9DQorDQorc3RhdGljIGludCBzcl9yZWFkX2VlcHJvbV93b3Jk KHN0cnVjdCB1c2JuZXQgKmRldiwgdTggb2Zmc2V0LCB2b2lkICp2YWx1ZSkNCit7DQorCXJldHVy biBzcl9zaGFyZV9yZWFkX3dvcmQoZGV2LCAwLCBvZmZzZXQsIHZhbHVlKTsNCit9DQorDQorc3Rh dGljIGludCBzcjk3MDBfZ2V0X2VlcHJvbV9sZW4oc3RydWN0IG5ldF9kZXZpY2UgKmRldikNCit7 DQorCXJldHVybiBTUl9FRVBST01fTEVOOw0KK30NCisNCitzdGF0aWMgaW50IHNyOTcwMF9nZXRf ZWVwcm9tKHN0cnVjdCBuZXRfZGV2aWNlICpuZXQsIHN0cnVjdCBldGh0b29sX2VlcHJvbSAqZWVw cm9tLCB1OCAqZGF0YSkNCit7DQorCXN0cnVjdCB1c2JuZXQgKmRldiA9IG5ldGRldl9wcml2KG5l dCk7DQorCV9fbGUxNiAqZWJ1ZiA9IChfX2xlMTYgKikgZGF0YTsNCisJaW50IHJldCA9IDA7DQor CWludCBpOw0KKw0KKwkvKiBhY2Nlc3MgaXMgMTZiaXQgKi8NCisJaWYgKChlZXByb20tPm9mZnNl dCAlIDIpIHx8IChlZXByb20tPmxlbiAlIDIpKQ0KKwkJcmV0dXJuIC1FSU5WQUw7DQorDQorCWZv ciAoaSA9IDA7IGkgPCBlZXByb20tPmxlbiAvIDI7IGkrKykNCisJCQlyZXQgPSBzcl9yZWFkX2Vl cHJvbV93b3JkKGRldiwgZWVwcm9tLT5vZmZzZXQgLyAyICsgaSwgJmVidWZbaV0pOw0KKw0KKwly ZXR1cm4gcmV0Ow0KK30NCisNCitzdGF0aWMgaW50IHNyX21kaW9fcmVhZChzdHJ1Y3QgbmV0X2Rl dmljZSAqbmV0ZGV2LCBpbnQgcGh5X2lkLCBpbnQgbG9jKQ0KK3sNCisJc3RydWN0IHVzYm5ldCAq ZGV2ID0gbmV0ZGV2X3ByaXYobmV0ZGV2KTsNCisJX19sZTE2IHJlczsNCisJaW50IHJjID0gMDsN CisNCisJaWYgKHBoeV9pZCkgew0KKwkJbmV0ZGV2X2RiZyhkZXYtPm5ldCwgIk9ubHkgaW50ZXJu YWwgcGh5IHN1cHBvcnRlZFxuIik7DQorCQlyZXR1cm4gMDsNCisJfQ0KKw0KKwkvKiBBY2Nlc3Mg TlNSX0xJTktTVCBiaXQgZm9yIGxpbmsgc3RhdHVzIGluc3RlYWQgb2YgTUlJX0JNU1IgKi8NCisJ aWYgKGxvYyA9PSBNSUlfQk1TUikgew0KKwkJCXU4IHZhbHVlOw0KKw0KKwkJCXNyX3JlYWRfcmVn KGRldiwgTlNSLCAmdmFsdWUpOw0KKwkJCWlmICh2YWx1ZSAmIE5TUl9MSU5LU1QpDQorCQkJCQly YyA9IDE7DQorCX0NCisJc3Jfc2hhcmVfcmVhZF93b3JkKGRldiwgMSwgbG9jLCAmcmVzKTsNCisJ aWYgKHJjID09IDEpDQorCQkJcmV0dXJuIGxlMTZfdG9fY3B1KHJlcykgfCBCTVNSX0xTVEFUVVM7 DQorCWVsc2UNCisJCQlyZXR1cm4gbGUxNl90b19jcHUocmVzKSAmIH5CTVNSX0xTVEFUVVM7DQor DQorCW5ldGRldl9kYmcoZGV2LT5uZXQsDQorCSAgICAgICAic3JfbWRpb19yZWFkKCkgcGh5X2lk PTB4JTAyeCwgbG9jPTB4JTAyeCwgcmV0dXJucz0weCUwNHhcbiIsDQorCSAgICAgICBwaHlfaWQs IGxvYywgbGUxNl90b19jcHUocmVzKSk7DQorDQorCXJldHVybiBsZTE2X3RvX2NwdShyZXMpOw0K K30NCisNCitzdGF0aWMgdm9pZCBzcl9tZGlvX3dyaXRlKHN0cnVjdCBuZXRfZGV2aWNlICpuZXRk ZXYsIGludCBwaHlfaWQsIGludCBsb2MsIGludCB2YWwpDQorew0KKwlzdHJ1Y3QgdXNibmV0ICpk ZXYgPSBuZXRkZXZfcHJpdihuZXRkZXYpOw0KKwlfX2xlMTYgcmVzID0gY3B1X3RvX2xlMTYodmFs KTsNCisNCisJaWYgKHBoeV9pZCkgew0KKwkJbmV0ZGV2X2RiZyhkZXYtPm5ldCwgIk9ubHkgaW50 ZXJuYWwgcGh5IHN1cHBvcnRlZFxuIik7DQorCQlyZXR1cm47DQorCX0NCisNCisJbmV0ZGV2X2Ri ZyhkZXYtPm5ldCwgInNyX21kaW9fd3JpdGUoKSBwaHlfaWQ9MHglMDJ4LCBsb2M9MHglMDJ4LCB2 YWw9MHglMDR4XG4iLA0KKwkgICAgICAgcGh5X2lkLCBsb2MsIHZhbCk7DQorDQorCXNyX3NoYXJl X3dyaXRlX3dvcmQoZGV2LCAxLCBsb2MsIHJlcyk7DQorfQ0KKw0KK3N0YXRpYyB1MzIgc3I5NzAw X2dldF9saW5rKHN0cnVjdCBuZXRfZGV2aWNlICpuZXQpDQorew0KKwlzdHJ1Y3QgdXNibmV0ICpk ZXYgPSBuZXRkZXZfcHJpdihuZXQpOw0KKwlpbnQgcmMgPSAwOw0KKwl1OCB2YWx1ZSA9IDA7DQor DQorCS8qIEdldCB0aGUgTGluayBTdGF0dXMgZGlyZWN0bHkgKi8NCisJc3JfcmVhZF9yZWcoZGV2 LCBOU1IsICZ2YWx1ZSk7DQorCWlmICh2YWx1ZSAmIE5TUl9MSU5LU1QpDQorCQlyYyA9IDE7DQor DQorCXJldHVybiByYzsNCit9DQorDQorc3RhdGljIGludCBzcjk3MDBfaW9jdGwoc3RydWN0IG5l dF9kZXZpY2UgKm5ldCwgc3RydWN0IGlmcmVxICpycSwgaW50IGNtZCkNCit7DQorCXN0cnVjdCB1 c2JuZXQgKmRldiA9IG5ldGRldl9wcml2KG5ldCk7DQorDQorCXJldHVybiBnZW5lcmljX21paV9p b2N0bCgmZGV2LT5taWksIGlmX21paShycSksIGNtZCwgTlVMTCk7DQorfQ0KKw0KK3N0YXRpYyBj b25zdCBzdHJ1Y3QgZXRodG9vbF9vcHMgc3I5NzAwX2V0aHRvb2xfb3BzID0gew0KKwkuZ2V0X2Ry dmluZm8JPSB1c2JuZXRfZ2V0X2RydmluZm8sDQorCS5nZXRfbGluawkJPSBzcjk3MDBfZ2V0X2xp bmssDQorCS5nZXRfbXNnbGV2ZWwJPSB1c2JuZXRfZ2V0X21zZ2xldmVsLA0KKwkuc2V0X21zZ2xl dmVsCT0gdXNibmV0X3NldF9tc2dsZXZlbCwNCisJLmdldF9lZXByb21fbGVuCT0gc3I5NzAwX2dl dF9lZXByb21fbGVuLA0KKwkuZ2V0X2VlcHJvbQkJPSBzcjk3MDBfZ2V0X2VlcHJvbSwNCisJLmdl dF9zZXR0aW5ncwk9IHVzYm5ldF9nZXRfc2V0dGluZ3MsDQorCS5zZXRfc2V0dGluZ3MJPSB1c2Ju ZXRfc2V0X3NldHRpbmdzLA0KKwkubndheV9yZXNldAkJPSB1c2JuZXRfbndheV9yZXNldCwNCit9 Ow0KKw0KK3N0YXRpYyB2b2lkIHNyOTcwMF9zZXRfbXVsdGljYXN0KHN0cnVjdCBuZXRfZGV2aWNl ICpuZXQpDQorew0KKwlzdHJ1Y3QgdXNibmV0ICpkZXYgPSBuZXRkZXZfcHJpdihuZXQpOw0KKwkv KiBXZSB1c2UgdGhlIDIwIGJ5dGUgZGV2LT5kYXRhIGZvciBvdXIgOCBieXRlIGZpbHRlciBidWZm ZXINCisJICogdG8gYXZvaWQgYWxsb2NhdGluZyBtZW1vcnkgdGhhdCBpcyB0cmlja3kgdG8gZnJl ZSBsYXRlcg0KKwkgKi8NCisJdTggKmhhc2hlcyA9ICh1OCAqKSAmZGV2LT5kYXRhOw0KKwkvKiBy eF9jdGwgc2V0dGluZyA6IGVuYWJsZSwgZGlzYWJsZV9sb25nLCBkaXNhYmxlX2NyYyAqLw0KKwl1 OCByeF9jdGwgPSBSQ1JfUlhFTiB8IFJDUl9ESVNfQ1JDIHwgUkNSX0RJU19MT05HOw0KKw0KKwlt ZW1zZXQoaGFzaGVzLCAweDAwLCBTUl9NQ0FTVF9TSVpFKTsNCisJaGFzaGVzW1NSX01DQVNUX1NJ WkUgLSAxXSB8PSBTUl9NQ0FTVF9BRERSX0ZMQUc7CS8qIGJyb2FkY2FzdCBhZGRyZXNzICovDQor DQorCWlmIChuZXQtPmZsYWdzICYgSUZGX1BST01JU0MpIHsNCisJCQlyeF9jdGwgfD0gUkNSX1BS TVNDOw0KKwl9IGVsc2UgaWYgKG5ldC0+ZmxhZ3MgJiBJRkZfQUxMTVVMVEkgfHwNCisJCQkJCW5l dGRldl9tY19jb3VudChuZXQpID4gU1JfTUNBU1RfTUFYKSB7DQorCQkJcnhfY3RsIHw9IFJDUl9S VU5UOw0KKwl9IGVsc2UgaWYgKCFuZXRkZXZfbWNfZW1wdHkobmV0KSkgew0KKwkJCXN0cnVjdCBu ZXRkZXZfaHdfYWRkciAqaGE7DQorCQkJbmV0ZGV2X2Zvcl9lYWNoX21jX2FkZHIoaGEsIG5ldCkg ew0KKwkJCQkJdTMyIGNyYyA9IGV0aGVyX2NyYyhFVEhfQUxFTiwgaGEtPmFkZHIpID4+IDI2Ow0K KwkJCQkJaGFzaGVzW2NyYyA+PiAzXSB8PSAxIDw8IChjcmMgJiAweDcpOw0KKwkJCX0NCisJfQ0K Kw0KKwlzcl93cml0ZV9hc3luYyhkZXYsIE1BUiwgU1JfTUNBU1RfU0laRSwgaGFzaGVzKTsNCisJ c3Jfd3JpdGVfcmVnX2FzeW5jKGRldiwgUkNSLCByeF9jdGwpOw0KK30NCisNCitzdGF0aWMgaW50 IHNyOTcwMF9zZXRfbWFjX2FkZHJlc3Moc3RydWN0IG5ldF9kZXZpY2UgKm5ldCwgdm9pZCAqcCkN Cit7DQorCXN0cnVjdCBzb2NrYWRkciAqYWRkciA9IHA7DQorCXN0cnVjdCB1c2JuZXQgKmRldiA9 IG5ldGRldl9wcml2KG5ldCk7DQorDQorCWlmICghaXNfdmFsaWRfZXRoZXJfYWRkcihhZGRyLT5z YV9kYXRhKSkgew0KKwkJbmV0ZGV2X2VycihuZXQsICJub3Qgc2V0dGluZyBpbnZhbGlkIG1hYyBh ZGRyZXNzICVwTVxuIiwNCisJCQkJCQlhZGRyLT5zYV9kYXRhKTsNCisJCXJldHVybiAtRUlOVkFM Ow0KKwl9DQorDQorCW1lbWNweShuZXQtPmRldl9hZGRyLCBhZGRyLT5zYV9kYXRhLCBuZXQtPmFk ZHJfbGVuKTsNCisJc3Jfd3JpdGVfYXN5bmMoZGV2LCBQQVIsIDYsIGRldi0+bmV0LT5kZXZfYWRk cik7DQorDQorCXJldHVybiAwOw0KK30NCisNCitzdGF0aWMgY29uc3Qgc3RydWN0IG5ldF9kZXZp Y2Vfb3BzIHNyOTcwMF9uZXRkZXZfb3BzID0gew0KKwkubmRvX29wZW4JCQk9IHVzYm5ldF9vcGVu LA0KKwkubmRvX3N0b3AJCQk9IHVzYm5ldF9zdG9wLA0KKwkubmRvX3N0YXJ0X3htaXQJCT0gdXNi bmV0X3N0YXJ0X3htaXQsDQorCS5uZG9fdHhfdGltZW91dAkJPSB1c2JuZXRfdHhfdGltZW91dCwN CisJLm5kb19jaGFuZ2VfbXR1CQk9IHVzYm5ldF9jaGFuZ2VfbXR1LA0KKwkubmRvX3ZhbGlkYXRl X2FkZHIJPSBldGhfdmFsaWRhdGVfYWRkciwNCisJLm5kb19kb19pb2N0bAkJPSBzcjk3MDBfaW9j dGwsDQorCS5uZG9fc2V0X3J4X21vZGUJPSBzcjk3MDBfc2V0X211bHRpY2FzdCwNCisJLm5kb19z ZXRfbWFjX2FkZHJlc3MJPSBzcjk3MDBfc2V0X21hY19hZGRyZXNzLA0KK307DQorDQorc3RhdGlj IGludCBzcjk3MDBfYmluZChzdHJ1Y3QgdXNibmV0ICpkZXYsIHN0cnVjdCB1c2JfaW50ZXJmYWNl ICppbnRmKQ0KK3sNCisJaW50IHJldDsNCisNCisJcmV0ID0gdXNibmV0X2dldF9lbmRwb2ludHMo ZGV2LCBpbnRmKTsNCisJaWYgKHJldCkNCisJCWdvdG8gb3V0Ow0KKw0KKwlkZXYtPm5ldC0+bmV0 ZGV2X29wcyA9ICZzcjk3MDBfbmV0ZGV2X29wczsNCisJZGV2LT5uZXQtPmV0aHRvb2xfb3BzID0g JnNyOTcwMF9ldGh0b29sX29wczsNCisJZGV2LT5uZXQtPmhhcmRfaGVhZGVyX2xlbiArPSBTUl9U WF9PVkVSSEVBRDsNCisJZGV2LT5oYXJkX210dSA9IGRldi0+bmV0LT5tdHUgKyBkZXYtPm5ldC0+ aGFyZF9oZWFkZXJfbGVuOw0KKwlkZXYtPnJ4X3VyYl9zaXplID0gMzA3MjsJLyogYnVsa2luIGJ1 ZmZlciBpcyBwcmVmZXJhYmx5IG5vdCBsZXNzIHRoYW4gM0sgKi8NCisNCisJZGV2LT5taWkuZGV2 ID0gZGV2LT5uZXQ7DQorCWRldi0+bWlpLm1kaW9fcmVhZCA9IHNyX21kaW9fcmVhZDsNCisJZGV2 LT5taWkubWRpb193cml0ZSA9IHNyX21kaW9fd3JpdGU7DQorCWRldi0+bWlpLnBoeV9pZF9tYXNr ID0gMHgxZjsNCisJZGV2LT5taWkucmVnX251bV9tYXNrID0gMHgxZjsNCisNCisJLyogcmVzZXQg dGhlIHNyOTcwMCAqLw0KKwlzcl93cml0ZV9yZWcoZGV2LCBOQ1IsIDEpOw0KKwl1ZGVsYXkoMjAp Ow0KKw0KKwkvKiByZWFkIE1BQw0KKwkgKiBBZnRlciBDaGlwIFBvd2VyIG9uLCB0aGUgQ2hpcCB3 aWxsIHJlbG9hZCB0aGUgTUFDIGZyb20gRUVQUk9NIGF1dG9tYXRpY2FsbHkgdG8gUEFSDQorCSAq IEluIGNhc2UgdGhlcmUgaXMgbm8gRUVQUk9NIGV4dGVybmFsbHksIGEgZGVmYXVsdCBNQUMgYWRk cmVzcyBpcyBzdG9yZWQgaW4gUEFSIGZvciBtYWtpbmcgY2hpcCB3b3JrIHByb3Blcmx5DQorCSAq Lw0KKwlpZiAoc3JfcmVhZChkZXYsIFBBUiwgRVRIX0FMRU4sIGRldi0+bmV0LT5kZXZfYWRkcikg PCAwKSB7DQorCQluZXRkZXZfZXJyKGRldi0+bmV0LCAiRXJyb3IgcmVhZGluZyBNQUMgYWRkcmVz c1xuIik7DQorCQlyZXQgPSAtRU5PREVWOw0KKwkJZ290byBvdXQ7DQorCX0NCisNCisJLyogcG93 ZXIgdXAgYW5kIHJlc2V0IHBoeSAqLw0KKwlzcl93cml0ZV9yZWcoZGV2LCBQUlIsIDEpOw0KKwlt ZGVsYXkoMjApOwkJLyogYXQgbGVhc3QgMTBtcywgaGVyZSAyMG1zIGZvciBzYWZlICovDQorCXNy X3dyaXRlX3JlZyhkZXYsIFBSUiwgMCk7DQorCXVkZWxheSgyICogMTAwMCk7CS8qIGF0IGxlYXN0 IDFtcywgaGVyZSAybXMgZm9yIHJlYWRpbmcgcmlnaHQgcmVnaXN0ZXIgKi8NCisNCisJLyogcmVj ZWl2ZSBicm9hZGNhc3QgcGFja2V0cyAqLw0KKwlzcjk3MDBfc2V0X211bHRpY2FzdChkZXYtPm5l dCk7DQorDQorCXNyX21kaW9fd3JpdGUoZGV2LT5uZXQsIGRldi0+bWlpLnBoeV9pZCwgTUlJX0JN Q1IsIEJNQ1JfUkVTRVQpOw0KKwlzcl9tZGlvX3dyaXRlKGRldi0+bmV0LCBkZXYtPm1paS5waHlf aWQsIE1JSV9BRFZFUlRJU0UsIEFEVkVSVElTRV9BTEwgfCBBRFZFUlRJU0VfQ1NNQSB8IEFEVkVS VElTRV9QQVVTRV9DQVApOw0KKwltaWlfbndheV9yZXN0YXJ0KCZkZXYtPm1paSk7DQorDQorb3V0 Og0KKwlyZXR1cm4gcmV0Ow0KK30NCisNCitzdGF0aWMgaW50IHNyOTcwMF9yeF9maXh1cChzdHJ1 Y3QgdXNibmV0ICpkZXYsIHN0cnVjdCBza19idWZmICpza2IpDQorew0KKwlpbnQgbGVuOw0KKwlz dHJ1Y3Qgc2tfYnVmZiAqc3Jfc2tiOw0KKw0KKwkvKiBmb3JtYXQ6DQorCSAgIGIwOiByeCBzdGF0 dXMNCisJICAgYjE6IHBhY2tldCBsZW5ndGggKGluY2wgY3JjKSBsb3cNCisJICAgYjI6IHBhY2tl dCBsZW5ndGggKGluY2wgY3JjKSBoaWdoDQorCSAgIGIzLi5uLTQ6IHBhY2tldCBkYXRhDQorCSAg IGJuLTMuLmJuOiBldGhlcm5ldCBjcmMNCisJICovDQorDQorCWlmICh1bmxpa2VseShza2ItPmxl biA8IFNSX1JYX09WRVJIRUFEKSkgew0KKwkJbmV0ZGV2X2VycihkZXYtPm5ldCwgInVuZXhwZWN0 ZWQgdGlueSByeCBmcmFtZVxuIik7DQorCQlyZXR1cm4gMDsNCisJfQ0KKw0KKwkvKiBFYWNoIHBh Y2tldCBjb250YWlucyBtdWx0aXBsZSBza2JzICovDQorCXdoaWxlIChza2ItPmxlbiA+IFNSX1JY X09WRVJIRUFEKSB7DQorCQlpZiAoc2tiLT5kYXRhWzBdICE9IDB4NDApDQorCQkJcmV0dXJuIDA7 DQorDQorCQkvKiBpZ25vcmUgdGhlIENSQyBsZW5ndGggKi8NCisJCWxlbiA9IChza2ItPmRhdGFb MV0gfCAoc2tiLT5kYXRhWzJdIDw8IDgpKSAtIDQ7DQorDQorCQlpZiAobGVuID4gRVRIX0ZSQU1F X0xFTikNCisJCQlyZXR1cm4gMDsNCisNCisJCS8qIHRoZSBsYXN0IHNrYiBvZiBjdXJyZW50IHBh Y2tldCAqLw0KKwkJaWYgKHNrYi0+bGVuID09IChsZW4gKyBTUl9SWF9PVkVSSEVBRCkpCXsNCisJ CQlza2JfcHVsbChza2IsIDMpOw0KKwkJCXNrYi0+bGVuID0gbGVuOw0KKwkJCXNrYi0+dGFpbCA9 IHNrYi0+ZGF0YSArIGxlbjsNCisJCQlza2ItPnRydWVzaXplID0gbGVuICsgc2l6ZW9mKHN0cnVj dCBza19idWZmKTsNCisJCQlyZXR1cm4gMjsNCisJCX0NCisNCisJCS8qIHNrYl9jbG9uZSBpcyB1 c2VkIGZvciBhZGRyZXNzIGFsaWduICovDQorCQlzcl9za2IgPSBza2JfY2xvbmUoc2tiLCBHRlBf QVRPTUlDKTsNCisJCWlmIChzcl9za2IpIHsNCisJCQlzcl9za2ItPmxlbiA9IGxlbjsNCisJCQlz cl9za2ItPmRhdGEgPSBza2ItPmRhdGEgKyAzOw0KKwkJCXNyX3NrYi0+dGFpbCA9IHNrYi0+ZGF0 YSArIGxlbjsNCisJCQlzcl9za2ItPnRydWVzaXplID0gbGVuICsgc2l6ZW9mKHN0cnVjdCBza19i dWZmKTsNCisJCQl1c2JuZXRfc2tiX3JldHVybihkZXYsIHNyX3NrYik7DQorCQl9IGVsc2Ugew0K KwkJCXJldHVybiAwOw0KKwkJfQ0KKw0KKwkJc2tiX3B1bGwoc2tiLCBsZW4gKyBTUl9SWF9PVkVS SEVBRCk7DQorCX07DQorDQorCXJldHVybiAwOw0KK30NCisNCitzdGF0aWMgc3RydWN0IHNrX2J1 ZmYgKnNyOTcwMF90eF9maXh1cChzdHJ1Y3QgdXNibmV0ICpkZXYsIHN0cnVjdCBza19idWZmICpz a2IsIGdmcF90IGZsYWdzKQ0KK3sNCisJaW50IGxlbjsNCisNCisJLyogZm9ybWF0Og0KKwkgICBi MDogcGFja2V0IGxlbmd0aCBsb3cNCisJICAgYjE6IHBhY2tldCBsZW5ndGggaGlnaA0KKwkgICBi My4ubjogcGFja2V0IGRhdGENCisJKi8NCisNCisJbGVuID0gc2tiLT5sZW47DQorDQorCWlmIChz a2JfaGVhZHJvb20oc2tiKSA8IFNSX1RYX09WRVJIRUFEKSB7DQorCQlzdHJ1Y3Qgc2tfYnVmZiAq c2tiMjsNCisNCisJCXNrYjIgPSBza2JfY29weV9leHBhbmQoc2tiLCBTUl9UWF9PVkVSSEVBRCwg MCwgZmxhZ3MpOw0KKwkJZGV2X2tmcmVlX3NrYl9hbnkoc2tiKTsNCisJCXNrYiA9IHNrYjI7DQor CQlpZiAoIXNrYikNCisJCQlyZXR1cm4gTlVMTDsNCisJfQ0KKw0KKwlfX3NrYl9wdXNoKHNrYiwg U1JfVFhfT1ZFUkhFQUQpOw0KKw0KKwkvKiB1c2JuZXQgYWRkcyBwYWRkaW5nIGlmIGxlbmd0aCBp cyBhIG11bHRpcGxlIG9mIHBhY2tldCBzaXplDQorCSAqIGlmIHNvLCBhZGp1c3QgbGVuZ3RoIHZh bHVlIGluIGhlYWRlcg0KKwkgKi8NCisJaWYgKChza2ItPmxlbiAlIGRldi0+bWF4cGFja2V0KSA9 PSAwKQ0KKwkJbGVuKys7DQorDQorCXNrYi0+ZGF0YVswXSA9IGxlbjsNCisJc2tiLT5kYXRhWzFd ID0gbGVuID4+IDg7DQorDQorCXJldHVybiBza2I7DQorfQ0KKw0KK3N0YXRpYyB2b2lkIHNyOTcw MF9zdGF0dXMoc3RydWN0IHVzYm5ldCAqZGV2LCBzdHJ1Y3QgdXJiICp1cmIpDQorew0KKwlpbnQg bGluazsNCisJdTggKmJ1ZjsNCisNCisJLyogZm9ybWF0Og0KKwkgICBiMDogbmV0IHN0YXR1cw0K KwkgICBiMTogdHggc3RhdHVzIDENCisJICAgYjI6IHR4IHN0YXR1cyAyDQorCSAgIGIzOiByeCBz dGF0dXMNCisJICAgYjQ6IHJ4IG92ZXJmbG93DQorCSAgIGI1OiByeCBjb3VudA0KKwkgICBiNjog dHggY291bnQNCisJICAgYjc6IGdwcg0KKwkqLw0KKw0KKwlpZiAodXJiLT5hY3R1YWxfbGVuZ3Ro IDwgOCkNCisJCXJldHVybjsNCisNCisJYnVmID0gdXJiLT50cmFuc2Zlcl9idWZmZXI7DQorDQor CWxpbmsgPSAhIShidWZbMF0gJiAweDQwKTsNCisJaWYgKG5ldGlmX2NhcnJpZXJfb2soZGV2LT5u ZXQpICE9IGxpbmspIHsNCisJCXVzYm5ldF9saW5rX2NoYW5nZShkZXYsIGxpbmssIDEpOw0KKwkJ bmV0ZGV2X2RiZyhkZXYtPm5ldCwgIkxpbmsgU3RhdHVzIGlzOiAlZFxuIiwgbGluayk7DQorCX0N Cit9DQorDQorc3RhdGljIGludCBzcjk3MDBfbGlua19yZXNldChzdHJ1Y3QgdXNibmV0ICpkZXYp DQorew0KKwlzdHJ1Y3QgZXRodG9vbF9jbWQgZWNtZDsNCisNCisJbWlpX2NoZWNrX21lZGlhKCZk ZXYtPm1paSwgMSwgMSk7DQorCW1paV9ldGh0b29sX2dzZXQoJmRldi0+bWlpLCAmZWNtZCk7DQor DQorCW5ldGRldl9kYmcoZGV2LT5uZXQsICJsaW5rX3Jlc2V0KCkgc3BlZWQ6ICVkIGR1cGxleDog JWRcbiIsDQorCSAgICAgICBlY21kLnNwZWVkLCBlY21kLmR1cGxleCk7DQorDQorCXJldHVybiAw Ow0KK30NCisNCitzdGF0aWMgY29uc3Qgc3RydWN0IGRyaXZlcl9pbmZvIHNyOTcwMF9kcml2ZXJf aW5mbyA9IHsNCisJLmRlc2NyaXB0aW9uCT0gIkNvcmVDaGlwIFNSOTcwMCBVU0IgRXRoZXJuZXQi LA0KKwkuZmxhZ3MJCT0gRkxBR19FVEhFUiwNCisJLmJpbmQJCT0gc3I5NzAwX2JpbmQsDQorCS5y eF9maXh1cAk9IHNyOTcwMF9yeF9maXh1cCwNCisJLnR4X2ZpeHVwCT0gc3I5NzAwX3R4X2ZpeHVw LA0KKwkuc3RhdHVzCQk9IHNyOTcwMF9zdGF0dXMsDQorCS5saW5rX3Jlc2V0CT0gc3I5NzAwX2xp bmtfcmVzZXQsDQorCS5yZXNldAkJPSBzcjk3MDBfbGlua19yZXNldCwNCit9Ow0KKw0KK3N0YXRp YyBjb25zdCBzdHJ1Y3QgdXNiX2RldmljZV9pZCBwcm9kdWN0c1tdID0gew0KKwl7DQorCSBVU0Jf REVWSUNFKDB4MGZlNiwgMHg5NzAwKSwJLyogU1I5NzAwIGRldmljZSAqLw0KKwkgLmRyaXZlcl9p bmZvID0gKHVuc2lnbmVkIGxvbmcpJnNyOTcwMF9kcml2ZXJfaW5mbywNCisJIH0sDQorCXt9LAkJ CS8qIEVORCAqLw0KK307DQorDQorTU9EVUxFX0RFVklDRV9UQUJMRSh1c2IsIHByb2R1Y3RzKTsN CisNCitzdGF0aWMgc3RydWN0IHVzYl9kcml2ZXIgc3I5NzAwX3VzYl9kcml2ZXIgPSB7DQorCS5u YW1lID0gInNyOTcwMCIsDQorCS5pZF90YWJsZSA9IHByb2R1Y3RzLA0KKwkucHJvYmUgPSB1c2Ju ZXRfcHJvYmUsDQorCS5kaXNjb25uZWN0ID0gdXNibmV0X2Rpc2Nvbm5lY3QsDQorCS5zdXNwZW5k ID0gdXNibmV0X3N1c3BlbmQsDQorCS5yZXN1bWUgPSB1c2JuZXRfcmVzdW1lLA0KKwkuZGlzYWJs ZV9odWJfaW5pdGlhdGVkX2xwbSA9IDEsDQorfTsNCisNCittb2R1bGVfdXNiX2RyaXZlcihzcjk3 MDBfdXNiX2RyaXZlcik7DQorDQorTU9EVUxFX0FVVEhPUigibGl1amwgPGxpdWp1bmxpYW5nX2xq bEAxNjMuY29tPiIpOw0KK01PRFVMRV9ERVNDUklQVElPTigiU1I5NzAwIG9uZSBjaGlwIFVTQiAx LjEgVVNCIHRvIEV0aGVybmV0IGRldmljZSBmcm9tIGh0dHA6Ly93d3cuY29yZWNoaXAtc3ouY29t LyIpOw0KK01PRFVMRV9MSUNFTlNFKCJHUEwiKTsNCmRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC91 c2Ivc3I5NzAwLmggYi9kcml2ZXJzL25ldC91c2Ivc3I5NzAwLmgNCm5ldyBmaWxlIG1vZGUgMTAw NjQ0DQppbmRleCAwMDAwMDAwLi5mMTk2OGFlDQotLS0gL2Rldi9udWxsDQorKysgYi9kcml2ZXJz L25ldC91c2Ivc3I5NzAwLmgNCkBAIC0wLDAgKzEsMTcyIEBADQorLyoNCisgKiBDb3JlQ2hpcC1z eiBTUjk3MDAgb25lIGNoaXAgVVNCIDEuMSBFdGhlcm5ldCBEZXZpY2VzDQorICoNCisgKiBBdXRo b3IgOiBsaXVqbCA8bGl1anVubGlhbmdfbGpsQDE2My5jb20+DQorICoNCisgKiBUaGlzIHByb2dy YW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yDQorICog bW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vu c2UNCisgKiB2ZXJzaW9uIDIgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5k YXRpb24uDQorICovDQorDQorI2lmbmRlZiBfU1I5NzAwX0gNCisjZGVmaW5lCV9TUjk3MDBfSA0K Kw0KKy8qIHNyOTcwMCBzcGVjLiByZWdpc3RlciB0YWJsZSBvbiBMaW51eCBwbGF0Zm9ybSAqLw0K Kw0KKy8qIE5ldHdvcmsgQ29udHJvbCBSZWcgKi8NCisjZGVmaW5lCU5DUgkJCTB4MDANCisjZGVm aW5lCQlOQ1JfUlNUCQkJKDEgPDwgMCkNCisjZGVmaW5lCQlOQ1JfTEJLCQkJKDMgPDwgMSkNCisj ZGVmaW5lCQlOQ1JfRkRYCQkJKDEgPDwgMykNCisjZGVmaW5lCQlOQ1JfV0FLRUVOCQkoMSA8PCA2 KQ0KKy8qIE5ldHdvcmsgU3RhdHVzIFJlZyAqLw0KKyNkZWZpbmUJTlNSCQkJMHgwMQ0KKyNkZWZp bmUJCU5TUl9SWFJEWQkJKDEgPDwgMCkNCisjZGVmaW5lCQlOU1JfUlhPVgkJKDEgPDwgMSkNCisj ZGVmaW5lCQlOU1JfVFgxRU5ECQkoMSA8PCAyKQ0KKyNkZWZpbmUJCU5TUl9UWDJFTkQJCSgxIDw8 IDMpDQorI2RlZmluZQkJTlNSX1RYRlVMTAkJKDEgPDwgNCkNCisjZGVmaW5lCQlOU1JfV0FLRVNU CQkoMSA8PCA1KQ0KKyNkZWZpbmUJCU5TUl9MSU5LU1QJCSgxIDw8IDYpDQorI2RlZmluZQkJTlNS X1NQRUVECQkoMSA8PCA3KQ0KKy8qIFR4IENvbnRyb2wgUmVnICovDQorI2RlZmluZQlUQ1IJCQkw eDAyDQorI2RlZmluZQkJVENSX0NSQ19ESVMJCSgxIDw8IDEpDQorI2RlZmluZQkJVENSX1BBRF9E SVMJCSgxIDw8IDIpDQorI2RlZmluZQkJVENSX0xDX0NBUkUJCSgxIDw8IDMpDQorI2RlZmluZQkJ VENSX0NSU19DQVJFCSgxIDw8IDQpDQorI2RlZmluZQkJVENSX0VYQ0VDTQkJKDEgPDwgNSkNCisj ZGVmaW5lCQlUQ1JfTEZfRU4JCSgxIDw8IDYpDQorLyogVHggU3RhdHVzIFJlZyBmb3IgUGFja2V0 IEluZGV4IDEgKi8NCisjZGVmaW5lCVRTUjEJCTB4MDMNCisjZGVmaW5lCQlUU1IxX0VDCQkJKDEg PDwgMikNCisjZGVmaW5lCQlUU1IxX0NPTAkJKDEgPDwgMykNCisjZGVmaW5lCQlUU1IxX0xDCQkJ KDEgPDwgNCkNCisjZGVmaW5lCQlUU1IxX05DCQkJKDEgPDwgNSkNCisjZGVmaW5lCQlUU1IxX0xP QwkJKDEgPDwgNikNCisjZGVmaW5lCQlUU1IxX1RMRgkJKDEgPDwgNykNCisvKiBUeCBTdGF0dXMg UmVnIGZvciBQYWNrZXQgSW5kZXggMiAqLw0KKyNkZWZpbmUJVFNSMgkJMHgwNA0KKyNkZWZpbmUJ CVRTUjJfRUMJCQkoMSA8PCAyKQ0KKyNkZWZpbmUJCVRTUjJfQ09MCQkoMSA8PCAzKQ0KKyNkZWZp bmUJCVRTUjJfTEMJCQkoMSA8PCA0KQ0KKyNkZWZpbmUJCVRTUjJfTkMJCQkoMSA8PCA1KQ0KKyNk ZWZpbmUJCVRTUjJfTE9DCQkoMSA8PCA2KQ0KKyNkZWZpbmUJCVRTUjJfVExGCQkoMSA8PCA3KQ0K Ky8qIFJ4IENvbnRyb2wgUmVnKi8NCisjZGVmaW5lCVJDUgkJCTB4MDUNCisjZGVmaW5lCQlSQ1Jf UlhFTgkJKDEgPDwgMCkNCisjZGVmaW5lCQlSQ1JfUFJNU0MJCSgxIDw8IDEpDQorI2RlZmluZQkJ UkNSX1JVTlQJCSgxIDw8IDIpDQorI2RlZmluZQkJUkNSX0FMTAkJCSgxIDw8IDMpDQorI2RlZmlu ZQkJUkNSX0RJU19DUkMJCSgxIDw8IDQpDQorI2RlZmluZQkJUkNSX0RJU19MT05HCSgxIDw8IDUp DQorLyogUnggU3RhdHVzIFJlZyAqLw0KKyNkZWZpbmUJUlNSCQkJMHgwNg0KKyNkZWZpbmUJCVJT Ul9BRQkJCSgxIDw8IDIpDQorI2RlZmluZQkJUlNSX01GCQkJKDEgPDwgNikNCisjZGVmaW5lCQlS U1JfUkYJCQkoMSA8PCA3KQ0KKy8qIFJ4IE92ZXJmbG93IENvdW50ZXIgUmVnICovDQorI2RlZmlu ZQlST0NSCQkweDA3DQorI2RlZmluZQkJUk9DUl9ST0MJCSgweDdGIDw8IDApDQorI2RlZmluZQkJ Uk9DUl9SWEZVCQkoMSA8PCA3KQ0KKy8qIEJhY2sgUHJlc3N1cmUgVGhyZXNob2xkIFJlZyAqLw0K KyNkZWZpbmUJQlBUUgkJMHgwOA0KKyNkZWZpbmUJCUJQVFJfSlBUCQkoMHgwRiA8PCAwKQ0KKyNk ZWZpbmUJCUJQVFJfQlBIVwkJKDB4MEYgPDwgNCkNCisvKiBGbG93IENvbnRyb2wgVGhyZXNob2xk IFJlZyAqLw0KKyNkZWZpbmUJRkNUUgkJMHgwOQ0KKyNkZWZpbmUJCUZDVFJfTFdPVAkJKDB4MEYg PDwgMCkNCisjZGVmaW5lCQlGQ1RSX0hXT1QJCSgweDBGIDw8IDQpDQorLyogcngvdHggRmxvdyBD b250cm9sIFJlZyAqLw0KKyNkZWZpbmUJRkNSCQkJMHgwQQ0KKyNkZWZpbmUJCUZDUl9GTENFCQko MSA8PCAwKQ0KKyNkZWZpbmUJCUZDUl9CS1BBCQkoMSA8PCA0KQ0KKyNkZWZpbmUJCUZDUl9UWFBF TgkJKDEgPDwgNSkNCisjZGVmaW5lCQlGQ1JfVFhQRgkJKDEgPDwgNikNCisjZGVmaW5lCQlGQ1Jf VFhQMAkJKDEgPDwgNykNCisvKiBFZXByb20gJiBQaHkgQ29udHJvbCBSZWcgKi8NCisjZGVmaW5l CUVQQ1IJCTB4MEINCisjZGVmaW5lCQlFUENSX0VSUkUJCSgxIDw8IDApDQorI2RlZmluZQkJRVBD Ul9FUlBSVwkJKDEgPDwgMSkNCisjZGVmaW5lCQlFUENSX0VSUFJSCQkoMSA8PCAyKQ0KKyNkZWZp bmUJCUVQQ1JfRVBPUwkJKDEgPDwgMykNCisjZGVmaW5lCQlFUENSX1dFUAkJKDEgPDwgNCkNCisv KiBFZXByb20gJiBQaHkgQWRkcmVzcyBSZWcgKi8NCisjZGVmaW5lCUVQQVIJCTB4MEMNCisjZGVm aW5lCQlFUEFSX0VST0EJCSgweDNGIDw8IDApDQorI2RlZmluZQkJRVBBUl9QSFlfQURSCSgweDAz IDw8IDYpDQorLyogRWVwcm9tICYJUGh5IERhdGEgUmVnICovDQorI2RlZmluZQlFUERSCQkweDBE CS8qIDB4MEQgfiAweDBFIGZvciBEYXRhIFJlZyBMb3cgJiBIaWdoICovDQorLyogV2FrZXVwIENv bnRyb2wgUmVnICovDQorI2RlZmluZQlXQ1IJCQkweDBGDQorI2RlZmluZQkJV0NSX01BR0lDU1QJ CSgxIDw8IDApDQorI2RlZmluZQkJV0NSX0xJTktTVAkJKDEgPDwgMikNCisjZGVmaW5lCQlXQ1Jf TUFHSUNFTgkJKDEgPDwgMykNCisjZGVmaW5lCQlXQ1JfTElOS0VOCQkoMSA8PCA1KQ0KKy8qIFBo eXNpY2FsIEFkZHJlc3MgUmVnICovDQorI2RlZmluZQlQQVIJCQkweDEwCS8qIDB4MTAgfiAweDE1 IDYgYnl0ZXMgZm9yIFBBUiAqLw0KKy8qIE11bHRpY2FzdCBBZGRyZXNzIFJlZyAqLw0KKyNkZWZp bmUJTUFSCQkJMHgxNgkvKiAweDE2IH4gMHgxRCA4IGJ5dGVzIGZvciBNQVIgKi8NCisvKiAweDFl IHVudXNlZCAqLw0KKy8qIFBoeSBSZXNldCBSZWcgKi8NCisjZGVmaW5lCVBSUgkJCTB4MUYNCisj ZGVmaW5lCQlQUlJfUEhZX1JTVAkJKDEgPDwgMCkNCisvKiBUeCBzZHJhbSBXcml0ZSBQb2ludGVy IEFkZHJlc3MgTG93ICovDQorI2RlZmluZQlUV1BBTAkJMHgyMA0KKy8qIFR4IHNkcmFtIFdyaXRl IFBvaW50ZXIgQWRkcmVzcyBIaWdoICovDQorI2RlZmluZQlUV1BBSAkJMHgyMQ0KKy8qIFR4IHNk cmFtIFJlYWQgUG9pbnRlciBBZGRyZXNzIExvdyAqLw0KKyNkZWZpbmUJVFJQQUwJCTB4MjINCisv KiBUeCBzZHJhbSBSZWFkIFBvaW50ZXIgQWRkcmVzcyBIaWdoICovDQorI2RlZmluZQlUUlBBSAkJ MHgyMw0KKy8qIFJ4IHNkcmFtIFdyaXRlIFBvaW50ZXIgQWRkcmVzcyBMb3cgKi8NCisjZGVmaW5l CVJXUEFMCQkweDI0DQorLyogUnggc2RyYW0gV3JpdGUgUG9pbnRlciBBZGRyZXNzIEhpZ2ggKi8N CisjZGVmaW5lCVJXUEFICQkweDI1DQorLyogUnggc2RyYW0gUmVhZCBQb2ludGVyIEFkZHJlc3Mg TG93ICovDQorI2RlZmluZQlSUlBBTAkJMHgyNg0KKy8qIFJ4IHNkcmFtIFJlYWQgUG9pbnRlciBB ZGRyZXNzIEhpZ2ggKi8NCisjZGVmaW5lCVJSUEFICQkweDI3DQorLyogVmVuZG9yIElEIHJlZ2lz dGVyICovDQorI2RlZmluZQlWSUQJCQkweDI4CS8qIDB4MjggfiAweDI5IDIgYnl0ZXMgZm9yIFZJ RCAqLw0KKy8qIFByb2R1Y3QgSUQgcmVnaXN0ZXIgKi8NCisjZGVmaW5lCVBJRAkJCTB4MkEJLyog MHgyQSB+IDB4MkIgMiBieXRlcyBmb3IgUElEICovDQorLyogQ0hJUCBSZXZpc2lvbiByZWdpc3Rl ciAqLw0KKyNkZWZpbmUJQ0hJUFIJCTB4MkMNCisvKiAweDJEIC0tPiAweEVGIHVudXNlZCAqLw0K Ky8qIFVTQiBEZXZpY2UgQWRkcmVzcyAqLw0KKyNkZWZpbmUJVVNCREEJCTB4RjANCisjZGVmaW5l CQlVU0JEQV9VU0JGQQkJKDB4N0YgPDwgMCkNCisvKiBSWCBwYWNrZXQgQ291bnRlciBSZWcgKi8N CisjZGVmaW5lCVJYQwkJCTB4RjENCisvKiBUeCBwYWNrZXQgQ291bnRlciAmIFVTQiBTdGF0dXMg UmVnICovDQorI2RlZmluZQlUWENfVVNCUwkweEYyDQorI2RlZmluZQkJVFhDX1VTQlNfVFhDMAkJ KDEgPDwgMCkNCisjZGVmaW5lCQlUWENfVVNCU19UWEMxCQkoMSA8PCAxKQ0KKyNkZWZpbmUJCVRY Q19VU0JTX1RYQzIJCSgxIDw8IDIpDQorI2RlZmluZQkJVFhDX1VTQlNfRVAxUkRZCQkoMSA8PCA1 KQ0KKyNkZWZpbmUJCVRYQ19VU0JTX1NVU0ZMQUcJKDEgPDwgNikNCisjZGVmaW5lCQlUWENfVVNC U19SWEZBVUxUCSgxIDw8IDcpDQorLyogVVNCIENvbnRyb2wgcmVnaXN0ZXIgKi8NCisjZGVmaW5l CVVTQkMJCTB4RjQNCisjZGVmaW5lCQlVU0JDX0VQM05BSwkJKDEgPDwgNCkNCisjZGVmaW5lCQlV U0JDX0VQM0FDSwkJKDEgPDwgNSkNCisNCisvKiBSZWdpc3RlciBhY2Nlc3MgY29tbWFuZHMgYW5k IGZsYWdzICovDQorI2RlZmluZQlTUl9SRF9SRUdTCQkweDAwDQorI2RlZmluZQlTUl9XUl9SRUdT CQkweDAxDQorI2RlZmluZQlTUl9XUl9SRUcJCTB4MDMNCisjZGVmaW5lCVNSX1JFUV9SRF9SRUcJ KFVTQl9ESVJfSU4gfCBVU0JfVFlQRV9WRU5ET1IgfCBVU0JfUkVDSVBfREVWSUNFKQ0KKyNkZWZp bmUJU1JfUkVRX1dSX1JFRwkoVVNCX0RJUl9PVVQgfCBVU0JfVFlQRV9WRU5ET1IgfCBVU0JfUkVD SVBfREVWSUNFKQ0KKw0KKy8qIHBhcmFtZXRlcnMgKi8NCisjZGVmaW5lCVNSX1NIQVJFX1RJTUVP VVQJMTAwMA0KKyNkZWZpbmUJU1JfRUVQUk9NX0xFTgkJMjU2DQorI2RlZmluZQlTUl9NQ0FTVF9T SVpFCQk4DQorI2RlZmluZQlTUl9NQ0FTVF9BRERSX0ZMQUcJMHg4MA0KKyNkZWZpbmUJU1JfTUNB U1RfTUFYCQk2NA0KKyNkZWZpbmUJU1JfVFhfT1ZFUkhFQUQJCTIJLyogMmJ5dGVzIGhlYWRlciAq Lw0KKyNkZWZpbmUJU1JfUlhfT1ZFUkhFQUQJCTcJLyogM2J5dGVzIGhlYWRlciArIDRjcmMgdGFp bCAqLw0KKw0KKyNlbmRpZgkvKiBfU1I5NzAwX0ggKi8NCg0KDQoNCjIwMTMtMDgtMjEgDQoNCg0K DQpsaXVqdW5saWFuZ19samwgDQoNCg0KDQq3orz+yMujuiBGcmFuY29pcyBSb21pZXUgDQq3osvN yrG85KO6IDIwMTMtMDgtMjEgIDA0OjQ2OjEyIA0KytW8/sjLo7ogbGl1anVubGlhbmdfbGpsIA0K s63LzaO6IGdyZWdraDsgc3VuaGVjaGVuZzsgbGludXgtdXNiOyBuZXRkZXY7IGxpbnV4LWtlcm5l bCANCtb3zOKjuiBSZTogW1BBVENILVNSOTcwMF0gTWVyZ2UgVVNCIDEuMSBFdGhlcm5ldCBBZGFw dGVyIFNSOTcwMCBEZXZpY2VEcml2ZXIgaW50byB0aGUgTGludXggS2VybmVsIA0KIA0KbGl1anVu bGlhbmdfbGpsIDxsaXVqdW5saWFuZ19samxAMTYzLmNvbT4gOg0KWy4uLl0NCj4gV2Ugd2FudCB0 byBtZXJnZSBTUjk3MDAgZGV2aWNlIGRyaXZlciBpbnRvIHRoZSBMaW51eCBLZXJuZWwuIFRoZSBm b2xsb3dpbmcNCj4gaXMgdGhlIExpbnV4IDMuMTAuNyB2ZXJzaW9uIHBhdGNoIGZvciBTUjk3MDAs IFBsZWFzZSBnaXZlIHVzIHRoZSBhc3Nlc3NtZW50DQo+IGFuZCBzdXBwb3J0Lg0KV2VsY29tZS4g R28gYWhlYWQuDQpbLi4uXQ0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvdXNiL3NyOTcwMC5j IGIvZHJpdmVycy9uZXQvdXNiL3NyOTcwMC5jDQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+IGlu ZGV4IDAwMDAwMDAuLjZhNjQyOWENCj4gLS0tIC9kZXYvbnVsbA0KPiArKysgYi9kcml2ZXJzL25l dC91c2Ivc3I5NzAwLmMNClsuLi5dDQo+ICtzdGF0aWMgaW50IHNyX3JlYWQoc3RydWN0IHVzYm5l dCAqZGV2LCB1OCByZWcsIHUxNiBsZW5ndGgsIHZvaWQgKmRhdGEpDQo+ICt7DQo+ICsgaW50IGVy cjsNCj4gKw0KPiArIGVyciA9IHVzYm5ldF9yZWFkX2NtZChkZXYsIFNSX1JEX1JFR1MsIFNSX1JF UV9SRF9SRUcsDQo+ICsgMCwgcmVnLCBkYXRhLCBsZW5ndGgpOw0KZXJyID0gdXNibmV0X3JlYWRf Y21kKGRldiwgU1JfUkRfUkVHUywgU1JfUkVRX1JEX1JFRywgMCwgcmVnLCBkYXRhLA0KICAgICAg bGVuZ3RoKTsNCj4gKyBpZihlcnIgIT0gbGVuZ3RoICYmIGVyciA+PSAwKQ0KICAgICAgICAgXl4g bWlzc2luZyBzcGFjZQ0KPiArIGVyciA9IC1FSU5WQUw7DQo+ICsgcmV0dXJuIGVycjsNCj4gK30N Cj4gKw0KPiArc3RhdGljIGludCBzcl93cml0ZShzdHJ1Y3QgdXNibmV0ICpkZXYsIHU4IHJlZywg dTE2IGxlbmd0aCwgdm9pZCAqZGF0YSkNCj4gK3sNCj4gKyBpbnQgZXJyOw0KPiArDQo+ICsgZXJy ID0gdXNibmV0X3dyaXRlX2NtZChkZXYsIFNSX1dSX1JFR1MsIFNSX1JFUV9XUl9SRUcsDQo+ICsg MCwgcmVnLCBkYXRhLCBsZW5ndGgpOw0KU2VlIGFib3ZlLg0KPiArIGlmIChlcnIgPj0gMCAmJiBl cnIgPCBsZW5ndGgpDQo+ICsgZXJyID0gLUVJTlZBTDsNCj4gKyANCj4gKyByZXR1cm4gZXJyOw0K PiArfQ0KPiArDQo+ICtzdGF0aWMgaW50IHNyX3JlYWRfcmVnKHN0cnVjdCB1c2JuZXQgKmRldiwg dTggcmVnLCB1OCAqdmFsdWUpDQo+ICt7DQo+ICsgcmV0dXJuIHNyX3JlYWQoZGV2LCByZWcsIDEs IHZhbHVlKTsNCj4gK30NCj4gKw0KPiArc3RhdGljIGludCBzcl93cml0ZV9yZWcoc3RydWN0IHVz Ym5ldCAqZGV2LCB1OCByZWcsIHU4IHZhbHVlKQ0KPiArew0KPiArIHJldHVybiB1c2JuZXRfd3Jp dGVfY21kKGRldiwgU1JfV1JfUkVHUywgU1JfUkVRX1dSX1JFRywNCj4gKyAgICAgICAgdmFsdWUs IHJlZywgTlVMTCwgMCk7DQpTaWMuDQo+ICt9DQo+ICsNCj4gK3N0YXRpYyB2b2lkIHNyX3dyaXRl X2FzeW5jKHN0cnVjdCB1c2JuZXQgKmRldiwgdTggcmVnLCB1MTYgbGVuZ3RoLCB2b2lkICpkYXRh KQ0KPiArew0KPiArIHVzYm5ldF93cml0ZV9jbWRfYXN5bmMoZGV2LCBTUl9XUl9SRUdTLCBTUl9S RVFfV1JfUkVHLA0KPiArIDAsIHJlZywgZGF0YSwgbGVuZ3RoKTsNClNpYy4NCj4gK30NCj4gKw0K PiArc3RhdGljIHZvaWQgc3Jfd3JpdGVfcmVnX2FzeW5jKHN0cnVjdCB1c2JuZXQgKmRldiwgdTgg cmVnLCB1OCB2YWx1ZSkNCj4gK3sNCj4gKyB1c2JuZXRfd3JpdGVfY21kX2FzeW5jKGRldiwgU1Jf V1JfUkVHUywgU1JfUkVRX1dSX1JFRywNCj4gKyB2YWx1ZSwgcmVnLCBOVUxMLCAwKTsNClNpYy4N Cj4gK30NCj4gKw0KPiArc3RhdGljIGludCBzcl9zaGFyZV9yZWFkX3dvcmQoc3RydWN0IHVzYm5l dCAqZGV2LCBpbnQgcGh5LCB1OCByZWcsIF9fbGUxNiAqdmFsdWUpDQo+ICt7DQo+ICsgaW50IHJl dCwgaTsNCj4gKw0KPiArIG11dGV4X2xvY2soJmRldi0+cGh5X211dGV4KTsNCj4gKw0KPiArIHNy X3dyaXRlX3JlZyhkZXYsIEVQQVIsIHBoeSA/IChyZWcgfCAweDQwKSA6IHJlZyk7DQo+ICsgc3Jf d3JpdGVfcmVnKGRldiwgRVBDUiwgcGh5ID8gMHhjIDogMHg0KTsNCj4gKw0KPiArIGZvciAoaSA9 IDA7IGkgPCBTUl9TSEFSRV9USU1FT1VUOyBpKyspIHsNCj4gKyB1OCB0bXAgPSAwOw0KPiArDQo+ ICsgdWRlbGF5KDEpOw0KPiArIHJldCA9IHNyX3JlYWRfcmVnKGRldiwgRVBDUiwgJnRtcCk7DQo+ ICsgaWYgKHJldCA8IDApDQo+ICsgZ290byBvdXQ7DQpnb3RvIG91dF91bmxvY2s7DQo+ICsNCj4g KyAvKiByZWFkeSAqLw0KPiArIGlmICgodG1wICYgMSkgPT0gMCkNCmlmICgodG1wICYgRVBDUl9F UlJFKSA9PSAwKQ0KPiArIGJyZWFrOw0KPiArIH0NCj4gKw0KPiArIGlmIChpID49IFNSX1NIQVJF X1RJTUVPVVQpIHsNCj4gKyBuZXRkZXZfZXJyKGRldi0+bmV0LCAiJXMgcmVhZCB0aW1lZCBvdXQh IiwgcGh5ID8gInBoeSIgOiAiZWVwcm9tIik7DQo+ICsgcmV0ID0gLUVJTzsNCj4gKyBnb3RvIG91 dDsNCj4gKyB9DQo+ICsNCj4gKyBzcl93cml0ZV9yZWcoZGV2LCBFUENSLCAweDApOw0KPiArIHJl dCA9IHNyX3JlYWQoZGV2LCBFUERSLCAyLCB2YWx1ZSk7DQo+ICsNCj4gKyBuZXRkZXZfZGJnKGRl di0+bmV0LCAicmVhZCBzaGFyZWQgJWQgMHglMDJ4IHJldHVybmVkIDB4JTA0eCwgJWQiLA0KPiAr ICAgICAgICBwaHksIHJlZywgKnZhbHVlLCByZXQpOw0KPiArDQo+ICsgb3V0Og0KICAgXiBwbGVh c2UgcmVtb3ZlIHNwYWNlLg0KPiArIG11dGV4X3VubG9jaygmZGV2LT5waHlfbXV0ZXgpOw0KPiAr IHJldHVybiByZXQ7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBpbnQgc3Jfc2hhcmVfd3JpdGVfd29y ZChzdHJ1Y3QgdXNibmV0ICpkZXYsIGludCBwaHksIHU4IHJlZywgX19sZTE2IHZhbHVlKQ0KPiAr ew0KPiArIGludCByZXQsIGk7DQo+ICsNCj4gKyBtdXRleF9sb2NrKCZkZXYtPnBoeV9tdXRleCk7 DQo+ICsNCj4gKyByZXQgPSBzcl93cml0ZShkZXYsIEVQRFIsIDIsICZ2YWx1ZSk7DQo+ICsgaWYg KHJldCA8IDApDQo+ICsgZ290byBvdXQ7DQo+ICsNCj4gKyBzcl93cml0ZV9yZWcoZGV2LCBFUEFS LCBwaHkgPyAocmVnIHwgMHg0MCkgOiByZWcpOw0KPiArIHNyX3dyaXRlX3JlZyhkZXYsIEVQQ1Is IHBoeSA/IDB4MWEgOiAweDEyKTsNCj4gKw0KPiArIGZvciAoaSA9IDA7IGkgPCBTUl9TSEFSRV9U SU1FT1VUOyBpKyspIHsNCj4gKyB1OCB0bXAgPSAwOw0KPiArDQo+ICsgdWRlbGF5KDEpOw0KPiAr IHJldCA9IHNyX3JlYWRfcmVnKGRldiwgRVBDUiwgJnRtcCk7DQo+ICsgaWYgKHJldCA8IDApDQo+ ICsgZ290byBvdXQ7DQo+ICsNCj4gKyAvKiByZWFkeSAqLw0KPiArIGlmICgodG1wICYgMSkgPT0g MCkNCj4gKyBicmVhazsNCj4gKyB9DQpUaGUgMTEgbGluZXMgYWJvdmUgYXJlIGlkZW50aWNhbCBp biBzcl9zaGFyZV9yZWFkX3dvcmQuIFBsZWFzZSByZWZhY3Rvci4NClsuLi5dDQo+ICtzdGF0aWMg aW50IHNyX21kaW9fcmVhZChzdHJ1Y3QgbmV0X2RldmljZSAqbmV0ZGV2LCBpbnQgcGh5X2lkLCBp bnQgbG9jKQ0KPiArew0KPiArIHN0cnVjdCB1c2JuZXQgKmRldiA9IG5ldGRldl9wcml2KG5ldGRl dik7DQo+ICsNCj4gKyBfX2xlMTYgcmVzOw0KRXhjZXNzIGVtcHR5IGxpbmUuDQo+ICsgaW50IHJj ID0gMDsNCj4gKw0KPiArIGlmIChwaHlfaWQpIHsNCj4gKyBuZXRkZXZfZGJnKGRldi0+bmV0LCAi T25seSBpbnRlcm5hbCBwaHkgc3VwcG9ydGVkIik7DQo+ICsgcmV0dXJuIDA7DQo+ICsgfQ0KPiAr DQo+ICsgLyogQWNjZXNzIE5TUl9MSU5LU1QgYml0IGZvciBsaW5rIHN0YXR1cyBpbnN0ZWFkIG9m IE1JSV9CTVNSICovDQo+ICsgaWYobG9jID09IE1JSV9CTVNSKXsNCiAgICAgICAgIF5eICAgICAg ICAgICAgICAgXl4NCk1pc3Npbmcgc3BhY2VzLg0KPiArIHU4IHZhbHVlOw0KRXhjZXNzIHRhYnMg YW5kIG1pc3NpbmcgZW1wdHkgbGluZS4NCj4gKyBzcl9yZWFkX3JlZyhkZXYsIE5TUiwgJnZhbHVl KTsNCj4gKyBpZih2YWx1ZSAmIE5TUl9MSU5LU1QpIHsNCkV4Y2VzcyB0YWJzLCBtaXNzaW5nIHNw YWNlcywgdXNlbGVzcyAieyIuDQo+ICsgcmMgPSAxOw0KPiArIH0NCj4gKyB9DQo+ICsgc3Jfc2hh cmVfcmVhZF93b3JkKGRldiwgMSwgbG9jLCAmcmVzKTsNCj4gKyBpZihyYyA9PSAxKQ0KPiArIHJl dHVybiAobGUxNl90b19jcHUocmVzKSB8IEJNU1JfTFNUQVRVUyk7DQo+ICsgZWxzZQ0KPiArIHJl dHVybiAobGUxNl90b19jcHUocmVzKSAmIH5CTVNSX0xTVEFUVVMpOw0KRXhjZXNzICIoIiAoYWth ICJyZXR1cm4gaXMgbm90IGEgZnVuY3Rpb24iKS4NClsuLi5dDQo+ICsvKi0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KSnVzdCBzYXkgbm8uDQpbLi4uXQ0KPiArc3RhdGljIHZv aWQgc3I5NzAwX3NldF9tdWx0aWNhc3Qoc3RydWN0IG5ldF9kZXZpY2UgKm5ldCkNCj4gK3sNCj4g KyBzdHJ1Y3QgdXNibmV0ICpkZXYgPSBuZXRkZXZfcHJpdihuZXQpOw0KPiArIC8qIFdlIHVzZSB0 aGUgMjAgYnl0ZSBkZXYtPmRhdGEgZm9yIG91ciA4IGJ5dGUgZmlsdGVyIGJ1ZmZlcg0KPiArICAq IHRvIGF2b2lkIGFsbG9jYXRpbmcgbWVtb3J5IHRoYXQgaXMgdHJpY2t5IHRvIGZyZWUgbGF0ZXIg Ki8NCj4gKyB1OCAqaGFzaGVzID0gKHU4ICopICYgZGV2LT5kYXRhOw0KICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBeZXh0cmFuZW91cyBzcGFjZQ0KPiArIHU4IHJ4X2N0bCA9IDB4MzE7IC8v IGVuYWJsZSwgZGlzYWJsZV9sb25nLCBkaXNhYmxlX2NyYw0KdTggcnhfY3RsID0gUkNSX0FMTCB8 IFJDUl9ESVNfQ1JDIHwgUkNSX0RJU19MT05HOw0KPiArDQo+ICsgbWVtc2V0KGhhc2hlcywgMHgw MCwgU1JfTUNBU1RfU0laRSk7DQo+ICsgaGFzaGVzW1NSX01DQVNUX1NJWkUgLSAxXSB8PSAweDgw OyAvKiBicm9hZGNhc3QgYWRkcmVzcyAqLw0KVXNlICNkZWZpbmUuDQo+ICsNCj4gKyAgICAgICAg aWYgKG5ldC0+ZmxhZ3MgJiBJRkZfUFJPTUlTQykgew0KICAgXl5eXl5eXl4gc2hvdWxkIHVzZSB0 YWIsIG5vdCBzcGFjZQ0KPiArICAgICAgICAgICAgICAgIHJ4X2N0bCB8PSAweDAyOw0KICAgXl5e Li4uIHNpYw0KPiArICAgICAgICB9IGVsc2UgaWYgKG5ldC0+ZmxhZ3MgJiBJRkZfQUxMTVVMVEkg fHwNCj4gKyAgICAgICAgICAgICAgICAgICBuZXRkZXZfbWNfY291bnQobmV0KSA+IFNSX01DQVNU X01BWCkgew0KPiArICAgICAgICAgICAgICAgIHJ4X2N0bCB8PSAweDA0Ow0KPiArICAgICAgICB9 IGVsc2UgaWYgKCFuZXRkZXZfbWNfZW1wdHkobmV0KSkgew0KPiArICAgICAgICAgICAgICAgIHN0 cnVjdCBuZXRkZXZfaHdfYWRkciAqaGE7DQo+ICsgDQo+ICsgICAgICAgICAgICAgICAgbmV0ZGV2 X2Zvcl9lYWNoX21jX2FkZHIoaGEsIG5ldCkgew0KPiArICAgICAgICAgICAgICAgICAgICAgICAg dTMyIGNyYyA9IGV0aGVyX2NyYyhFVEhfQUxFTiwgaGEtPmFkZHIpID4+IDI2Ow0KPiArICAgICAg ICAgICAgICAgICAgICAgICAgaGFzaGVzW2NyYyA+PiAzXSB8PSAxIDw8IChjcmMgJiAweDcpOw0K PiArICAgICAgICAgICAgICAgIH0NCj4gKyAgICAgICAgfQ0KICAgXl5eLi4uIGV0Yy4NCj4gKw0K PiArIHNyX3dyaXRlX2FzeW5jKGRldiwgTUFSLCBTUl9NQ0FTVF9TSVpFLCBoYXNoZXMpOw0KPiAr IHNyX3dyaXRlX3JlZ19hc3luYyhkZXYsIFJDUiwgcnhfY3RsKTsNCj4gK30NCj4gKw0KPiArc3Rh dGljIGludCBzcjk3MDBfc2V0X21hY19hZGRyZXNzKHN0cnVjdCBuZXRfZGV2aWNlICpuZXQsIHZv aWQgKnApDQo+ICt7DQo+ICsgc3RydWN0IHNvY2thZGRyICphZGRyID0gcDsNCj4gKyBzdHJ1Y3Qg dXNibmV0ICpkZXYgPSBuZXRkZXZfcHJpdihuZXQpOw0KTG9uZyBkZWNsYXJhdGlvbiBsaW5lcyBm aXJzdCBwbGVhc2UuDQo+ICsNCj4gKyBpZiAoIWlzX3ZhbGlkX2V0aGVyX2FkZHIoYWRkci0+c2Ff ZGF0YSkpIHsNCj4gKyBkZXZfZXJyKCZuZXQtPmRldiwgIm5vdCBzZXR0aW5nIGludmFsaWQgbWFj IGFkZHJlc3MgJXBNXG4iLA0KPiArIGFkZHItPnNhX2RhdGEpOw0KZGV2X2VycigmbmV0LT5kZXYs ICJub3Qgc2V0dGluZyBpbnZhbGlkIG1hYyBhZGRyZXNzICVwTVxuIiwNCmFkZHItPnNhX2RhdGEp Ow0KWy4uLl0NCj4gK3N0YXRpYyBpbnQgc3I5NzAwX3J4X2ZpeHVwKHN0cnVjdCB1c2JuZXQgKmRl diwgc3RydWN0IHNrX2J1ZmYgKnNrYikNCj4gK3sNCj4gKyBpbnQgbGVuOw0KPiArIHN0cnVjdCBz a19idWZmICpzcl9za2I7DQo+ICsNCj4gKyAvKiBmb3JtYXQ6DQo+ICsgICAgYjA6IHJ4IHN0YXR1 cw0KPiArICAgIGIxOiBwYWNrZXQgbGVuZ3RoIChpbmNsIGNyYykgbG93DQo+ICsgICAgYjI6IHBh Y2tldCBsZW5ndGggKGluY2wgY3JjKSBoaWdoDQo+ICsgICAgYjMuLm4tNDogcGFja2V0IGRhdGEN Cj4gKyAgICBibi0zLi5ibjogZXRoZXJuZXQgY3JjDQo+ICsgICovDQo+ICsNCj4gKyBpZiAodW5s aWtlbHkoc2tiLT5sZW4gPCBTUl9SWF9PVkVSSEVBRCkpIHsNCj4gKyBkZXZfZXJyKCZkZXYtPnVk ZXYtPmRldiwgInVuZXhwZWN0ZWQgdGlueSByeCBmcmFtZVxuIik7DQo+ICsgcmV0dXJuIDA7DQo+ ICsgfQ0KPiArDQo+ICsgLyoNCj4gKyAgKiBFYWNoIHBhY2tldCBjb250YWlucyBtdWx0aXBsZSBz a2JzDQo+ICsgICovDQo+ICsgd2hpbGUgKHNrYi0+bGVuID4gU1JfUlhfT1ZFUkhFQUQpDQo+ICsg ew0KSyZSIHBsZWFzZS4NClsuLi5dDQo+ICtzdGF0aWMgc3RydWN0IHVzYl9kcml2ZXIgc3I5NzAw X3VzYl9kcml2ZXIgPSB7DQo+ICsgLm5hbWUgPSAic3I5NzAwIiwNCj4gKyAuaWRfdGFibGUgPSBw cm9kdWN0cywNCj4gKyAucHJvYmUgPSB1c2JuZXRfcHJvYmUsDQo+ICsgLmRpc2Nvbm5lY3QgPSB1 c2JuZXRfZGlzY29ubmVjdCwNCj4gKyAuc3VzcGVuZCA9IHVzYm5ldF9zdXNwZW5kLA0KPiArIC5y ZXN1bWUgPSB1c2JuZXRfcmVzdW1lLA0KPiArIC5kaXNhYmxlX2h1Yl9pbml0aWF0ZWRfbHBtID0g MSwNClVzZSA8dGFiPj0uDQpbLi4uXQ0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvdXNiL3Ny OTcwMC5oIGIvZHJpdmVycy9uZXQvdXNiL3NyOTcwMC5oDQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0 DQo+IGluZGV4IDAwMDAwMDAuLmQ5ZmU4MmQNCj4gLS0tIC9kZXYvbnVsbA0KPiArKysgYi9kcml2 ZXJzL25ldC91c2Ivc3I5NzAwLmgNCj4gQEAgLTAsMCArMSwxNTIgQEANCj4gKy8qDQo+ICsgKiBD b3JlQ2hpcC1zeiBTUjk3MDAgb25lIGNoaXAgVVNCIDEuMSBFdGhlcm5ldCBEZXZpY2VzDQo+ICsg Kg0KPiArICogQXV0aG9yIDogbGl1amwgPGxpdWp1bmxpYW5nX2xqbEAxNjMuY29tPg0KPiArICoN Cj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0 ZSBpdCBhbmQvb3INCj4gKyAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBH ZW5lcmFsIFB1YmxpYyBMaWNlbnNlDQo+ICsgKiB2ZXJzaW9uIDIgYXMgcHVibGlzaGVkIGJ5IHRo ZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uDQo+ICsgKi8NCj4gKw0KPiArLyogc3I5NzAwIHNw ZWMuIHJlZ2lzdGVyIHRhYmxlIG9uIGFuZHJvaWQgcGxhdGZvcm0gKi8NCj4gKy8qIFJlZ2lzdGVy cyAqLw0KPiArI2RlZmluZSBOQ1IgMHgwMA0KPiArI2RlZmluZSBOU1IgMHgwMQ0KWy4uLl0NCj4g Ky8qIEJpdCBkZWZpbml0aW9uIGZvciByZWdpc3RlcnMgKi8NCj4gKy8vIE5ldHdvcmsgQ29udHJv bCBSZWcNCj4gKyNkZWZpbmUgTkNSX1JTVCAoMSA8PCAwKQ0KPiArI2RlZmluZSBOQ1JfTEJLICgz IDw8IDEpDQo+ICsjZGVmaW5lIE5DUl9GRFggKDEgPDwgMykNCj4gKyNkZWZpbmUgTkNSX1dBS0VF TiAoMSA8PCA2KQ0KWW91IG1heSBncm91cCB0aGVzZSB3aXRoIHRoZSByZWdpc3RlciBkZWNsYXJh dGlvbnMgYWJvdmUuIFVzZSBhbg0Kb2Zmc2V0IHRvIGltcHJvdmUgcmVhZGFiaWxpdHkgYW5kIHNl cGFyYXRlIHJlZ2lzdGVycyBmcm9tIGZpZWxkcy4NClNlZSBkcml2ZXJzL25ldC9ldGhlcm5ldC9i cm9hZGNvbS90ZzMuaCBmb3IgaW5zdGFuY2UuDQotLSANClVlaW1vcg0K