From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752636Ab3HUKSf (ORCPT ); Wed, 21 Aug 2013 06:18:35 -0400 Received: from m50-132.163.com ([123.125.50.132]:43519 "EHLO m50-132.163.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751644Ab3HUKSL (ORCPT ); Wed, 21 Aug 2013 06:18:11 -0400 X-Greylist: delayed 917 seconds by postgrey-1.27 at vger.kernel.org; Wed, 21 Aug 2013 06:18:09 EDT Date: Wed, 21 Aug 2013 18:02:45 +0800 From: "=?utf-8?B?bGl1anVubGlhbmdfbGps?=" To: "=?utf-8?B?QmVuIEh1dGNoaW5ncw==?=" Cc: "=?utf-8?B?Z3JlZ2to?=" , "=?utf-8?B?bGludXgtdXNi?=" , "=?utf-8?B?bmV0ZGV2?=" , "=?utf-8?B?bGludXgta2VybmVs?=" , "=?utf-8?B?c3VuaGVjaGVuZw==?=" References: <201308201850095789331@163.com> Subject: =?utf-8?B?UmU6IFJlOiBbUEFUQ0gtU1I5NzAwXSBNZXJnZSBVU0IgMS4xIEV0aGVybmV0IEFkYXB0ZXIgU1I5NzAwIERldmljZURyaXZlciBpbnRvIHRoZSBMaW51eCBLZXJuZWw=?= Message-ID: <201308211802427961789@163.com> X-mailer: Foxmail 6, 15, 201, 22 [cn] Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-CM-TRANSID: DNGowEAZW0o1kBRS9SQeAQ--.674S2 X-Coremail-Antispam: 1Uf129KBjvAXoWftFW8Kr47WFW7GFWDCr4rKrg_yoW8tFWfKo Z3XFsxJw18JryxArZ5Ww1xXws8ZFyDKw13Aw43XrZ7Xa43XF1qgrW3W3y5Z345Xa4S9Fn5 Zw18ta93AFZYvrW5n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjxUcyIUUUUUU X-CM-SenderInfo: xolxy3pqolt0hjboyzi6rwjhhfrp/1tbiqxiAX1EAEzA5pAAAsD 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 r7LAIgMl021957 Dear Ben : 1, please give me email address of David Miller, and Thanks a lot. 2, please check the new sr9700 device driver which is checked by the script tools scripts/checkpatch.pl and the attachment file is the result of scripts/checkpatch.pl patch-commit-20130821 I'm sorry that I'm still finding the way to signed-off 3, Thanks again for your correct suggestion and Please check the new device driver patch. [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 发件人: Ben Hutchings 发送时间: 2013-08-20 21:36:50 收件人: liujunliang_ljl 抄送: gregkh; linux-usb; netdev; linux-kernel; sunhecheng 主题: Re: [PATCH-SR9700] Merge USB 1.1 Ethernet Adapter SR9700 DeviceDriver into the Linux Kernel On Tue, 2013-08-20 at 18:50 +0800, liujunliang_ljl wrote: > Dear Gregkh & all : > > I am the software engineer Liu Junliang from ShenZhen CoreChips high technology company, on the market of SR9700 chip is designed and owned by us. > SR9700 is a type of USB to Ethernet Converter and is compatible with USB 1.1 protocol, 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. > Thanks a lot. As this is a net driver, the relevant maintainer is David Miller and not Greg. There are some style errors here which can be found using scripts/checkpatch.pl. You'll need to fix those and re-submit. I'll point out some more problems inline. > --- /dev/null > +++ b/drivers/net/usb/sr9700.c [...] > +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 i; > + > + /* access is 16bit */ > + if ((eeprom->offset % 2) || (eeprom->len % 2)) > + return -EINVAL; You're really supposed to handle these cases by shifting as necessary. > + for (i = 0; i < eeprom->len / 2; i++) { > + if (sr_read_eeprom_word(dev, eeprom->offset / 2 + i, &ebuf[i]) < 0) > + return -EINVAL; You should pass up the error code, not substitute -EINVAL. [...] > +static void sr9700_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) > +{ > + /* Inherit standard device info */ > + usbnet_get_drvinfo(net, info); > + info->eedump_len = SR_EEPROM_LEN; You don't need to set eedump_len; the ethtool core will set it after calling sr9700_get_eeprom_len(). So you don't need your own implementation of get_drvinfo at all. [...] > +static int sr9700_bind(struct usbnet *dev, struct usb_interface *intf) > +{ [...] > + /* read MAC */ > + if (sr_read(dev, PAR, ETH_ALEN, dev->net->dev_addr) < 0) { > + printk(KERN_ERR "Error reading MAC address\n"); > + ret = -ENODEV; > + goto out; > + } [...] I think this should read the MAC address from EEPROM and copy it to both dev_addr to perm_addr. MAC address changes should not persist if the driver is reloaded. Ben. -- Ben Hutchings, Staff Engineer, Solarflare Not speaking for my employer; that's the marketing department's job. They asked us to note that Solarflare product names are trademarked. {.n++%ݶw{.n+{G{ayʇڙ,jfhz_(階ݢj"mG?&~iOzv^m ?I From mboxrd@z Thu Jan 1 00:00:00 1970 From: "=?utf-8?B?bGl1anVubGlhbmdfbGps?=" Subject: =?utf-8?B?UmU6IFJlOiBbUEFUQ0gtU1I5NzAwXSBNZXJnZSBVU0IgMS4xIEV0aGVybmV0IEFkYXB0ZXIgU1I5NzAwIERldmljZURyaXZlciBpbnRvIHRoZSBMaW51eCBLZXJuZWw=?= Date: Wed, 21 Aug 2013 18:02:45 +0800 Message-ID: <201308211802427961789@163.com> References: <201308201850095789331@163.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Cc: "=?utf-8?B?Z3JlZ2to?=" , "=?utf-8?B?bGludXgtdXNi?=" , "=?utf-8?B?bmV0ZGV2?=" , "=?utf-8?B?bGludXgta2VybmVs?=" , "=?utf-8?B?c3VuaGVjaGVuZw==?=" To: "=?utf-8?B?QmVuIEh1dGNoaW5ncw==?=" Return-path: Sender: linux-kernel-owner@vger.kernel.org List-Id: netdev.vger.kernel.org RGVhciBCZW4gOg0KDQoJCTEsICBwbGVhc2UgZ2l2ZSBtZSBlbWFpbCBhZGRyZXNzIG9mIERhdmlk IE1pbGxlciwgYW5kIFRoYW5rcyBhIGxvdC4NCg0KCQkyLCAgcGxlYXNlIGNoZWNrIHRoZSBuZXcg c3I5NzAwIGRldmljZSBkcml2ZXIgd2hpY2ggaXMgY2hlY2tlZCBieSB0aGUgc2NyaXB0IHRvb2xz DQoJCQkNCgkJCQlzY3JpcHRzL2NoZWNrcGF0Y2gucGwgDQoJCQlhbmQgdGhlIGF0dGFjaG1lbnQg ZmlsZSBpcyB0aGUgcmVzdWx0IG9mIHNjcmlwdHMvY2hlY2twYXRjaC5wbCBwYXRjaC1jb21taXQt MjAxMzA4MjENCg0KCQkJSSdtIHNvcnJ5IHRoYXQgSSdtIHN0aWxsIGZpbmRpbmcgdGhlIHdheSB0 byBzaWduZWQtb2ZmDQoNCgkJMywgVGhhbmtzIGFnYWluIGZvciB5b3VyIGNvcnJlY3Qgc3VnZ2Vz dGlvbiBhbmQgUGxlYXNlIGNoZWNrIHRoZSBuZXcgZGV2aWNlIGRyaXZlciBwYXRjaC4NCgkJDQpb UEFUQ0hdIDogIA0KICANCmRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC91c2IvS2NvbmZpZyBiL2Ry 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 bCAqLw0KKw0KKyNlbmRpZgkvKiBfU1I5NzAwX0ggKi8NCg0KDQoNCg0KMjAxMy0wOC0yMSANCg0K DQoNCmxpdWp1bmxpYW5nX2xqbCANCg0KDQoNCuWPkeS7tuS6uu+8miBCZW4gSHV0Y2hpbmdzIA0K 5Y+R6YCB5pe26Ze077yaIDIwMTMtMDgtMjAgIDIxOjM2OjUwIA0K5pS25Lu25Lq677yaIGxpdWp1 bmxpYW5nX2xqbCANCuaKhOmAge+8miBncmVna2g7IGxpbnV4LXVzYjsgbmV0ZGV2OyBsaW51eC1r ZXJuZWw7IHN1bmhlY2hlbmcgDQrkuLvpopjvvJogUmU6IFtQQVRDSC1TUjk3MDBdIE1lcmdlIFVT QiAxLjEgRXRoZXJuZXQgQWRhcHRlciBTUjk3MDAgRGV2aWNlRHJpdmVyIGludG8gdGhlIExpbnV4 IEtlcm5lbCANCiANCk9uIFR1ZSwgMjAxMy0wOC0yMCBhdCAxODo1MCArMDgwMCwgbGl1anVubGlh bmdfbGpsIHdyb3RlOg0KPiBEZWFyIEdyZWdraCAmIGFsbCA6DQo+IA0KPiAgSSBhbSB0aGUgc29m dHdhcmUgZW5naW5lZXIgTGl1IEp1bmxpYW5nIGZyb20gU2hlblpoZW4gQ29yZUNoaXBzIGhpZ2gg dGVjaG5vbG9neSBjb21wYW55LCBvbiB0aGUgbWFya2V0IG9mIFNSOTcwMCBjaGlwIGlzIGRlc2ln bmVkIGFuZCBvd25lZCBieSB1cy4gDQo+ICAgICAgICAgU1I5NzAwIGlzIGEgdHlwZSBvZiBVU0Ig dG8gRXRoZXJuZXQgQ29udmVydGVyIGFuZCBpcyBjb21wYXRpYmxlIHdpdGggVVNCIDEuMSBwcm90 b2NvbCwgV2Ugd2FudCB0byBtZXJnZSBTUjk3MDAgZGV2aWNlIGRyaXZlciBpbnRvIHRoZSBMaW51 eCBLZXJuZWwuIFRoZSBmb2xsb3dpbmcgaXMgdGhlIExpbnV4IDMuMTAuNyB2ZXJzaW9uIHBhdGNo IGZvciBTUjk3MDAsIFBsZWFzZSBnaXZlIHVzIHRoZSBhc3Nlc3NtZW50IGFuZCBzdXBwb3J0Lg0K PiAgICAgICAgIFRoYW5rcyBhIGxvdC4NCkFzIHRoaXMgaXMgYSBuZXQgZHJpdmVyLCB0aGUgcmVs ZXZhbnQgbWFpbnRhaW5lciBpcyBEYXZpZCBNaWxsZXIgYW5kIG5vdA0KR3JlZy4NClRoZXJlIGFy ZSBzb21lIHN0eWxlIGVycm9ycyBoZXJlIHdoaWNoIGNhbiBiZSBmb3VuZCB1c2luZw0Kc2NyaXB0 cy9jaGVja3BhdGNoLnBsLiAgWW91J2xsIG5lZWQgdG8gZml4IHRob3NlIGFuZCByZS1zdWJtaXQu ICBJJ2xsDQpwb2ludCBvdXQgc29tZSBtb3JlIHByb2JsZW1zIGlubGluZS4NCj4gLS0tIC9kZXYv bnVsbA0KPiArKysgYi9kcml2ZXJzL25ldC91c2Ivc3I5NzAwLmMNClsuLi5dDQo+ICtzdGF0aWMg aW50IHNyOTcwMF9nZXRfZWVwcm9tKHN0cnVjdCBuZXRfZGV2aWNlICpuZXQsIHN0cnVjdCBldGh0 b29sX2VlcHJvbSAqZWVwcm9tLCB1OCAqIGRhdGEpDQo+ICt7DQo+ICsgc3RydWN0IHVzYm5ldCAq ZGV2ID0gbmV0ZGV2X3ByaXYobmV0KTsNCj4gKyBfX2xlMTYgKmVidWYgPSAoX19sZTE2ICopIGRh dGE7DQo+ICsgaW50IGk7DQo+ICsNCj4gKyAvKiBhY2Nlc3MgaXMgMTZiaXQgKi8NCj4gKyBpZiAo KGVlcHJvbS0+b2Zmc2V0ICUgMikgfHwgKGVlcHJvbS0+bGVuICUgMikpDQo+ICsgcmV0dXJuIC1F SU5WQUw7DQpZb3UncmUgcmVhbGx5IHN1cHBvc2VkIHRvIGhhbmRsZSB0aGVzZSBjYXNlcyBieSBz aGlmdGluZyBhcyBuZWNlc3NhcnkuDQo+ICsgZm9yIChpID0gMDsgaSA8IGVlcHJvbS0+bGVuIC8g MjsgaSsrKSB7DQo+ICsgaWYgKHNyX3JlYWRfZWVwcm9tX3dvcmQoZGV2LCBlZXByb20tPm9mZnNl dCAvIDIgKyBpLCAmZWJ1ZltpXSkgPCAwKQ0KPiArIHJldHVybiAtRUlOVkFMOw0KWW91IHNob3Vs ZCBwYXNzIHVwIHRoZSBlcnJvciBjb2RlLCBub3Qgc3Vic3RpdHV0ZSAtRUlOVkFMLg0KWy4uLl0N Cj4gK3N0YXRpYyB2b2lkIHNyOTcwMF9nZXRfZHJ2aW5mbyhzdHJ1Y3QgbmV0X2RldmljZSAqbmV0 LCBzdHJ1Y3QgZXRodG9vbF9kcnZpbmZvICppbmZvKQ0KPiArew0KPiArIC8qIEluaGVyaXQgc3Rh bmRhcmQgZGV2aWNlIGluZm8gKi8NCj4gKyB1c2JuZXRfZ2V0X2RydmluZm8obmV0LCBpbmZvKTsN Cj4gKyBpbmZvLT5lZWR1bXBfbGVuID0gU1JfRUVQUk9NX0xFTjsNCllvdSBkb24ndCBuZWVkIHRv IHNldCBlZWR1bXBfbGVuOyB0aGUgZXRodG9vbCBjb3JlIHdpbGwgc2V0IGl0IGFmdGVyDQpjYWxs aW5nIHNyOTcwMF9nZXRfZWVwcm9tX2xlbigpLiAgU28geW91IGRvbid0IG5lZWQgeW91ciBvd24N CmltcGxlbWVudGF0aW9uIG9mIGdldF9kcnZpbmZvIGF0IGFsbC4NClsuLi5dDQo+ICtzdGF0aWMg aW50IHNyOTcwMF9iaW5kKHN0cnVjdCB1c2JuZXQgKmRldiwgc3RydWN0IHVzYl9pbnRlcmZhY2Ug KmludGYpDQo+ICt7DQpbLi4uXQ0KPiArIC8qIHJlYWQgTUFDICovDQo+ICsgaWYgKHNyX3JlYWQo ZGV2LCBQQVIsIEVUSF9BTEVOLCBkZXYtPm5ldC0+ZGV2X2FkZHIpIDwgMCkgew0KPiArIHByaW50 ayhLRVJOX0VSUiAiRXJyb3IgcmVhZGluZyBNQUMgYWRkcmVzc1xuIik7DQo+ICsgcmV0ID0gLUVO T0RFVjsNCj4gKyBnb3RvIG91dDsNCj4gKyB9DQpbLi4uXQ0KSSB0aGluayB0aGlzIHNob3VsZCBy ZWFkIHRoZSBNQUMgYWRkcmVzcyBmcm9tIEVFUFJPTSBhbmQgY29weSBpdCB0byBib3RoDQpkZXZf YWRkciB0byBwZXJtX2FkZHIuICBNQUMgYWRkcmVzcyBjaGFuZ2VzIHNob3VsZCBub3QgcGVyc2lz dCBpZiB0aGUNCmRyaXZlciBpcyByZWxvYWRlZC4NCkJlbi4NCi0tIA0KQmVuIEh1dGNoaW5ncywg U3RhZmYgRW5naW5lZXIsIFNvbGFyZmxhcmUNCk5vdCBzcGVha2luZyBmb3IgbXkgZW1wbG95ZXI7 IHRoYXQncyB0aGUgbWFya2V0aW5nIGRlcGFydG1lbnQncyBqb2IuDQpUaGV5IGFza2VkIHVzIHRv IG5vdGUgdGhhdCBTb2xhcmZsYXJlIHByb2R1Y3QgbmFtZXMgYXJlIHRyYWRlbWFya2VkLg0K