From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752333Ab3HUKXG (ORCPT ); Wed, 21 Aug 2013 06:23:06 -0400 Received: from m50-132.163.com ([123.125.50.132]:48975 "EHLO m50-132.163.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751392Ab3HUKXC (ORCPT ); Wed, 21 Aug 2013 06:23:02 -0400 Date: Wed, 21 Aug 2013 18:07:30 +0800 From: "=?utf-8?B?bGl1anVubGlhbmdfbGps?=" To: "=?utf-8?B?Sm9lIFBlcmNoZXM=?=" , "=?utf-8?B?RnJhbmNvaXMgUm9taWV1?=" Cc: "=?utf-8?B?Z3JlZ2to?=" , "=?utf-8?B?c3VuaGVjaGVuZw==?=" , "=?utf-8?B?bGludXgtdXNi?=" , "=?utf-8?B?bmV0ZGV2?=" , "=?utf-8?B?bGludXgta2VybmVs?=" References: <201308201841116403992@163.com>, <20130820204606.GB26241@electric-eye.fr.zoreil.com>, <1377032302.2016.75.camel@joe-AO722> Subject: =?utf-8?B?UmU6IFJlOiBbUEFUQ0gtU1I5NzAwXSBNZXJnZSBVU0IgMS4xIEV0aGVybmV0IEFkYXB0ZXIgU1I5NzAwIERldmljZURyaXZlciBpbnRvIHRoZSBMaW51eCBLZXJuZWw=?= Message-ID: <201308211807295009698@163.com> X-mailer: Foxmail 6, 15, 201, 22 [cn] Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-CM-TRANSID: DNGowECJvVpUkRRSu4MeAQ--.637S2 X-Coremail-Antispam: 1Uf129KBjvAXoWfZw1xCr1ktw4rJryfCFy3Jwb_yoW8ur47Co Z3XFsxJw18JryxArZ5Gw17Xw4DZFyDKw15Ar43XrZ7Xa43XF1qgrW3W3y5Z345Ja4S9rn5 Zw18ta93AFZYvryrn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjxUsQJ5UUUUU X-CM-SenderInfo: xolxy3pqolt0hjboyzi6rwjhhfrp/1tbiwAmAX1D+OvO0awAAsu 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 r7LANCTw022021 Dear Joe : Thanks a lot and I have been fixed all the problems mentioned above. please check the following patch and thanks again. [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 发件人: Joe Perches 发送时间: 2013-08-21 04:58:27 收件人: Francois Romieu 抄送: liujunliang_ljl; gregkh; sunhecheng; linux-usb; netdev; linux-kernel 主题: Re: [PATCH-SR9700] Merge USB 1.1 Ethernet Adapter SR9700 DeviceDriver into the Linux Kernel On Tue, 2013-08-20 at 22:46 +0200, Francois Romieu wrote: > liujunliang_ljl : > > + if (i >= SR_SHARE_TIMEOUT) { > > + netdev_err(dev->net, "%s read timed out!", phy ? "phy" : "eeprom"); netdev_, like almost all other printk messages needs a terminating "\n" newline to avoid any possible message interleaving by other printks. > > + 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); prefer netdev_ to dev_ where possible. {.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:07:30 +0800 Message-ID: <201308211807295009698@163.com> References: <201308201841116403992@163.com>, <20130820204606.GB26241@electric-eye.fr.zoreil.com>, <1377032302.2016.75.camel@joe-AO722> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Cc: "=?utf-8?B?Z3JlZ2to?=" , "=?utf-8?B?c3VuaGVjaGVuZw==?=" , "=?utf-8?B?bGludXgtdXNi?=" , "=?utf-8?B?bmV0ZGV2?=" , "=?utf-8?B?bGludXgta2VybmVs?=" To: "=?utf-8?B?Sm9lIFBlcmNoZXM=?=" , "=?utf-8?B?RnJhbmNvaXMgUm9taWV1?=" Return-path: Sender: linux-kernel-owner@vger.kernel.org List-Id: netdev.vger.kernel.org RGVhciBKb2UgOg0KDQoJCVRoYW5rcyBhIGxvdCBhbmQgSSBoYXZlIGJlZW4gZml4ZWQgYWxsIHRo ZSBwcm9ibGVtcyBtZW50aW9uZWQgYWJvdmUuIHBsZWFzZSBjaGVjayB0aGUgZm9sbG93aW5nIHBh dGNoIGFuZCB0aGFua3MgYWdhaW4uIA0KDQpbUEFUQ0hdIDoNCmRpZmYgLS1naXQgYS9kcml2ZXJz L25ldC91c2IvS2NvbmZpZyBiL2RyaXZlcnMvbmV0L3VzYi9LY29uZmlnDQppbmRleCAyODdjYzYy Li5hOTRiMTk2IDEwMDY0NA0KLS0tIGEvZHJpdmVycy9uZXQvdXNiL0tjb25maWcNCisrKyBiL2Ry aXZlcnMvbmV0L3VzYi9LY29uZmlnDQpAQCAtMjcyLDYgKzI3MiwxNCBAQCBjb25maWcgVVNCX05F VF9ETTk2MDENCiAJICBUaGlzIG9wdGlvbiBhZGRzIHN1cHBvcnQgZm9yIERhdmljb20gRE05NjAx IGJhc2VkIFVTQiAxLjENCiAJICAxMC8xMDAgRXRoZXJuZXQgYWRhcHRlcnMuDQogDQorY29uZmln IFVTQl9ORVRfU1I5NzAwDQorCXRyaXN0YXRlICJDb3JlQ2hpcC1zeiBTUjk3MDAgYmFzZWQgVVNC IDEuMSAxMC8xMDAgZXRoZXJuZXQgZGV2aWNlcyINCisJZGVwZW5kcyBvbiBVU0JfVVNCTkVUDQor CXNlbGVjdCBDUkMzMg0KKwloZWxwDQorCSAgVGhpcyBvcHRpb24gYWRkcyBzdXBwb3J0IGZvciBD b3JlQ2hpcC1zeiBTUjk3MDAgYmFzZWQgVVNCIDEuMQ0KKwkgIDEwLzEwMCBFdGhlcm5ldCBhZGFw dGVycy4NCisNCiBjb25maWcgVVNCX05FVF9TTVNDNzVYWA0KIAl0cmlzdGF0ZSAiU01TQyBMQU43 NVhYIGJhc2VkIFVTQiAyLjAgZ2lnYWJpdCBldGhlcm5ldCBkZXZpY2VzIg0KIAlkZXBlbmRzIG9u IFVTQl9VU0JORVQNCmRpZmYgLS1naXQgYS9kcml2ZXJzL25ldC91c2IvTWFrZWZpbGUgYi9kcml2 ZXJzL25ldC91c2IvTWFrZWZpbGUNCmluZGV4IDlhYjVjOWQuLmJiYTg3YTIgMTAwNjQ0DQotLS0g YS9kcml2ZXJzL25ldC91c2IvTWFrZWZpbGUNCisrKyBiL2RyaXZlcnMvbmV0L3VzYi9NYWtlZmls ZQ0KQEAgLTE0LDYgKzE0LDcgQEAgb2JqLSQoQ09ORklHX1VTQl9ORVRfQVg4ODE3OV8xNzhBKSAg ICAgICs9IGF4ODgxNzlfMTc4YS5vDQogb2JqLSQoQ09ORklHX1VTQl9ORVRfQ0RDRVRIRVIpCSs9 IGNkY19ldGhlci5vDQogb2JqLSQoQ09ORklHX1VTQl9ORVRfQ0RDX0VFTSkJKz0gY2RjX2VlbS5v DQogb2JqLSQoQ09ORklHX1VTQl9ORVRfRE05NjAxKQkrPSBkbTk2MDEubw0KK29iai0kKENPTkZJ R19VU0JfTkVUX1NSOTcwMCkJKz0gc3I5NzAwLm8NCiBvYmotJChDT05GSUdfVVNCX05FVF9TTVND NzVYWCkJKz0gc21zYzc1eHgubw0KIG9iai0kKENPTkZJR19VU0JfTkVUX1NNU0M5NVhYKQkrPSBz bXNjOTV4eC5vDQogb2JqLSQoQ09ORklHX1VTQl9ORVRfR0w2MjBBKQkrPSBnbDYyMGEubw0KZGlm ZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3VzYi9zcjk3MDAuYyBiL2RyaXZlcnMvbmV0L3VzYi9zcjk3 MDAuYw0KbmV3IGZpbGUgbW9kZSAxMDA2NDQNCmluZGV4IDAwMDAwMDAuLjljOGYxNjcNCi0tLSAv ZGV2L251bGwNCisrKyBiL2RyaXZlcnMvbmV0L3VzYi9zcjk3MDAuYw0KQEAgLTAsMCArMSw1MzYg QEANCisvKg0KKyAqIENvcmVDaGlwLXN6IFNSOTcwMCBvbmUgY2hpcCBVU0IgMS4xIEV0aGVybmV0 IERldmljZXMNCisgKg0KKyAqIEF1dGhvciA6IGxpdWpsIDxsaXVqdW5saWFuZ19samxAMTYzLmNv bT4NCisgKg0KKyAqIEJhc2VkIG9uIGRtOTYwMS5jDQorICoNCisgKiBUaGlzIGZpbGUgaXMgbGlj ZW5zZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQ0K KyAqIHZlcnNpb24gMi4gIFRoaXMgcHJvZ3JhbSBpcyBsaWNlbnNlZCAiYXMgaXMiIHdpdGhvdXQg YW55IHdhcnJhbnR5IG9mIGFueQ0KKyAqIGtpbmQsIHdoZXRoZXIgZXhwcmVzcyBvciBpbXBsaWVk Lg0KKyAqLw0KKw0KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4NCisjaW5jbHVkZSA8bGludXgv c2NoZWQuaD4NCisjaW5jbHVkZSA8bGludXgvc3RkZGVmLmg+DQorI2luY2x1ZGUgPGxpbnV4L2lu aXQuaD4NCisjaW5jbHVkZSA8bGludXgvbmV0ZGV2aWNlLmg+DQorI2luY2x1ZGUgPGxpbnV4L2V0 aGVyZGV2aWNlLmg+DQorI2luY2x1ZGUgPGxpbnV4L2V0aHRvb2wuaD4NCisjaW5jbHVkZSA8bGlu dXgvbWlpLmg+DQorI2luY2x1ZGUgPGxpbnV4L3VzYi5oPg0KKyNpbmNsdWRlIDxsaW51eC9jcmMz Mi5oPg0KKyNpbmNsdWRlIDxsaW51eC91c2IvdXNibmV0Lmg+DQorDQorI2luY2x1ZGUgInNyOTcw MC5oIg0KKw0KK3N0YXRpYyBpbnQgc3JfcmVhZChzdHJ1Y3QgdXNibmV0ICpkZXYsIHU4IHJlZywg dTE2IGxlbmd0aCwgdm9pZCAqZGF0YSkNCit7DQorCWludCBlcnI7DQorDQorCWVyciA9IHVzYm5l dF9yZWFkX2NtZChkZXYsIFNSX1JEX1JFR1MsIFNSX1JFUV9SRF9SRUcsDQorCQkJCQkwLCByZWcs IGRhdGEsIGxlbmd0aCk7DQorCWlmICgoZXJyICE9IGxlbmd0aCkgJiYgKGVyciA+PSAwKSkNCisJ CWVyciA9IC1FSU5WQUw7DQorCXJldHVybiBlcnI7DQorfQ0KKw0KK3N0YXRpYyBpbnQgc3Jfd3Jp dGUoc3RydWN0IHVzYm5ldCAqZGV2LCB1OCByZWcsIHUxNiBsZW5ndGgsIHZvaWQgKmRhdGEpDQor ew0KKwlpbnQgZXJyOw0KKw0KKwllcnIgPSB1c2JuZXRfd3JpdGVfY21kKGRldiwgU1JfV1JfUkVH UywgU1JfUkVRX1dSX1JFRywNCisJCQkJCTAsIHJlZywgZGF0YSwgbGVuZ3RoKTsNCisJaWYgKChl cnIgPj0gMCkgJiYgKGVyciA8IGxlbmd0aCkpDQorCQllcnIgPSAtRUlOVkFMOw0KKwlyZXR1cm4g ZXJyOw0KK30NCisNCitzdGF0aWMgaW50IHNyX3JlYWRfcmVnKHN0cnVjdCB1c2JuZXQgKmRldiwg dTggcmVnLCB1OCAqdmFsdWUpDQorew0KKwlyZXR1cm4gc3JfcmVhZChkZXYsIHJlZywgMSwgdmFs dWUpOw0KK30NCisNCitzdGF0aWMgaW50IHNyX3dyaXRlX3JlZyhzdHJ1Y3QgdXNibmV0ICpkZXYs IHU4IHJlZywgdTggdmFsdWUpDQorew0KKwlyZXR1cm4gdXNibmV0X3dyaXRlX2NtZChkZXYsIFNS X1dSX1JFR1MsIFNSX1JFUV9XUl9SRUcsDQorCQkJCQl2YWx1ZSwgcmVnLCBOVUxMLCAwKTsNCit9 DQorDQorc3RhdGljIHZvaWQgc3Jfd3JpdGVfYXN5bmMoc3RydWN0IHVzYm5ldCAqZGV2LCB1OCBy ZWcsIHUxNiBsZW5ndGgsIHZvaWQgKmRhdGEpDQorew0KKwl1c2JuZXRfd3JpdGVfY21kX2FzeW5j KGRldiwgU1JfV1JfUkVHUywgU1JfUkVRX1dSX1JFRywNCisJCQkJCTAsIHJlZywgZGF0YSwgbGVu Z3RoKTsNCit9DQorDQorc3RhdGljIHZvaWQgc3Jfd3JpdGVfcmVnX2FzeW5jKHN0cnVjdCB1c2Ju ZXQgKmRldiwgdTggcmVnLCB1OCB2YWx1ZSkNCit7DQorCXVzYm5ldF93cml0ZV9jbWRfYXN5bmMo ZGV2LCBTUl9XUl9SRUdTLCBTUl9SRVFfV1JfUkVHLA0KKwkJCQkJdmFsdWUsIHJlZywgTlVMTCwg MCk7DQorfQ0KKw0KK3N0YXRpYyBpbnQgc3Jfc2hhcmVfcmVhZF93b3JkKHN0cnVjdCB1c2JuZXQg KmRldiwgaW50IHBoeSwgdTggcmVnLCBfX2xlMTYgKnZhbHVlKQ0KK3sNCisJaW50IHJldCwgaTsN CisNCisJbXV0ZXhfbG9jaygmZGV2LT5waHlfbXV0ZXgpOw0KKw0KKwlzcl93cml0ZV9yZWcoZGV2 LCBFUEFSLCBwaHkgPyAocmVnIHwgMHg0MCkgOiByZWcpOw0KKwlzcl93cml0ZV9yZWcoZGV2LCBF UENSLCBwaHkgPyAweGMgOiAweDQpOw0KKw0KKwlmb3IgKGkgPSAwOyBpIDwgU1JfU0hBUkVfVElN RU9VVDsgaSsrKSB7DQorCQl1OCB0bXAgPSAwOw0KKw0KKwkJdWRlbGF5KDEpOw0KKwkJcmV0ID0g c3JfcmVhZF9yZWcoZGV2LCBFUENSLCAmdG1wKTsNCisJCWlmIChyZXQgPCAwKQ0KKwkJCWdvdG8g b3V0X3VubG9jazsNCisNCisJCS8qIHJlYWR5ICovDQorCQlpZiAoKHRtcCAmIEVQQ1JfRVJSRSkg PT0gMCkNCisJCQlicmVhazsNCisJfQ0KKw0KKwlpZiAoaSA+PSBTUl9TSEFSRV9USU1FT1VUKSB7 DQorCQluZXRkZXZfZXJyKGRldi0+bmV0LCAiJXMgcmVhZCB0aW1lZCBvdXQhXG4iLCBwaHkgPyAi cGh5IiA6ICJlZXByb20iKTsNCisJCXJldCA9IC1FSU87DQorCQlnb3RvIG91dF91bmxvY2s7DQor CX0NCisNCisJc3Jfd3JpdGVfcmVnKGRldiwgRVBDUiwgMHgwKTsNCisJcmV0ID0gc3JfcmVhZChk ZXYsIEVQRFIsIDIsIHZhbHVlKTsNCisNCisJbmV0ZGV2X2RiZyhkZXYtPm5ldCwgInJlYWQgc2hh cmVkICVkIDB4JTAyeCByZXR1cm5lZCAweCUwNHgsICVkXG4iLA0KKwkgICAgICAgcGh5LCByZWcs ICp2YWx1ZSwgcmV0KTsNCisNCisgb3V0X3VubG9jazoNCisJbXV0ZXhfdW5sb2NrKCZkZXYtPnBo eV9tdXRleCk7DQorCXJldHVybiByZXQ7DQorfQ0KKw0KK3N0YXRpYyBpbnQgc3Jfc2hhcmVfd3Jp dGVfd29yZChzdHJ1Y3QgdXNibmV0ICpkZXYsIGludCBwaHksIHU4IHJlZywgX19sZTE2IHZhbHVl KQ0KK3sNCisJaW50IHJldCwgaTsNCisNCisJbXV0ZXhfbG9jaygmZGV2LT5waHlfbXV0ZXgpOw0K Kw0KKwlyZXQgPSBzcl93cml0ZShkZXYsIEVQRFIsIDIsICZ2YWx1ZSk7DQorCWlmIChyZXQgPCAw KQ0KKwkJZ290byBvdXRfdW5sb2NrOw0KKw0KKwlzcl93cml0ZV9yZWcoZGV2LCBFUEFSLCBwaHkg PyAocmVnIHwgMHg0MCkgOiByZWcpOw0KKwlzcl93cml0ZV9yZWcoZGV2LCBFUENSLCBwaHkgPyAw eDFhIDogMHgxMik7DQorDQorCWZvciAoaSA9IDA7IGkgPCBTUl9TSEFSRV9USU1FT1VUOyBpKysp IHsNCisJCXU4IHRtcCA9IDA7DQorDQorCQl1ZGVsYXkoMSk7DQorCQlyZXQgPSBzcl9yZWFkX3Jl ZyhkZXYsIEVQQ1IsICZ0bXApOw0KKwkJaWYgKHJldCA8IDApDQorCQkJZ290byBvdXRfdW5sb2Nr Ow0KKw0KKwkJLyogcmVhZHkgKi8NCisJCWlmICgodG1wICYgRVBDUl9FUlJFKSA9PSAwKQ0KKwkJ CWJyZWFrOw0KKwl9DQorDQorCWlmIChpID49IFNSX1NIQVJFX1RJTUVPVVQpIHsNCisJCW5ldGRl dl9lcnIoZGV2LT5uZXQsICIlcyB3cml0ZSB0aW1lZCBvdXQhXG4iLCBwaHkgPyAicGh5IiA6ICJl ZXByb20iKTsNCisJCXJldCA9IC1FSU87DQorCQlnb3RvIG91dF91bmxvY2s7DQorCX0NCisNCisJ c3Jfd3JpdGVfcmVnKGRldiwgRVBDUiwgMHgwKTsNCisNCitvdXRfdW5sb2NrOg0KKwltdXRleF91 bmxvY2soJmRldi0+cGh5X211dGV4KTsNCisJcmV0dXJuIHJldDsNCit9DQorDQorc3RhdGljIGlu dCBzcl9yZWFkX2VlcHJvbV93b3JkKHN0cnVjdCB1c2JuZXQgKmRldiwgdTggb2Zmc2V0LCB2b2lk ICp2YWx1ZSkNCit7DQorCXJldHVybiBzcl9zaGFyZV9yZWFkX3dvcmQoZGV2LCAwLCBvZmZzZXQs IHZhbHVlKTsNCit9DQorDQorc3RhdGljIGludCBzcjk3MDBfZ2V0X2VlcHJvbV9sZW4oc3RydWN0 IG5ldF9kZXZpY2UgKmRldikNCit7DQorCXJldHVybiBTUl9FRVBST01fTEVOOw0KK30NCisNCitz dGF0aWMgaW50IHNyOTcwMF9nZXRfZWVwcm9tKHN0cnVjdCBuZXRfZGV2aWNlICpuZXQsIHN0cnVj dCBldGh0b29sX2VlcHJvbSAqZWVwcm9tLCB1OCAqZGF0YSkNCit7DQorCXN0cnVjdCB1c2JuZXQg KmRldiA9IG5ldGRldl9wcml2KG5ldCk7DQorCV9fbGUxNiAqZWJ1ZiA9IChfX2xlMTYgKikgZGF0 YTsNCisJaW50IHJldCA9IDA7DQorCWludCBpOw0KKw0KKwkvKiBhY2Nlc3MgaXMgMTZiaXQgKi8N CisJaWYgKChlZXByb20tPm9mZnNldCAlIDIpIHx8IChlZXByb20tPmxlbiAlIDIpKQ0KKwkJcmV0 dXJuIC1FSU5WQUw7DQorDQorCWZvciAoaSA9IDA7IGkgPCBlZXByb20tPmxlbiAvIDI7IGkrKykN CisJCQlyZXQgPSBzcl9yZWFkX2VlcHJvbV93b3JkKGRldiwgZWVwcm9tLT5vZmZzZXQgLyAyICsg aSwgJmVidWZbaV0pOw0KKw0KKwlyZXR1cm4gcmV0Ow0KK30NCisNCitzdGF0aWMgaW50IHNyX21k aW9fcmVhZChzdHJ1Y3QgbmV0X2RldmljZSAqbmV0ZGV2LCBpbnQgcGh5X2lkLCBpbnQgbG9jKQ0K K3sNCisJc3RydWN0IHVzYm5ldCAqZGV2ID0gbmV0ZGV2X3ByaXYobmV0ZGV2KTsNCisJX19sZTE2 IHJlczsNCisJaW50IHJjID0gMDsNCisNCisJaWYgKHBoeV9pZCkgew0KKwkJbmV0ZGV2X2RiZyhk ZXYtPm5ldCwgIk9ubHkgaW50ZXJuYWwgcGh5IHN1cHBvcnRlZFxuIik7DQorCQlyZXR1cm4gMDsN CisJfQ0KKw0KKwkvKiBBY2Nlc3MgTlNSX0xJTktTVCBiaXQgZm9yIGxpbmsgc3RhdHVzIGluc3Rl YWQgb2YgTUlJX0JNU1IgKi8NCisJaWYgKGxvYyA9PSBNSUlfQk1TUikgew0KKwkJCXU4IHZhbHVl Ow0KKw0KKwkJCXNyX3JlYWRfcmVnKGRldiwgTlNSLCAmdmFsdWUpOw0KKwkJCWlmICh2YWx1ZSAm IE5TUl9MSU5LU1QpDQorCQkJCQlyYyA9IDE7DQorCX0NCisJc3Jfc2hhcmVfcmVhZF93b3JkKGRl diwgMSwgbG9jLCAmcmVzKTsNCisJaWYgKHJjID09IDEpDQorCQkJcmV0dXJuIGxlMTZfdG9fY3B1 KHJlcykgfCBCTVNSX0xTVEFUVVM7DQorCWVsc2UNCisJCQlyZXR1cm4gbGUxNl90b19jcHUocmVz KSAmIH5CTVNSX0xTVEFUVVM7DQorDQorCW5ldGRldl9kYmcoZGV2LT5uZXQsDQorCSAgICAgICAi c3JfbWRpb19yZWFkKCkgcGh5X2lkPTB4JTAyeCwgbG9jPTB4JTAyeCwgcmV0dXJucz0weCUwNHhc biIsDQorCSAgICAgICBwaHlfaWQsIGxvYywgbGUxNl90b19jcHUocmVzKSk7DQorDQorCXJldHVy biBsZTE2X3RvX2NwdShyZXMpOw0KK30NCisNCitzdGF0aWMgdm9pZCBzcl9tZGlvX3dyaXRlKHN0 cnVjdCBuZXRfZGV2aWNlICpuZXRkZXYsIGludCBwaHlfaWQsIGludCBsb2MsIGludCB2YWwpDQor ew0KKwlzdHJ1Y3QgdXNibmV0ICpkZXYgPSBuZXRkZXZfcHJpdihuZXRkZXYpOw0KKwlfX2xlMTYg cmVzID0gY3B1X3RvX2xlMTYodmFsKTsNCisNCisJaWYgKHBoeV9pZCkgew0KKwkJbmV0ZGV2X2Ri ZyhkZXYtPm5ldCwgIk9ubHkgaW50ZXJuYWwgcGh5IHN1cHBvcnRlZFxuIik7DQorCQlyZXR1cm47 DQorCX0NCisNCisJbmV0ZGV2X2RiZyhkZXYtPm5ldCwgInNyX21kaW9fd3JpdGUoKSBwaHlfaWQ9 MHglMDJ4LCBsb2M9MHglMDJ4LCB2YWw9MHglMDR4XG4iLA0KKwkgICAgICAgcGh5X2lkLCBsb2Ms IHZhbCk7DQorDQorCXNyX3NoYXJlX3dyaXRlX3dvcmQoZGV2LCAxLCBsb2MsIHJlcyk7DQorfQ0K Kw0KK3N0YXRpYyB1MzIgc3I5NzAwX2dldF9saW5rKHN0cnVjdCBuZXRfZGV2aWNlICpuZXQpDQor ew0KKwlzdHJ1Y3QgdXNibmV0ICpkZXYgPSBuZXRkZXZfcHJpdihuZXQpOw0KKwlpbnQgcmMgPSAw Ow0KKwl1OCB2YWx1ZSA9IDA7DQorDQorCS8qIEdldCB0aGUgTGluayBTdGF0dXMgZGlyZWN0bHkg Ki8NCisJc3JfcmVhZF9yZWcoZGV2LCBOU1IsICZ2YWx1ZSk7DQorCWlmICh2YWx1ZSAmIE5TUl9M SU5LU1QpDQorCQlyYyA9IDE7DQorDQorCXJldHVybiByYzsNCit9DQorDQorc3RhdGljIGludCBz cjk3MDBfaW9jdGwoc3RydWN0IG5ldF9kZXZpY2UgKm5ldCwgc3RydWN0IGlmcmVxICpycSwgaW50 IGNtZCkNCit7DQorCXN0cnVjdCB1c2JuZXQgKmRldiA9IG5ldGRldl9wcml2KG5ldCk7DQorDQor CXJldHVybiBnZW5lcmljX21paV9pb2N0bCgmZGV2LT5taWksIGlmX21paShycSksIGNtZCwgTlVM TCk7DQorfQ0KKw0KK3N0YXRpYyBjb25zdCBzdHJ1Y3QgZXRodG9vbF9vcHMgc3I5NzAwX2V0aHRv b2xfb3BzID0gew0KKwkuZ2V0X2RydmluZm8JPSB1c2JuZXRfZ2V0X2RydmluZm8sDQorCS5nZXRf bGluawkJPSBzcjk3MDBfZ2V0X2xpbmssDQorCS5nZXRfbXNnbGV2ZWwJPSB1c2JuZXRfZ2V0X21z Z2xldmVsLA0KKwkuc2V0X21zZ2xldmVsCT0gdXNibmV0X3NldF9tc2dsZXZlbCwNCisJLmdldF9l ZXByb21fbGVuCT0gc3I5NzAwX2dldF9lZXByb21fbGVuLA0KKwkuZ2V0X2VlcHJvbQkJPSBzcjk3 MDBfZ2V0X2VlcHJvbSwNCisJLmdldF9zZXR0aW5ncwk9IHVzYm5ldF9nZXRfc2V0dGluZ3MsDQor CS5zZXRfc2V0dGluZ3MJPSB1c2JuZXRfc2V0X3NldHRpbmdzLA0KKwkubndheV9yZXNldAkJPSB1 c2JuZXRfbndheV9yZXNldCwNCit9Ow0KKw0KK3N0YXRpYyB2b2lkIHNyOTcwMF9zZXRfbXVsdGlj YXN0KHN0cnVjdCBuZXRfZGV2aWNlICpuZXQpDQorew0KKwlzdHJ1Y3QgdXNibmV0ICpkZXYgPSBu ZXRkZXZfcHJpdihuZXQpOw0KKwkvKiBXZSB1c2UgdGhlIDIwIGJ5dGUgZGV2LT5kYXRhIGZvciBv dXIgOCBieXRlIGZpbHRlciBidWZmZXINCisJICogdG8gYXZvaWQgYWxsb2NhdGluZyBtZW1vcnkg dGhhdCBpcyB0cmlja3kgdG8gZnJlZSBsYXRlcg0KKwkgKi8NCisJdTggKmhhc2hlcyA9ICh1OCAq KSAmZGV2LT5kYXRhOw0KKwkvKiByeF9jdGwgc2V0dGluZyA6IGVuYWJsZSwgZGlzYWJsZV9sb25n LCBkaXNhYmxlX2NyYyAqLw0KKwl1OCByeF9jdGwgPSBSQ1JfUlhFTiB8IFJDUl9ESVNfQ1JDIHwg UkNSX0RJU19MT05HOw0KKw0KKwltZW1zZXQoaGFzaGVzLCAweDAwLCBTUl9NQ0FTVF9TSVpFKTsN CisJaGFzaGVzW1NSX01DQVNUX1NJWkUgLSAxXSB8PSBTUl9NQ0FTVF9BRERSX0ZMQUc7CS8qIGJy b2FkY2FzdCBhZGRyZXNzICovDQorDQorCWlmIChuZXQtPmZsYWdzICYgSUZGX1BST01JU0MpIHsN CisJCQlyeF9jdGwgfD0gUkNSX1BSTVNDOw0KKwl9IGVsc2UgaWYgKG5ldC0+ZmxhZ3MgJiBJRkZf QUxMTVVMVEkgfHwNCisJCQkJCW5ldGRldl9tY19jb3VudChuZXQpID4gU1JfTUNBU1RfTUFYKSB7 DQorCQkJcnhfY3RsIHw9IFJDUl9SVU5UOw0KKwl9IGVsc2UgaWYgKCFuZXRkZXZfbWNfZW1wdHko bmV0KSkgew0KKwkJCXN0cnVjdCBuZXRkZXZfaHdfYWRkciAqaGE7DQorCQkJbmV0ZGV2X2Zvcl9l YWNoX21jX2FkZHIoaGEsIG5ldCkgew0KKwkJCQkJdTMyIGNyYyA9IGV0aGVyX2NyYyhFVEhfQUxF TiwgaGEtPmFkZHIpID4+IDI2Ow0KKwkJCQkJaGFzaGVzW2NyYyA+PiAzXSB8PSAxIDw8IChjcmMg JiAweDcpOw0KKwkJCX0NCisJfQ0KKw0KKwlzcl93cml0ZV9hc3luYyhkZXYsIE1BUiwgU1JfTUNB U1RfU0laRSwgaGFzaGVzKTsNCisJc3Jfd3JpdGVfcmVnX2FzeW5jKGRldiwgUkNSLCByeF9jdGwp Ow0KK30NCisNCitzdGF0aWMgaW50IHNyOTcwMF9zZXRfbWFjX2FkZHJlc3Moc3RydWN0IG5ldF9k ZXZpY2UgKm5ldCwgdm9pZCAqcCkNCit7DQorCXN0cnVjdCBzb2NrYWRkciAqYWRkciA9IHA7DQor CXN0cnVjdCB1c2JuZXQgKmRldiA9IG5ldGRldl9wcml2KG5ldCk7DQorDQorCWlmICghaXNfdmFs aWRfZXRoZXJfYWRkcihhZGRyLT5zYV9kYXRhKSkgew0KKwkJbmV0ZGV2X2VycihuZXQsICJub3Qg c2V0dGluZyBpbnZhbGlkIG1hYyBhZGRyZXNzICVwTVxuIiwNCisJCQkJCQlhZGRyLT5zYV9kYXRh KTsNCisJCXJldHVybiAtRUlOVkFMOw0KKwl9DQorDQorCW1lbWNweShuZXQtPmRldl9hZGRyLCBh ZGRyLT5zYV9kYXRhLCBuZXQtPmFkZHJfbGVuKTsNCisJc3Jfd3JpdGVfYXN5bmMoZGV2LCBQQVIs IDYsIGRldi0+bmV0LT5kZXZfYWRkcik7DQorDQorCXJldHVybiAwOw0KK30NCisNCitzdGF0aWMg Y29uc3Qgc3RydWN0IG5ldF9kZXZpY2Vfb3BzIHNyOTcwMF9uZXRkZXZfb3BzID0gew0KKwkubmRv X29wZW4JCQk9IHVzYm5ldF9vcGVuLA0KKwkubmRvX3N0b3AJCQk9IHVzYm5ldF9zdG9wLA0KKwku bmRvX3N0YXJ0X3htaXQJCT0gdXNibmV0X3N0YXJ0X3htaXQsDQorCS5uZG9fdHhfdGltZW91dAkJ PSB1c2JuZXRfdHhfdGltZW91dCwNCisJLm5kb19jaGFuZ2VfbXR1CQk9IHVzYm5ldF9jaGFuZ2Vf bXR1LA0KKwkubmRvX3ZhbGlkYXRlX2FkZHIJPSBldGhfdmFsaWRhdGVfYWRkciwNCisJLm5kb19k b19pb2N0bAkJPSBzcjk3MDBfaW9jdGwsDQorCS5uZG9fc2V0X3J4X21vZGUJPSBzcjk3MDBfc2V0 X211bHRpY2FzdCwNCisJLm5kb19zZXRfbWFjX2FkZHJlc3MJPSBzcjk3MDBfc2V0X21hY19hZGRy ZXNzLA0KK307DQorDQorc3RhdGljIGludCBzcjk3MDBfYmluZChzdHJ1Y3QgdXNibmV0ICpkZXYs IHN0cnVjdCB1c2JfaW50ZXJmYWNlICppbnRmKQ0KK3sNCisJaW50IHJldDsNCisNCisJcmV0ID0g dXNibmV0X2dldF9lbmRwb2ludHMoZGV2LCBpbnRmKTsNCisJaWYgKHJldCkNCisJCWdvdG8gb3V0 Ow0KKw0KKwlkZXYtPm5ldC0+bmV0ZGV2X29wcyA9ICZzcjk3MDBfbmV0ZGV2X29wczsNCisJZGV2 LT5uZXQtPmV0aHRvb2xfb3BzID0gJnNyOTcwMF9ldGh0b29sX29wczsNCisJZGV2LT5uZXQtPmhh cmRfaGVhZGVyX2xlbiArPSBTUl9UWF9PVkVSSEVBRDsNCisJZGV2LT5oYXJkX210dSA9IGRldi0+ bmV0LT5tdHUgKyBkZXYtPm5ldC0+aGFyZF9oZWFkZXJfbGVuOw0KKwlkZXYtPnJ4X3VyYl9zaXpl ID0gMzA3MjsJLyogYnVsa2luIGJ1ZmZlciBpcyBwcmVmZXJhYmx5IG5vdCBsZXNzIHRoYW4gM0sg Ki8NCisNCisJZGV2LT5taWkuZGV2ID0gZGV2LT5uZXQ7DQorCWRldi0+bWlpLm1kaW9fcmVhZCA9 IHNyX21kaW9fcmVhZDsNCisJZGV2LT5taWkubWRpb193cml0ZSA9IHNyX21kaW9fd3JpdGU7DQor CWRldi0+bWlpLnBoeV9pZF9tYXNrID0gMHgxZjsNCisJZGV2LT5taWkucmVnX251bV9tYXNrID0g MHgxZjsNCisNCisJLyogcmVzZXQgdGhlIHNyOTcwMCAqLw0KKwlzcl93cml0ZV9yZWcoZGV2LCBO Q1IsIDEpOw0KKwl1ZGVsYXkoMjApOw0KKw0KKwkvKiByZWFkIE1BQw0KKwkgKiBBZnRlciBDaGlw IFBvd2VyIG9uLCB0aGUgQ2hpcCB3aWxsIHJlbG9hZCB0aGUgTUFDIGZyb20gRUVQUk9NIGF1dG9t YXRpY2FsbHkgdG8gUEFSDQorCSAqIEluIGNhc2UgdGhlcmUgaXMgbm8gRUVQUk9NIGV4dGVybmFs bHksIGEgZGVmYXVsdCBNQUMgYWRkcmVzcyBpcyBzdG9yZWQgaW4gUEFSIGZvciBtYWtpbmcgY2hp cCB3b3JrIHByb3Blcmx5DQorCSAqLw0KKwlpZiAoc3JfcmVhZChkZXYsIFBBUiwgRVRIX0FMRU4s IGRldi0+bmV0LT5kZXZfYWRkcikgPCAwKSB7DQorCQluZXRkZXZfZXJyKGRldi0+bmV0LCAiRXJy b3IgcmVhZGluZyBNQUMgYWRkcmVzc1xuIik7DQorCQlyZXQgPSAtRU5PREVWOw0KKwkJZ290byBv dXQ7DQorCX0NCisNCisJLyogcG93ZXIgdXAgYW5kIHJlc2V0IHBoeSAqLw0KKwlzcl93cml0ZV9y ZWcoZGV2LCBQUlIsIDEpOw0KKwltZGVsYXkoMjApOwkJLyogYXQgbGVhc3QgMTBtcywgaGVyZSAy MG1zIGZvciBzYWZlICovDQorCXNyX3dyaXRlX3JlZyhkZXYsIFBSUiwgMCk7DQorCXVkZWxheSgy ICogMTAwMCk7CS8qIGF0IGxlYXN0IDFtcywgaGVyZSAybXMgZm9yIHJlYWRpbmcgcmlnaHQgcmVn aXN0ZXIgKi8NCisNCisJLyogcmVjZWl2ZSBicm9hZGNhc3QgcGFja2V0cyAqLw0KKwlzcjk3MDBf c2V0X211bHRpY2FzdChkZXYtPm5ldCk7DQorDQorCXNyX21kaW9fd3JpdGUoZGV2LT5uZXQsIGRl di0+bWlpLnBoeV9pZCwgTUlJX0JNQ1IsIEJNQ1JfUkVTRVQpOw0KKwlzcl9tZGlvX3dyaXRlKGRl di0+bmV0LCBkZXYtPm1paS5waHlfaWQsIE1JSV9BRFZFUlRJU0UsIEFEVkVSVElTRV9BTEwgfCBB RFZFUlRJU0VfQ1NNQSB8IEFEVkVSVElTRV9QQVVTRV9DQVApOw0KKwltaWlfbndheV9yZXN0YXJ0 KCZkZXYtPm1paSk7DQorDQorb3V0Og0KKwlyZXR1cm4gcmV0Ow0KK30NCisNCitzdGF0aWMgaW50 IHNyOTcwMF9yeF9maXh1cChzdHJ1Y3QgdXNibmV0ICpkZXYsIHN0cnVjdCBza19idWZmICpza2Ip DQorew0KKwlpbnQgbGVuOw0KKwlzdHJ1Y3Qgc2tfYnVmZiAqc3Jfc2tiOw0KKw0KKwkvKiBmb3Jt YXQ6DQorCSAgIGIwOiByeCBzdGF0dXMNCisJICAgYjE6IHBhY2tldCBsZW5ndGggKGluY2wgY3Jj KSBsb3cNCisJICAgYjI6IHBhY2tldCBsZW5ndGggKGluY2wgY3JjKSBoaWdoDQorCSAgIGIzLi5u LTQ6IHBhY2tldCBkYXRhDQorCSAgIGJuLTMuLmJuOiBldGhlcm5ldCBjcmMNCisJICovDQorDQor CWlmICh1bmxpa2VseShza2ItPmxlbiA8IFNSX1JYX09WRVJIRUFEKSkgew0KKwkJbmV0ZGV2X2Vy cihkZXYtPm5ldCwgInVuZXhwZWN0ZWQgdGlueSByeCBmcmFtZVxuIik7DQorCQlyZXR1cm4gMDsN CisJfQ0KKw0KKwkvKiBFYWNoIHBhY2tldCBjb250YWlucyBtdWx0aXBsZSBza2JzICovDQorCXdo aWxlIChza2ItPmxlbiA+IFNSX1JYX09WRVJIRUFEKSB7DQorCQlpZiAoc2tiLT5kYXRhWzBdICE9 IDB4NDApDQorCQkJcmV0dXJuIDA7DQorDQorCQkvKiBpZ25vcmUgdGhlIENSQyBsZW5ndGggKi8N CisJCWxlbiA9IChza2ItPmRhdGFbMV0gfCAoc2tiLT5kYXRhWzJdIDw8IDgpKSAtIDQ7DQorDQor CQlpZiAobGVuID4gRVRIX0ZSQU1FX0xFTikNCisJCQlyZXR1cm4gMDsNCisNCisJCS8qIHRoZSBs YXN0IHNrYiBvZiBjdXJyZW50IHBhY2tldCAqLw0KKwkJaWYgKHNrYi0+bGVuID09IChsZW4gKyBT Ul9SWF9PVkVSSEVBRCkpCXsNCisJCQlza2JfcHVsbChza2IsIDMpOw0KKwkJCXNrYi0+bGVuID0g bGVuOw0KKwkJCXNrYi0+dGFpbCA9IHNrYi0+ZGF0YSArIGxlbjsNCisJCQlza2ItPnRydWVzaXpl ID0gbGVuICsgc2l6ZW9mKHN0cnVjdCBza19idWZmKTsNCisJCQlyZXR1cm4gMjsNCisJCX0NCisN CisJCS8qIHNrYl9jbG9uZSBpcyB1c2VkIGZvciBhZGRyZXNzIGFsaWduICovDQorCQlzcl9za2Ig PSBza2JfY2xvbmUoc2tiLCBHRlBfQVRPTUlDKTsNCisJCWlmIChzcl9za2IpIHsNCisJCQlzcl9z a2ItPmxlbiA9IGxlbjsNCisJCQlzcl9za2ItPmRhdGEgPSBza2ItPmRhdGEgKyAzOw0KKwkJCXNy X3NrYi0+dGFpbCA9IHNrYi0+ZGF0YSArIGxlbjsNCisJCQlzcl9za2ItPnRydWVzaXplID0gbGVu ICsgc2l6ZW9mKHN0cnVjdCBza19idWZmKTsNCisJCQl1c2JuZXRfc2tiX3JldHVybihkZXYsIHNy X3NrYik7DQorCQl9IGVsc2Ugew0KKwkJCXJldHVybiAwOw0KKwkJfQ0KKw0KKwkJc2tiX3B1bGwo c2tiLCBsZW4gKyBTUl9SWF9PVkVSSEVBRCk7DQorCX07DQorDQorCXJldHVybiAwOw0KK30NCisN CitzdGF0aWMgc3RydWN0IHNrX2J1ZmYgKnNyOTcwMF90eF9maXh1cChzdHJ1Y3QgdXNibmV0ICpk ZXYsIHN0cnVjdCBza19idWZmICpza2IsIGdmcF90IGZsYWdzKQ0KK3sNCisJaW50IGxlbjsNCisN CisJLyogZm9ybWF0Og0KKwkgICBiMDogcGFja2V0IGxlbmd0aCBsb3cNCisJICAgYjE6IHBhY2tl dCBsZW5ndGggaGlnaA0KKwkgICBiMy4ubjogcGFja2V0IGRhdGENCisJKi8NCisNCisJbGVuID0g c2tiLT5sZW47DQorDQorCWlmIChza2JfaGVhZHJvb20oc2tiKSA8IFNSX1RYX09WRVJIRUFEKSB7 DQorCQlzdHJ1Y3Qgc2tfYnVmZiAqc2tiMjsNCisNCisJCXNrYjIgPSBza2JfY29weV9leHBhbmQo c2tiLCBTUl9UWF9PVkVSSEVBRCwgMCwgZmxhZ3MpOw0KKwkJZGV2X2tmcmVlX3NrYl9hbnkoc2ti KTsNCisJCXNrYiA9IHNrYjI7DQorCQlpZiAoIXNrYikNCisJCQlyZXR1cm4gTlVMTDsNCisJfQ0K Kw0KKwlfX3NrYl9wdXNoKHNrYiwgU1JfVFhfT1ZFUkhFQUQpOw0KKw0KKwkvKiB1c2JuZXQgYWRk cyBwYWRkaW5nIGlmIGxlbmd0aCBpcyBhIG11bHRpcGxlIG9mIHBhY2tldCBzaXplDQorCSAqIGlm IHNvLCBhZGp1c3QgbGVuZ3RoIHZhbHVlIGluIGhlYWRlcg0KKwkgKi8NCisJaWYgKChza2ItPmxl biAlIGRldi0+bWF4cGFja2V0KSA9PSAwKQ0KKwkJbGVuKys7DQorDQorCXNrYi0+ZGF0YVswXSA9 IGxlbjsNCisJc2tiLT5kYXRhWzFdID0gbGVuID4+IDg7DQorDQorCXJldHVybiBza2I7DQorfQ0K Kw0KK3N0YXRpYyB2b2lkIHNyOTcwMF9zdGF0dXMoc3RydWN0IHVzYm5ldCAqZGV2LCBzdHJ1Y3Qg dXJiICp1cmIpDQorew0KKwlpbnQgbGluazsNCisJdTggKmJ1ZjsNCisNCisJLyogZm9ybWF0Og0K KwkgICBiMDogbmV0IHN0YXR1cw0KKwkgICBiMTogdHggc3RhdHVzIDENCisJICAgYjI6IHR4IHN0 YXR1cyAyDQorCSAgIGIzOiByeCBzdGF0dXMNCisJICAgYjQ6IHJ4IG92ZXJmbG93DQorCSAgIGI1 OiByeCBjb3VudA0KKwkgICBiNjogdHggY291bnQNCisJICAgYjc6IGdwcg0KKwkqLw0KKw0KKwlp ZiAodXJiLT5hY3R1YWxfbGVuZ3RoIDwgOCkNCisJCXJldHVybjsNCisNCisJYnVmID0gdXJiLT50 cmFuc2Zlcl9idWZmZXI7DQorDQorCWxpbmsgPSAhIShidWZbMF0gJiAweDQwKTsNCisJaWYgKG5l dGlmX2NhcnJpZXJfb2soZGV2LT5uZXQpICE9IGxpbmspIHsNCisJCXVzYm5ldF9saW5rX2NoYW5n ZShkZXYsIGxpbmssIDEpOw0KKwkJbmV0ZGV2X2RiZyhkZXYtPm5ldCwgIkxpbmsgU3RhdHVzIGlz OiAlZFxuIiwgbGluayk7DQorCX0NCit9DQorDQorc3RhdGljIGludCBzcjk3MDBfbGlua19yZXNl dChzdHJ1Y3QgdXNibmV0ICpkZXYpDQorew0KKwlzdHJ1Y3QgZXRodG9vbF9jbWQgZWNtZDsNCisN CisJbWlpX2NoZWNrX21lZGlhKCZkZXYtPm1paSwgMSwgMSk7DQorCW1paV9ldGh0b29sX2dzZXQo JmRldi0+bWlpLCAmZWNtZCk7DQorDQorCW5ldGRldl9kYmcoZGV2LT5uZXQsICJsaW5rX3Jlc2V0 KCkgc3BlZWQ6ICVkIGR1cGxleDogJWRcbiIsDQorCSAgICAgICBlY21kLnNwZWVkLCBlY21kLmR1 cGxleCk7DQorDQorCXJldHVybiAwOw0KK30NCisNCitzdGF0aWMgY29uc3Qgc3RydWN0IGRyaXZl cl9pbmZvIHNyOTcwMF9kcml2ZXJfaW5mbyA9IHsNCisJLmRlc2NyaXB0aW9uCT0gIkNvcmVDaGlw IFNSOTcwMCBVU0IgRXRoZXJuZXQiLA0KKwkuZmxhZ3MJCT0gRkxBR19FVEhFUiwNCisJLmJpbmQJ CT0gc3I5NzAwX2JpbmQsDQorCS5yeF9maXh1cAk9IHNyOTcwMF9yeF9maXh1cCwNCisJLnR4X2Zp eHVwCT0gc3I5NzAwX3R4X2ZpeHVwLA0KKwkuc3RhdHVzCQk9IHNyOTcwMF9zdGF0dXMsDQorCS5s aW5rX3Jlc2V0CT0gc3I5NzAwX2xpbmtfcmVzZXQsDQorCS5yZXNldAkJPSBzcjk3MDBfbGlua19y ZXNldCwNCit9Ow0KKw0KK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdXNiX2RldmljZV9pZCBwcm9kdWN0 c1tdID0gew0KKwl7DQorCSBVU0JfREVWSUNFKDB4MGZlNiwgMHg5NzAwKSwJLyogU1I5NzAwIGRl dmljZSAqLw0KKwkgLmRyaXZlcl9pbmZvID0gKHVuc2lnbmVkIGxvbmcpJnNyOTcwMF9kcml2ZXJf aW5mbywNCisJIH0sDQorCXt9LAkJCS8qIEVORCAqLw0KK307DQorDQorTU9EVUxFX0RFVklDRV9U QUJMRSh1c2IsIHByb2R1Y3RzKTsNCisNCitzdGF0aWMgc3RydWN0IHVzYl9kcml2ZXIgc3I5NzAw X3VzYl9kcml2ZXIgPSB7DQorCS5uYW1lID0gInNyOTcwMCIsDQorCS5pZF90YWJsZSA9IHByb2R1 Y3RzLA0KKwkucHJvYmUgPSB1c2JuZXRfcHJvYmUsDQorCS5kaXNjb25uZWN0ID0gdXNibmV0X2Rp c2Nvbm5lY3QsDQorCS5zdXNwZW5kID0gdXNibmV0X3N1c3BlbmQsDQorCS5yZXN1bWUgPSB1c2Ju ZXRfcmVzdW1lLA0KKwkuZGlzYWJsZV9odWJfaW5pdGlhdGVkX2xwbSA9IDEsDQorfTsNCisNCitt b2R1bGVfdXNiX2RyaXZlcihzcjk3MDBfdXNiX2RyaXZlcik7DQorDQorTU9EVUxFX0FVVEhPUigi bGl1amwgPGxpdWp1bmxpYW5nX2xqbEAxNjMuY29tPiIpOw0KK01PRFVMRV9ERVNDUklQVElPTigi U1I5NzAwIG9uZSBjaGlwIFVTQiAxLjEgVVNCIHRvIEV0aGVybmV0IGRldmljZSBmcm9tIGh0dHA6 Ly93d3cuY29yZWNoaXAtc3ouY29tLyIpOw0KK01PRFVMRV9MSUNFTlNFKCJHUEwiKTsNCmRpZmYg LS1naXQgYS9kcml2ZXJzL25ldC91c2Ivc3I5NzAwLmggYi9kcml2ZXJzL25ldC91c2Ivc3I5NzAw LmgNCm5ldyBmaWxlIG1vZGUgMTAwNjQ0DQppbmRleCAwMDAwMDAwLi5mMTk2OGFlDQotLS0gL2Rl di9udWxsDQorKysgYi9kcml2ZXJzL25ldC91c2Ivc3I5NzAwLmgNCkBAIC0wLDAgKzEsMTcyIEBA DQorLyoNCisgKiBDb3JlQ2hpcC1zeiBTUjk3MDAgb25lIGNoaXAgVVNCIDEuMSBFdGhlcm5ldCBE ZXZpY2VzDQorICoNCisgKiBBdXRob3IgOiBsaXVqbCA8bGl1anVubGlhbmdfbGpsQDE2My5jb20+ DQorICoNCisgKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3Ry aWJ1dGUgaXQgYW5kL29yDQorICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05V IEdlbmVyYWwgUHVibGljIExpY2Vuc2UNCisgKiB2ZXJzaW9uIDIgYXMgcHVibGlzaGVkIGJ5IHRo ZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uDQorICovDQorDQorI2lmbmRlZiBfU1I5NzAwX0gN CisjZGVmaW5lCV9TUjk3MDBfSA0KKw0KKy8qIHNyOTcwMCBzcGVjLiByZWdpc3RlciB0YWJsZSBv biBMaW51eCBwbGF0Zm9ybSAqLw0KKw0KKy8qIE5ldHdvcmsgQ29udHJvbCBSZWcgKi8NCisjZGVm aW5lCU5DUgkJCTB4MDANCisjZGVmaW5lCQlOQ1JfUlNUCQkJKDEgPDwgMCkNCisjZGVmaW5lCQlO Q1JfTEJLCQkJKDMgPDwgMSkNCisjZGVmaW5lCQlOQ1JfRkRYCQkJKDEgPDwgMykNCisjZGVmaW5l CQlOQ1JfV0FLRUVOCQkoMSA8PCA2KQ0KKy8qIE5ldHdvcmsgU3RhdHVzIFJlZyAqLw0KKyNkZWZp bmUJTlNSCQkJMHgwMQ0KKyNkZWZpbmUJCU5TUl9SWFJEWQkJKDEgPDwgMCkNCisjZGVmaW5lCQlO U1JfUlhPVgkJKDEgPDwgMSkNCisjZGVmaW5lCQlOU1JfVFgxRU5ECQkoMSA8PCAyKQ0KKyNkZWZp bmUJCU5TUl9UWDJFTkQJCSgxIDw8IDMpDQorI2RlZmluZQkJTlNSX1RYRlVMTAkJKDEgPDwgNCkN CisjZGVmaW5lCQlOU1JfV0FLRVNUCQkoMSA8PCA1KQ0KKyNkZWZpbmUJCU5TUl9MSU5LU1QJCSgx IDw8IDYpDQorI2RlZmluZQkJTlNSX1NQRUVECQkoMSA8PCA3KQ0KKy8qIFR4IENvbnRyb2wgUmVn ICovDQorI2RlZmluZQlUQ1IJCQkweDAyDQorI2RlZmluZQkJVENSX0NSQ19ESVMJCSgxIDw8IDEp DQorI2RlZmluZQkJVENSX1BBRF9ESVMJCSgxIDw8IDIpDQorI2RlZmluZQkJVENSX0xDX0NBUkUJ CSgxIDw8IDMpDQorI2RlZmluZQkJVENSX0NSU19DQVJFCSgxIDw8IDQpDQorI2RlZmluZQkJVENS X0VYQ0VDTQkJKDEgPDwgNSkNCisjZGVmaW5lCQlUQ1JfTEZfRU4JCSgxIDw8IDYpDQorLyogVHgg U3RhdHVzIFJlZyBmb3IgUGFja2V0IEluZGV4IDEgKi8NCisjZGVmaW5lCVRTUjEJCTB4MDMNCisj ZGVmaW5lCQlUU1IxX0VDCQkJKDEgPDwgMikNCisjZGVmaW5lCQlUU1IxX0NPTAkJKDEgPDwgMykN CisjZGVmaW5lCQlUU1IxX0xDCQkJKDEgPDwgNCkNCisjZGVmaW5lCQlUU1IxX05DCQkJKDEgPDwg NSkNCisjZGVmaW5lCQlUU1IxX0xPQwkJKDEgPDwgNikNCisjZGVmaW5lCQlUU1IxX1RMRgkJKDEg PDwgNykNCisvKiBUeCBTdGF0dXMgUmVnIGZvciBQYWNrZXQgSW5kZXggMiAqLw0KKyNkZWZpbmUJ VFNSMgkJMHgwNA0KKyNkZWZpbmUJCVRTUjJfRUMJCQkoMSA8PCAyKQ0KKyNkZWZpbmUJCVRTUjJf Q09MCQkoMSA8PCAzKQ0KKyNkZWZpbmUJCVRTUjJfTEMJCQkoMSA8PCA0KQ0KKyNkZWZpbmUJCVRT UjJfTkMJCQkoMSA8PCA1KQ0KKyNkZWZpbmUJCVRTUjJfTE9DCQkoMSA8PCA2KQ0KKyNkZWZpbmUJ CVRTUjJfVExGCQkoMSA8PCA3KQ0KKy8qIFJ4IENvbnRyb2wgUmVnKi8NCisjZGVmaW5lCVJDUgkJ CTB4MDUNCisjZGVmaW5lCQlSQ1JfUlhFTgkJKDEgPDwgMCkNCisjZGVmaW5lCQlSQ1JfUFJNU0MJ CSgxIDw8IDEpDQorI2RlZmluZQkJUkNSX1JVTlQJCSgxIDw8IDIpDQorI2RlZmluZQkJUkNSX0FM TAkJCSgxIDw8IDMpDQorI2RlZmluZQkJUkNSX0RJU19DUkMJCSgxIDw8IDQpDQorI2RlZmluZQkJ UkNSX0RJU19MT05HCSgxIDw8IDUpDQorLyogUnggU3RhdHVzIFJlZyAqLw0KKyNkZWZpbmUJUlNS CQkJMHgwNg0KKyNkZWZpbmUJCVJTUl9BRQkJCSgxIDw8IDIpDQorI2RlZmluZQkJUlNSX01GCQkJ KDEgPDwgNikNCisjZGVmaW5lCQlSU1JfUkYJCQkoMSA8PCA3KQ0KKy8qIFJ4IE92ZXJmbG93IENv dW50ZXIgUmVnICovDQorI2RlZmluZQlST0NSCQkweDA3DQorI2RlZmluZQkJUk9DUl9ST0MJCSgw eDdGIDw8IDApDQorI2RlZmluZQkJUk9DUl9SWEZVCQkoMSA8PCA3KQ0KKy8qIEJhY2sgUHJlc3N1 cmUgVGhyZXNob2xkIFJlZyAqLw0KKyNkZWZpbmUJQlBUUgkJMHgwOA0KKyNkZWZpbmUJCUJQVFJf SlBUCQkoMHgwRiA8PCAwKQ0KKyNkZWZpbmUJCUJQVFJfQlBIVwkJKDB4MEYgPDwgNCkNCisvKiBG bG93IENvbnRyb2wgVGhyZXNob2xkIFJlZyAqLw0KKyNkZWZpbmUJRkNUUgkJMHgwOQ0KKyNkZWZp bmUJCUZDVFJfTFdPVAkJKDB4MEYgPDwgMCkNCisjZGVmaW5lCQlGQ1RSX0hXT1QJCSgweDBGIDw8 IDQpDQorLyogcngvdHggRmxvdyBDb250cm9sIFJlZyAqLw0KKyNkZWZpbmUJRkNSCQkJMHgwQQ0K KyNkZWZpbmUJCUZDUl9GTENFCQkoMSA8PCAwKQ0KKyNkZWZpbmUJCUZDUl9CS1BBCQkoMSA8PCA0 KQ0KKyNkZWZpbmUJCUZDUl9UWFBFTgkJKDEgPDwgNSkNCisjZGVmaW5lCQlGQ1JfVFhQRgkJKDEg PDwgNikNCisjZGVmaW5lCQlGQ1JfVFhQMAkJKDEgPDwgNykNCisvKiBFZXByb20gJiBQaHkgQ29u dHJvbCBSZWcgKi8NCisjZGVmaW5lCUVQQ1IJCTB4MEINCisjZGVmaW5lCQlFUENSX0VSUkUJCSgx IDw8IDApDQorI2RlZmluZQkJRVBDUl9FUlBSVwkJKDEgPDwgMSkNCisjZGVmaW5lCQlFUENSX0VS UFJSCQkoMSA8PCAyKQ0KKyNkZWZpbmUJCUVQQ1JfRVBPUwkJKDEgPDwgMykNCisjZGVmaW5lCQlF UENSX1dFUAkJKDEgPDwgNCkNCisvKiBFZXByb20gJiBQaHkgQWRkcmVzcyBSZWcgKi8NCisjZGVm aW5lCUVQQVIJCTB4MEMNCisjZGVmaW5lCQlFUEFSX0VST0EJCSgweDNGIDw8IDApDQorI2RlZmlu ZQkJRVBBUl9QSFlfQURSCSgweDAzIDw8IDYpDQorLyogRWVwcm9tICYJUGh5IERhdGEgUmVnICov DQorI2RlZmluZQlFUERSCQkweDBECS8qIDB4MEQgfiAweDBFIGZvciBEYXRhIFJlZyBMb3cgJiBI aWdoICovDQorLyogV2FrZXVwIENvbnRyb2wgUmVnICovDQorI2RlZmluZQlXQ1IJCQkweDBGDQor I2RlZmluZQkJV0NSX01BR0lDU1QJCSgxIDw8IDApDQorI2RlZmluZQkJV0NSX0xJTktTVAkJKDEg PDwgMikNCisjZGVmaW5lCQlXQ1JfTUFHSUNFTgkJKDEgPDwgMykNCisjZGVmaW5lCQlXQ1JfTElO S0VOCQkoMSA8PCA1KQ0KKy8qIFBoeXNpY2FsIEFkZHJlc3MgUmVnICovDQorI2RlZmluZQlQQVIJ CQkweDEwCS8qIDB4MTAgfiAweDE1IDYgYnl0ZXMgZm9yIFBBUiAqLw0KKy8qIE11bHRpY2FzdCBB ZGRyZXNzIFJlZyAqLw0KKyNkZWZpbmUJTUFSCQkJMHgxNgkvKiAweDE2IH4gMHgxRCA4IGJ5dGVz IGZvciBNQVIgKi8NCisvKiAweDFlIHVudXNlZCAqLw0KKy8qIFBoeSBSZXNldCBSZWcgKi8NCisj ZGVmaW5lCVBSUgkJCTB4MUYNCisjZGVmaW5lCQlQUlJfUEhZX1JTVAkJKDEgPDwgMCkNCisvKiBU eCBzZHJhbSBXcml0ZSBQb2ludGVyIEFkZHJlc3MgTG93ICovDQorI2RlZmluZQlUV1BBTAkJMHgy MA0KKy8qIFR4IHNkcmFtIFdyaXRlIFBvaW50ZXIgQWRkcmVzcyBIaWdoICovDQorI2RlZmluZQlU V1BBSAkJMHgyMQ0KKy8qIFR4IHNkcmFtIFJlYWQgUG9pbnRlciBBZGRyZXNzIExvdyAqLw0KKyNk ZWZpbmUJVFJQQUwJCTB4MjINCisvKiBUeCBzZHJhbSBSZWFkIFBvaW50ZXIgQWRkcmVzcyBIaWdo ICovDQorI2RlZmluZQlUUlBBSAkJMHgyMw0KKy8qIFJ4IHNkcmFtIFdyaXRlIFBvaW50ZXIgQWRk cmVzcyBMb3cgKi8NCisjZGVmaW5lCVJXUEFMCQkweDI0DQorLyogUnggc2RyYW0gV3JpdGUgUG9p bnRlciBBZGRyZXNzIEhpZ2ggKi8NCisjZGVmaW5lCVJXUEFICQkweDI1DQorLyogUnggc2RyYW0g UmVhZCBQb2ludGVyIEFkZHJlc3MgTG93ICovDQorI2RlZmluZQlSUlBBTAkJMHgyNg0KKy8qIFJ4 IHNkcmFtIFJlYWQgUG9pbnRlciBBZGRyZXNzIEhpZ2ggKi8NCisjZGVmaW5lCVJSUEFICQkweDI3 DQorLyogVmVuZG9yIElEIHJlZ2lzdGVyICovDQorI2RlZmluZQlWSUQJCQkweDI4CS8qIDB4Mjgg fiAweDI5IDIgYnl0ZXMgZm9yIFZJRCAqLw0KKy8qIFByb2R1Y3QgSUQgcmVnaXN0ZXIgKi8NCisj ZGVmaW5lCVBJRAkJCTB4MkEJLyogMHgyQSB+IDB4MkIgMiBieXRlcyBmb3IgUElEICovDQorLyog Q0hJUCBSZXZpc2lvbiByZWdpc3RlciAqLw0KKyNkZWZpbmUJQ0hJUFIJCTB4MkMNCisvKiAweDJE IC0tPiAweEVGIHVudXNlZCAqLw0KKy8qIFVTQiBEZXZpY2UgQWRkcmVzcyAqLw0KKyNkZWZpbmUJ VVNCREEJCTB4RjANCisjZGVmaW5lCQlVU0JEQV9VU0JGQQkJKDB4N0YgPDwgMCkNCisvKiBSWCBw YWNrZXQgQ291bnRlciBSZWcgKi8NCisjZGVmaW5lCVJYQwkJCTB4RjENCisvKiBUeCBwYWNrZXQg Q291bnRlciAmIFVTQiBTdGF0dXMgUmVnICovDQorI2RlZmluZQlUWENfVVNCUwkweEYyDQorI2Rl ZmluZQkJVFhDX1VTQlNfVFhDMAkJKDEgPDwgMCkNCisjZGVmaW5lCQlUWENfVVNCU19UWEMxCQko MSA8PCAxKQ0KKyNkZWZpbmUJCVRYQ19VU0JTX1RYQzIJCSgxIDw8IDIpDQorI2RlZmluZQkJVFhD X1VTQlNfRVAxUkRZCQkoMSA8PCA1KQ0KKyNkZWZpbmUJCVRYQ19VU0JTX1NVU0ZMQUcJKDEgPDwg NikNCisjZGVmaW5lCQlUWENfVVNCU19SWEZBVUxUCSgxIDw8IDcpDQorLyogVVNCIENvbnRyb2wg cmVnaXN0ZXIgKi8NCisjZGVmaW5lCVVTQkMJCTB4RjQNCisjZGVmaW5lCQlVU0JDX0VQM05BSwkJ KDEgPDwgNCkNCisjZGVmaW5lCQlVU0JDX0VQM0FDSwkJKDEgPDwgNSkNCisNCisvKiBSZWdpc3Rl ciBhY2Nlc3MgY29tbWFuZHMgYW5kIGZsYWdzICovDQorI2RlZmluZQlTUl9SRF9SRUdTCQkweDAw DQorI2RlZmluZQlTUl9XUl9SRUdTCQkweDAxDQorI2RlZmluZQlTUl9XUl9SRUcJCTB4MDMNCisj ZGVmaW5lCVNSX1JFUV9SRF9SRUcJKFVTQl9ESVJfSU4gfCBVU0JfVFlQRV9WRU5ET1IgfCBVU0Jf UkVDSVBfREVWSUNFKQ0KKyNkZWZpbmUJU1JfUkVRX1dSX1JFRwkoVVNCX0RJUl9PVVQgfCBVU0Jf VFlQRV9WRU5ET1IgfCBVU0JfUkVDSVBfREVWSUNFKQ0KKw0KKy8qIHBhcmFtZXRlcnMgKi8NCisj ZGVmaW5lCVNSX1NIQVJFX1RJTUVPVVQJMTAwMA0KKyNkZWZpbmUJU1JfRUVQUk9NX0xFTgkJMjU2 DQorI2RlZmluZQlTUl9NQ0FTVF9TSVpFCQk4DQorI2RlZmluZQlTUl9NQ0FTVF9BRERSX0ZMQUcJ MHg4MA0KKyNkZWZpbmUJU1JfTUNBU1RfTUFYCQk2NA0KKyNkZWZpbmUJU1JfVFhfT1ZFUkhFQUQJ CTIJLyogMmJ5dGVzIGhlYWRlciAqLw0KKyNkZWZpbmUJU1JfUlhfT1ZFUkhFQUQJCTcJLyogM2J5 dGVzIGhlYWRlciArIDRjcmMgdGFpbCAqLw0KKw0KKyNlbmRpZgkvKiBfU1I5NzAwX0ggKi8NCg0K DQoNCg0KDQoyMDEzLTA4LTIxIA0KDQoNCg0KbGl1anVubGlhbmdfbGpsIA0KDQoNCg0K5Y+R5Lu2 5Lq677yaIEpvZSBQZXJjaGVzIA0K5Y+R6YCB5pe26Ze077yaIDIwMTMtMDgtMjEgIDA0OjU4OjI3 IA0K5pS25Lu25Lq677yaIEZyYW5jb2lzIFJvbWlldSANCuaKhOmAge+8miBsaXVqdW5saWFuZ19s amw7IGdyZWdraDsgc3VuaGVjaGVuZzsgbGludXgtdXNiOyBuZXRkZXY7IGxpbnV4LWtlcm5lbCAN CuS4u+mimO+8miBSZTogW1BBVENILVNSOTcwMF0gTWVyZ2UgVVNCIDEuMSBFdGhlcm5ldCBBZGFw dGVyIFNSOTcwMCBEZXZpY2VEcml2ZXIgaW50byB0aGUgTGludXggS2VybmVsIA0KIA0KT24gVHVl LCAyMDEzLTA4LTIwIGF0IDIyOjQ2ICswMjAwLCBGcmFuY29pcyBSb21pZXUgd3JvdGU6DQo+IGxp dWp1bmxpYW5nX2xqbCA8bGl1anVubGlhbmdfbGpsQDE2My5jb20+IDoNCj4gPiArIGlmIChpID49 IFNSX1NIQVJFX1RJTUVPVVQpIHsNCj4gPiArIG5ldGRldl9lcnIoZGV2LT5uZXQsICIlcyByZWFk IHRpbWVkIG91dCEiLCBwaHkgPyAicGh5IiA6ICJlZXByb20iKTsNCm5ldGRldl88bGV2ZWw+LCBs aWtlIGFsbW9zdCBhbGwgb3RoZXIgcHJpbnRrDQptZXNzYWdlcyBuZWVkcyBhIHRlcm1pbmF0aW5n ICJcbiIgbmV3bGluZSB0bw0KYXZvaWQgYW55IHBvc3NpYmxlIG1lc3NhZ2UgaW50ZXJsZWF2aW5n IGJ5IG90aGVyDQpwcmludGtzLg0KPiA+ICsgaWYgKCFpc192YWxpZF9ldGhlcl9hZGRyKGFkZHIt PnNhX2RhdGEpKSB7DQo+ID4gKyBkZXZfZXJyKCZuZXQtPmRldiwgIm5vdCBzZXR0aW5nIGludmFs aWQgbWFjIGFkZHJlc3MgJXBNXG4iLA0KPiA+ICsgYWRkci0+c2FfZGF0YSk7DQo+IA0KPiAgZGV2 X2VycigmbmV0LT5kZXYsICJub3Qgc2V0dGluZyBpbnZhbGlkIG1hYyBhZGRyZXNzICVwTVxuIiwN Cj4gIGFkZHItPnNhX2RhdGEpOw0KcHJlZmVyIG5ldGRldl88bGV2ZWw+IHRvIGRldl88bGV2ZWw+ IHdoZXJlIHBvc3NpYmxlLg0K