Bluetooth: Add driver extension for vendor specific init
Subsystems (2)
RFC 1/2 Bluetooth: Add driver extension for vendor specific init
From: Tedd Ho-Jeong An <[email protected]>
This patch provides an extension of btusb to support device vendor can implement their own module to execute the vendor specific device initialization before the stack sends generic BT device initialization.
--- drivers/bluetooth/btusb.c | 191 +++++++++++++++++++++++++------------- drivers/bluetooth/btusb.h | 53 +++++++++++ include/net/bluetooth/hci_core.h | 10 ++ net/bluetooth/hci_core.c | 15 ++- 4 files changed, 204 insertions(+), 65 deletions(-) create mode 100644 drivers/bluetooth/btusb.h
drivers/bluetooth/btusb.c +127 -64
@@ -26,6 +26,7 @@#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> +#include "btusb.h" #define VERSION "0.6"
@@ -39,14 +40,59 @@ static bool reset = 1;static struct usb_driver btusb_driver; -#define BTUSB_IGNORE 0x01 -#define BTUSB_DIGIANSWER 0x02 -#define BTUSB_CSR 0x04 -#define BTUSB_SNIFFER 0x08 -#define BTUSB_BCM92035 0x10 -#define BTUSB_BROKEN_ISOC 0x20 -#define BTUSB_WRONG_SCO_MTU 0x40 -#define BTUSB_ATH3012 0x80 +/* +* Create btusb_driver_info struct for each driver_info flags used by +* blacklist since vendor's btusb driver will return btusb_driver_info struct. +*/ + +/* +* if the device is set to this, this menas that the device is generic and +* doesn't require any vendor specific handling +*/ +static const struct btusb_driver_info generic = { + .description ="BTUSB Generic" , + .flags =BTUSB_GENERIC , +}; + +static const struct btusb_driver_info ignore = { + .description ="BTUSB Ignore" , + .flags =BTUSB_IGNORE , +}; + +static const struct btusb_driver_info digianswer = { + .description ="BTUSB DIGIANSWER" , + .flags =BTUSB_DIGIANSWER , +}; + +static const struct btusb_driver_info csr = { + .description ="BTUSB CSR" , + .flags =BTUSB_CSR , +}; + +static const struct btusb_driver_info sniffer = { + .description ="BTUSB Sniffer" , + .flags =BTUSB_SNIFFER , +}; + +static const struct btusb_driver_info bcm92035 = { + .description ="BTUSB BCM92035" , + .flags =BTUSB_BCM92035 , +}; + +static const struct btusb_driver_info broken_isoc = { + .description ="BTUSB Broken ISOC" , + .flags =BTUSB_BROKEN_ISOC , +}; + +static const struct btusb_driver_info wrong_sco_mtu = { + .description ="BTUSB Wrong SCO MTU" , + .flags =BTUSB_WRONG_SCO_MTU , +}; + +static const struct btusb_driver_info ath3012 = { + .description ="BTUSB Ath3012" , + .flags =BTUSB_ATH3012 , +};static struct usb_device_id btusb_table[] = {/* Generic Bluetooth USB device */
@@ -105,90 +151,89 @@ static struct usb_device_id btusb_table[] = { { }/* Terminating entry */ }; -MODULE_DEVICE_TABLE (usb, btusb_table);static struct usb_device_id blacklist_table[] = {/* CSR BlueCore devices */ - {USB_DEVICE (0x0a12 ,0x0001 ), .driver_info =BTUSB_CSR }, + {USB_DEVICE (0x0a12 ,0x0001 ), .driver_info = (unsigned long ) &csr },/* Broadcom BCM2033 without firmware */ - {USB_DEVICE (0x0a5c ,0x2033 ), .driver_info =BTUSB_IGNORE }, + {USB_DEVICE (0x0a5c ,0x2033 ), .driver_info = (unsigned long ) &ignore },/* Atheros 3011 with sflash firmware */ - {USB_DEVICE (0x0cf3 ,0x3002 ), .driver_info =BTUSB_IGNORE }, - {USB_DEVICE (0x0cf3 ,0xe019 ), .driver_info =BTUSB_IGNORE }, - {USB_DEVICE (0x13d3 ,0x3304 ), .driver_info =BTUSB_IGNORE }, - {USB_DEVICE (0x0930 ,0x0215 ), .driver_info =BTUSB_IGNORE }, - {USB_DEVICE (0x0489 ,0xe03d ), .driver_info =BTUSB_IGNORE }, + {USB_DEVICE (0x0cf3 ,0x3002 ), .driver_info = (unsigned long ) &ignore }, + {USB_DEVICE (0x0cf3 ,0xe019 ), .driver_info = (unsigned long ) &ignore }, + {USB_DEVICE (0x13d3 ,0x3304 ), .driver_info = (unsigned long ) &ignore }, + {USB_DEVICE (0x0930 ,0x0215 ), .driver_info = (unsigned long ) &ignore }, + {USB_DEVICE (0x0489 ,0xe03d ), .driver_info = (unsigned long ) &ignore },/* Atheros AR9285 Malbec with sflash firmware */ - {USB_DEVICE (0x03f0 ,0x311d ), .driver_info =BTUSB_IGNORE }, + {USB_DEVICE (0x03f0 ,0x311d ), .driver_info = (unsigned long ) &ignore },/* Atheros 3012 with sflash firmware */ - {USB_DEVICE (0x0cf3 ,0x3004 ), .driver_info =BTUSB_ATH3012 }, - {USB_DEVICE (0x0cf3 ,0x311d ), .driver_info =BTUSB_ATH3012 }, - {USB_DEVICE (0x13d3 ,0x3375 ), .driver_info =BTUSB_ATH3012 }, - {USB_DEVICE (0x04ca ,0x3005 ), .driver_info =BTUSB_ATH3012 }, - {USB_DEVICE (0x13d3 ,0x3362 ), .driver_info =BTUSB_ATH3012 }, - {USB_DEVICE (0x0cf3 ,0xe004 ), .driver_info =BTUSB_ATH3012 }, - {USB_DEVICE (0x0930 ,0x0219 ), .driver_info =BTUSB_ATH3012 }, + {USB_DEVICE (0x0cf3 ,0x3004 ), .driver_info = (unsigned long ) &ath3012 }, + {USB_DEVICE (0x0cf3 ,0x311d ), .driver_info = (unsigned long ) &ath3012 }, + {USB_DEVICE (0x13d3 ,0x3375 ), .driver_info = (unsigned long ) &ath3012 }, + {USB_DEVICE (0x04ca ,0x3005 ), .driver_info = (unsigned long ) &ath3012 }, + {USB_DEVICE (0x13d3 ,0x3362 ), .driver_info = (unsigned long ) &ath3012 }, + {USB_DEVICE (0x0cf3 ,0xe004 ), .driver_info = (unsigned long ) &ath3012 }, + {USB_DEVICE (0x0930 ,0x0219 ), .driver_info = (unsigned long ) &ath3012 },/* Atheros AR5BBU12 with sflash firmware */ - {USB_DEVICE (0x0489 ,0xe02c ), .driver_info =BTUSB_IGNORE }, + {USB_DEVICE (0x0489 ,0xe02c ), .driver_info = (unsigned long ) &ignore },/* Atheros AR5BBU12 with sflash firmware */ - {USB_DEVICE (0x0489 ,0xe03c ), .driver_info =BTUSB_ATH3012 }, + {USB_DEVICE (0x0489 ,0xe03c ), .driver_info = (unsigned long ) &ath3012 },/* Broadcom BCM2035 */ - {USB_DEVICE (0x0a5c ,0x2035 ), .driver_info =BTUSB_WRONG_SCO_MTU }, - {USB_DEVICE (0x0a5c ,0x200a ), .driver_info =BTUSB_WRONG_SCO_MTU }, - {USB_DEVICE (0x0a5c ,0x2009 ), .driver_info =BTUSB_BCM92035 }, + {USB_DEVICE (0x0a5c ,0x2035 ), .driver_info = (unsigned long ) &wrong_sco_mtu }, + {USB_DEVICE (0x0a5c ,0x200a ), .driver_info = (unsigned long ) &wrong_sco_mtu }, + {USB_DEVICE (0x0a5c ,0x2009 ), .driver_info = (unsigned long ) &bcm92035 },/* Broadcom BCM2045 */ - {USB_DEVICE (0x0a5c ,0x2039 ), .driver_info =BTUSB_WRONG_SCO_MTU }, - {USB_DEVICE (0x0a5c ,0x2101 ), .driver_info =BTUSB_WRONG_SCO_MTU }, + {USB_DEVICE (0x0a5c ,0x2039 ), .driver_info = (unsigned long ) &wrong_sco_mtu }, + {USB_DEVICE (0x0a5c ,0x2101 ), .driver_info = (unsigned long ) &wrong_sco_mtu },/* IBM/Lenovo ThinkPad with Broadcom chip */ - {USB_DEVICE (0x0a5c ,0x201e ), .driver_info =BTUSB_WRONG_SCO_MTU }, - {USB_DEVICE (0x0a5c ,0x2110 ), .driver_info =BTUSB_WRONG_SCO_MTU }, + {USB_DEVICE (0x0a5c ,0x201e ), .driver_info = (unsigned long ) &wrong_sco_mtu }, + {USB_DEVICE (0x0a5c ,0x2110 ), .driver_info = (unsigned long ) &wrong_sco_mtu },/* HP laptop with Broadcom chip */ - {USB_DEVICE (0x03f0 ,0x171d ), .driver_info =BTUSB_WRONG_SCO_MTU }, + {USB_DEVICE (0x03f0 ,0x171d ), .driver_info = (unsigned long ) &wrong_sco_mtu },/* Dell laptop with Broadcom chip */ - {USB_DEVICE (0x413c ,0x8126 ), .driver_info =BTUSB_WRONG_SCO_MTU }, + {USB_DEVICE (0x413c ,0x8126 ), .driver_info = (unsigned long ) &wrong_sco_mtu },/* Dell Wireless 370 and 410 devices */ - {USB_DEVICE (0x413c ,0x8152 ), .driver_info =BTUSB_WRONG_SCO_MTU }, - {USB_DEVICE (0x413c ,0x8156 ), .driver_info =BTUSB_WRONG_SCO_MTU }, + {USB_DEVICE (0x413c ,0x8152 ), .driver_info = (unsigned long ) &wrong_sco_mtu }, + {USB_DEVICE (0x413c ,0x8156 ), .driver_info = (unsigned long ) &wrong_sco_mtu },/* Belkin F8T012 and F8T013 devices */ - {USB_DEVICE (0x050d ,0x0012 ), .driver_info =BTUSB_WRONG_SCO_MTU }, - {USB_DEVICE (0x050d ,0x0013 ), .driver_info =BTUSB_WRONG_SCO_MTU }, + {USB_DEVICE (0x050d ,0x0012 ), .driver_info = (unsigned long ) &wrong_sco_mtu }, + {USB_DEVICE (0x050d ,0x0013 ), .driver_info = (unsigned long ) &wrong_sco_mtu },/* Asus WL-BTD202 device */ - {USB_DEVICE (0x0b05 ,0x1715 ), .driver_info =BTUSB_WRONG_SCO_MTU }, + {USB_DEVICE (0x0b05 ,0x1715 ), .driver_info = (unsigned long ) &wrong_sco_mtu },/* Kensington Bluetooth USB adapter */ - {USB_DEVICE (0x047d ,0x105e ), .driver_info =BTUSB_WRONG_SCO_MTU }, + {USB_DEVICE (0x047d ,0x105e ), .driver_info = (unsigned long ) &wrong_sco_mtu },/* RTX Telecom based adapters with buggy SCO support */ - {USB_DEVICE (0x0400 ,0x0807 ), .driver_info =BTUSB_BROKEN_ISOC }, - {USB_DEVICE (0x0400 ,0x080a ), .driver_info =BTUSB_BROKEN_ISOC }, + {USB_DEVICE (0x0400 ,0x0807 ), .driver_info = (unsigned long ) &broken_isoc }, + {USB_DEVICE (0x0400 ,0x080a ), .driver_info = (unsigned long ) &broken_isoc },/* CONWISE Technology based adapters with buggy SCO support */ - {USB_DEVICE (0x0e5e ,0x6622 ), .driver_info =BTUSB_BROKEN_ISOC }, + {USB_DEVICE (0x0e5e ,0x6622 ), .driver_info = (unsigned long ) &broken_isoc },/* Digianswer devices */ - {USB_DEVICE (0x08fd ,0x0001 ), .driver_info =BTUSB_DIGIANSWER }, - {USB_DEVICE (0x08fd ,0x0002 ), .driver_info =BTUSB_IGNORE }, + {USB_DEVICE (0x08fd ,0x0001 ), .driver_info = (unsigned long ) &digianswer }, + {USB_DEVICE (0x08fd ,0x0002 ), .driver_info = (unsigned long ) &ignore },/* CSR BlueCore Bluetooth Sniffer */ - {USB_DEVICE (0x0a12 ,0x0002 ), .driver_info =BTUSB_SNIFFER }, + {USB_DEVICE (0x0a12 ,0x0002 ), .driver_info = (unsigned long ) &sniffer },/* Frontline ComProbe Bluetooth Sniffer */ - {USB_DEVICE (0x16d3 ,0x0002 ), .driver_info =BTUSB_SNIFFER }, + {USB_DEVICE (0x16d3 ,0x0002 ), .driver_info = (unsigned long ) &sniffer }, { }/* Terminating entry */ };
@@ -910,12 +955,12 @@ static void btusb_waker(struct work_struct *work)usb_autopm_put_interface (data->intf); } -static int btusb_probe (struct usb_interface *intf, -const struct usb_device_id *id) +int btusb_probe (struct usb_interface *intf,const struct usb_device_id *id) {struct usb_endpoint_descriptor *ep_desc;struct btusb_data *data;struct hci_dev *hdev; +struct btusb_driver_info *info;int i, err;BT_DBG ("intf %p id %p" , intf, id);
@@ -931,19 +976,28 @@ static int btusb_probe(struct usb_interface *intf, id = match; } -if (id->driver_info ==BTUSB_IGNORE ) +/* +* Make sure the driver_info is not null or 0 because the code below +* need to access the flags +*/ +if (!id->driver_info) + info = (struct btusb_driver_info *) &generic; +else + info = (struct btusb_driver_info *) id->driver_info; + +if (info->flags ==BTUSB_IGNORE )return -ENODEV ; -if (ignore_dga && id->driver_info &BTUSB_DIGIANSWER ) +if (ignore_dga && (info->flags &BTUSB_DIGIANSWER ))return -ENODEV ; -if (ignore_csr && id->driver_info &BTUSB_CSR ) +if (ignore_csr && (info->flags &BTUSB_CSR ))return -ENODEV ; -if (ignore_sniffer && id->driver_info &BTUSB_SNIFFER ) +if (ignore_sniffer && (info->flags &BTUSB_SNIFFER ))return -ENODEV ; -if (id->driver_info &BTUSB_ATH3012 ) { +if (info->flags &BTUSB_ATH3012 ) {struct usb_device *udev =interface_to_usbdev (intf);/* Old firmware would otherwise let ath3k driver load
@@ -1012,26 +1066,30 @@ static int btusb_probe(struct usb_interface *intf, hdev->send = btusb_send_frame; hdev->notify = btusb_notify; +/* vendor specific device initialization routines */ + hdev->vsdev_init = info->vsdev_init; + hdev->vsdev_event = info->vsdev_event; +/* Interface numbers are hardcoded in the specification */ data->isoc =usb_ifnum_to_if (data->udev,1 );if (!reset)set_bit (HCI_QUIRK_RESET_ON_CLOSE , &hdev->quirks); -if (force_scofix || id->driver_info &BTUSB_WRONG_SCO_MTU ) { +if (force_scofix || (info->flags &BTUSB_WRONG_SCO_MTU )) {if (!disable_scofix)set_bit (HCI_QUIRK_FIXUP_BUFFER_SIZE , &hdev->quirks); } -if (id->driver_info &BTUSB_BROKEN_ISOC ) +if (info->flags &BTUSB_BROKEN_ISOC ) data->isoc =NULL ; -if (id->driver_info &BTUSB_DIGIANSWER ) { +if (info->flags &BTUSB_DIGIANSWER ) { data->cmdreq_type =USB_TYPE_VENDOR ;set_bit (HCI_QUIRK_RESET_ON_CLOSE , &hdev->quirks); } -if (id->driver_info &BTUSB_CSR ) { +if (info->flags &BTUSB_CSR ) {struct usb_device *udev = data->udev;/* Old firmware would otherwise execute USB reset */
@@ -1039,7 +1097,7 @@ static int btusb_probe(struct usb_interface *intf,set_bit (HCI_QUIRK_RESET_ON_CLOSE , &hdev->quirks); } -if (id->driver_info &BTUSB_SNIFFER ) { +if (info->flags &BTUSB_SNIFFER ) {struct usb_device *udev = data->udev;/* New sniffer firmware has crippled HCI interface */
@@ -1049,7 +1107,7 @@ static int btusb_probe(struct usb_interface *intf, data->isoc =NULL ; } -if (id->driver_info &BTUSB_BCM92035 ) { +if (info->flags &BTUSB_BCM92035 ) {unsigned char cmd[] = {0x3b ,0xfc ,0x01 ,0x00 };struct sk_buff *skb;
@@ -1079,8 +1137,9 @@ static int btusb_probe(struct usb_interface *intf,return 0 ; } +EXPORT_SYMBOL_GPL (btusb_probe); -static void btusb_disconnect (struct usb_interface *intf) +void btusb_disconnect (struct usb_interface *intf) {struct btusb_data *data =usb_get_intfdata (intf);struct hci_dev *hdev;
@@ -1105,9 +1164,10 @@ static void btusb_disconnect(struct usb_interface *intf)hci_free_dev (hdev); } +EXPORT_SYMBOL_GPL (btusb_disconnect);#ifdef CONFIG_PM -static int btusb_suspend (struct usb_interface *intf,pm_message_t message) +int btusb_suspend (struct usb_interface *intf,pm_message_t message) {struct btusb_data *data =usb_get_intfdata (intf);
@@ -1133,6 +1193,7 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)return 0 ; } +EXPORT_SYMBOL_GPL (btusb_suspend);static void play_deferred (struct btusb_data *data) {
@@ -1149,7 +1210,7 @@ static void play_deferred(struct btusb_data *data)usb_scuttle_anchored_urbs (&data->deferred); } -static int btusb_resume (struct usb_interface *intf) +int btusb_resume (struct usb_interface *intf) {struct btusb_data *data =usb_get_intfdata (intf);struct hci_dev *hdev = data->hdev;
@@ -1205,8 +1266,10 @@ done:return err; } +EXPORT_SYMBOL_GPL (btusb_resume);#endif +static struct usb_driver btusb_driver = { .name ="btusb" , .probe = btusb_probe,
drivers/bluetooth/btusb.h new file +53 -0
53 lines not on this page · raw message
include/net/bluetooth/hci_core.h +10 -0
@@ -275,6 +275,16 @@ struct hci_dev {int (*send)(struct sk_buff *skb);void (*notify)(struct hci_dev *hdev,unsigned int evt);int (*ioctl)(struct hci_dev *hdev,unsigned int cmd,unsigned long arg); + +/* +* TODO: Added following members for vendor specific initialization to +* make the bluetooth.ko transparent to the interface. +* These members are set by the vendor provided driver +*/ +int vsdev_init_done; +void *vsdev_priv_data; +int (*vsdev_init)(struct hci_dev *hdev); +void (*vsdev_event)(struct hci_dev *hdev,struct sk_buff *skb); };struct hci_conn {
net/bluetooth/hci_core.c +14 -1
@@ -685,6 +685,15 @@ int hci_dev_open(__u16 dev)set_bit (HCI_INIT , &hdev->flags); hdev->init_last_cmd =0 ; +/* vendor specific device initialization */ +if (hdev->vsdev_init) { + ret = hdev->vsdev_init (hdev); + hdev->vsdev_init_done =1 ; + hdev->vsdev_event =NULL ; +if (ret <0 ) + goto done; + } + ret =__hci_request (hdev, hci_init_req,0 ,HCI_INIT_TIMEOUT );if (lmp_host_le_capable (hdev))
@@ -2119,6 +2128,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)return 0 ; } +EXPORT_SYMBOL (hci_send_cmd);/* Get data from the previously sent command */ void *hci_sent_cmd_data (struct hci_dev *hdev,__u16 opcode)
@@ -2800,7 +2810,10 @@ static void hci_rx_work(struct work_struct *work)switch (bt_cb (skb)->pkt_type) {case HCI_EVENT_PKT :BT_DBG ("%s Event packet" , hdev->name); -hci_event_packet (hdev, skb); +if (hdev->vsdev_event && !hdev->vsdev_init_done) + hdev->vsdev_event (hdev, skb); +else +hci_event_packet (hdev, skb);break ;case HCI_ACLDATA_PKT :
Signature · 1 line
1.7.9.5
Marcel Holtmann
maintainerHi Tedd,
Quoted 46 lines
This patch provides an extension of btusb to support device vendor can implement their own module to execute the vendor specific device initialization before the stack sends generic BT device initialization.
Signed-off-by Tedd Ho-Jeong An <[email protected]>--- drivers/bluetooth/btusb.c | 191 +++++++++++++++++++++++++------------- drivers/bluetooth/btusb.h | 53 +++++++++++ include/net/bluetooth/hci_core.h | 10 ++ net/bluetooth/hci_core.c | 15 ++- 4 files changed, 204 insertions(+), 65 deletions(-) create mode 100644 drivers/bluetooth/btusb.hdrivers/bluetooth/btusb.c +9
-8@@ -26,6 +26,7 @@#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> +#include "btusb.h" #define VERSION "0.6"@@ -39,14 +40,59 @@ static bool reset = 1;static struct usb_driver btusb_driver; -#define BTUSB_IGNORE 0x01 -#define BTUSB_DIGIANSWER 0x02 -#define BTUSB_CSR 0x04 -#define BTUSB_SNIFFER 0x08 -#define BTUSB_BCM92035 0x10 -#define BTUSB_BROKEN_ISOC 0x20 -#define BTUSB_WRONG_SCO_MTU 0x40 -#define BTUSB_ATH3012 0x80 +/* +* Create btusb_driver_info struct for each driver_info flags used by +* blacklist since vendor's btusb driver will return btusb_driver_info struct. +*/ + +/* +* if the device is set to this, this menas that the device is generic and +* doesn't require any vendor specific handling
drivers/bluetooth/btusb.c static bool reset = 1; · line 60
Quoted 10 lines
drivers/bluetooth/btusb.c +10
-0+*/ +static const struct btusb_driver_info generic = { + .description ="BTUSB Generic" , + .flags =BTUSB_GENERIC , +}; + +static const struct btusb_driver_info ignore = { + .description ="BTUSB Ignore" , + .flags =BTUSB_IGNORE , +};
I like the effort, but I think you went a little bit too far here. For these simple ones, we can easily keep our simple blacklist. It keeps the code more readable than this part. But I do appreciate the attempt in unifying this.
Quoted 39 lines
drivers/bluetooth/btusb.c +35
-0+ +static const struct btusb_driver_info digianswer = { + .description ="BTUSB DIGIANSWER" , + .flags =BTUSB_DIGIANSWER , +}; + +static const struct btusb_driver_info csr = { + .description ="BTUSB CSR" , + .flags =BTUSB_CSR , +}; + +static const struct btusb_driver_info sniffer = { + .description ="BTUSB Sniffer" , + .flags =BTUSB_SNIFFER , +}; + +static const struct btusb_driver_info bcm92035 = { + .description ="BTUSB BCM92035" , + .flags =BTUSB_BCM92035 , +}; + +static const struct btusb_driver_info broken_isoc = { + .description ="BTUSB Broken ISOC" , + .flags =BTUSB_BROKEN_ISOC , +}; + +static const struct btusb_driver_info wrong_sco_mtu = { + .description ="BTUSB Wrong SCO MTU" , + .flags =BTUSB_WRONG_SCO_MTU , +}; + +static const struct btusb_driver_info ath3012 = { + .description ="BTUSB Ath3012" , + .flags =BTUSB_ATH3012 , +};static struct usb_device_id btusb_table[] = {/* Generic Bluetooth USB device */
drivers/bluetooth/btusb.c static struct usb_device_id btusb_table[] = { · line 158
Quoted 10 lines
drivers/bluetooth/btusb.c +1
-2@@ -105,90 +151,89 @@ static struct usb_device_id btusb_table[] = { { }/* Terminating entry */ }; -MODULE_DEVICE_TABLE (usb, btusb_table);static struct usb_device_id blacklist_table[] = {/* CSR BlueCore devices */ - {USB_DEVICE (0x0a12 ,0x0001 ), .driver_info =BTUSB_CSR }, + {USB_DEVICE (0x0a12 ,0x0001 ), .driver_info = (unsigned long ) &csr },
Keep the blacklist_table as it is. The important table to modify is btusb_table and use a common driver_info that will be shared between drivers.
That would also make it simple to just add BTUSB_IGNORE or a new BTUSB_VENDOR flag to call out the drivers that have a separate driver with a vendor init function, but would match the Bluetooth general USB descriptors.
Then over time, we can move the BTUSB_BCM92035 for example into its separate driver. And also deal with cleaning up all the other Broadcom specialties.
Quoted 308 lines
drivers/bluetooth/btusb.c +72
-54/* Broadcom BCM2033 without firmware */ - { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x0a5c, 0x2033), .driver_info = (unsigned long) &ignore }, /* Atheros 3011 with sflash firmware */ - { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, - { USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE }, - { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, - { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, - { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x0cf3, 0x3002), .driver_info = (unsigned long) &ignore }, + { USB_DEVICE(0x0cf3, 0xe019), .driver_info = (unsigned long) &ignore }, + { USB_DEVICE(0x13d3, 0x3304), .driver_info = (unsigned long) &ignore }, + { USB_DEVICE(0x0930, 0x0215), .driver_info = (unsigned long) &ignore }, + { USB_DEVICE(0x0489, 0xe03d), .driver_info = (unsigned long) &ignore }, /* Atheros AR9285 Malbec with sflash firmware */ - { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x03f0, 0x311d), .driver_info = (unsigned long) &ignore }, /* Atheros 3012 with sflash firmware */ - { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0x3004), .driver_info = (unsigned long) &ath3012 }, + { USB_DEVICE(0x0cf3, 0x311d), .driver_info = (unsigned long) &ath3012 }, + { USB_DEVICE(0x13d3, 0x3375), .driver_info = (unsigned long) &ath3012 }, + { USB_DEVICE(0x04ca, 0x3005), .driver_info = (unsigned long) &ath3012 }, + { USB_DEVICE(0x13d3, 0x3362), .driver_info = (unsigned long) &ath3012 }, + { USB_DEVICE(0x0cf3, 0xe004), .driver_info = (unsigned long) &ath3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = (unsigned long) &ath3012 }, /* Atheros AR5BBU12 with sflash firmware */ - { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x0489, 0xe02c), .driver_info = (unsigned long) &ignore }, /* Atheros AR5BBU12 with sflash firmware */ - { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe03c), .driver_info = (unsigned long) &ath3012 }, /* Broadcom BCM2035 */ - { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, - { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, - { USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 }, + { USB_DEVICE(0x0a5c, 0x2035), .driver_info = (unsigned long) &wrong_sco_mtu }, + { USB_DEVICE(0x0a5c, 0x200a), .driver_info = (unsigned long) &wrong_sco_mtu }, + { USB_DEVICE(0x0a5c, 0x2009), .driver_info = (unsigned long) &bcm92035 }, /* Broadcom BCM2045 */ - { USB_DEVICE(0x0a5c, 0x2039), .driver_info = BTUSB_WRONG_SCO_MTU }, - { USB_DEVICE(0x0a5c, 0x2101), .driver_info = BTUSB_WRONG_SCO_MTU }, + { USB_DEVICE(0x0a5c, 0x2039), .driver_info = (unsigned long) &wrong_sco_mtu }, + { USB_DEVICE(0x0a5c, 0x2101), .driver_info = (unsigned long) &wrong_sco_mtu }, /* IBM/Lenovo ThinkPad with Broadcom chip */ - { USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_WRONG_SCO_MTU }, - { USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_WRONG_SCO_MTU }, + { USB_DEVICE(0x0a5c, 0x201e), .driver_info = (unsigned long) &wrong_sco_mtu }, + { USB_DEVICE(0x0a5c, 0x2110), .driver_info = (unsigned long) &wrong_sco_mtu }, /* HP laptop with Broadcom chip */ - { USB_DEVICE(0x03f0, 0x171d), .driver_info = BTUSB_WRONG_SCO_MTU }, + { USB_DEVICE(0x03f0, 0x171d), .driver_info = (unsigned long) &wrong_sco_mtu }, /* Dell laptop with Broadcom chip */ - { USB_DEVICE(0x413c, 0x8126), .driver_info = BTUSB_WRONG_SCO_MTU }, + { USB_DEVICE(0x413c, 0x8126), .driver_info = (unsigned long) &wrong_sco_mtu }, /* Dell Wireless 370 and 410 devices */ - { USB_DEVICE(0x413c, 0x8152), .driver_info = BTUSB_WRONG_SCO_MTU }, - { USB_DEVICE(0x413c, 0x8156), .driver_info = BTUSB_WRONG_SCO_MTU }, + { USB_DEVICE(0x413c, 0x8152), .driver_info = (unsigned long) &wrong_sco_mtu }, + { USB_DEVICE(0x413c, 0x8156), .driver_info = (unsigned long) &wrong_sco_mtu }, /* Belkin F8T012 and F8T013 devices */ - { USB_DEVICE(0x050d, 0x0012), .driver_info = BTUSB_WRONG_SCO_MTU }, - { USB_DEVICE(0x050d, 0x0013), .driver_info = BTUSB_WRONG_SCO_MTU }, + { USB_DEVICE(0x050d, 0x0012), .driver_info = (unsigned long) &wrong_sco_mtu }, + { USB_DEVICE(0x050d, 0x0013), .driver_info = (unsigned long) &wrong_sco_mtu }, /* Asus WL-BTD202 device */ - { USB_DEVICE(0x0b05, 0x1715), .driver_info = BTUSB_WRONG_SCO_MTU }, + { USB_DEVICE(0x0b05, 0x1715), .driver_info = (unsigned long) &wrong_sco_mtu }, /* Kensington Bluetooth USB adapter */ - { USB_DEVICE(0x047d, 0x105e), .driver_info = BTUSB_WRONG_SCO_MTU }, + { USB_DEVICE(0x047d, 0x105e), .driver_info = (unsigned long) &wrong_sco_mtu }, /* RTX Telecom based adapters with buggy SCO support */ - { USB_DEVICE(0x0400, 0x0807), .driver_info = BTUSB_BROKEN_ISOC }, - { USB_DEVICE(0x0400, 0x080a), .driver_info = BTUSB_BROKEN_ISOC }, + { USB_DEVICE(0x0400, 0x0807), .driver_info = (unsigned long) &broken_isoc }, + { USB_DEVICE(0x0400, 0x080a), .driver_info = (unsigned long) &broken_isoc }, /* CONWISE Technology based adapters with buggy SCO support */ - { USB_DEVICE(0x0e5e, 0x6622), .driver_info = BTUSB_BROKEN_ISOC }, + { USB_DEVICE(0x0e5e, 0x6622), .driver_info = (unsigned long) &broken_isoc }, /* Digianswer devices */ - { USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER }, - { USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x08fd, 0x0001), .driver_info = (unsigned long) &digianswer }, + { USB_DEVICE(0x08fd, 0x0002), .driver_info = (unsigned long) &ignore }, /* CSR BlueCore Bluetooth Sniffer */ - { USB_DEVICE(0x0a12, 0x0002), .driver_info = BTUSB_SNIFFER }, + { USB_DEVICE(0x0a12, 0x0002), .driver_info = (unsigned long) &sniffer }, /* Frontline ComProbe Bluetooth Sniffer */ - { USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER }, + { USB_DEVICE(0x16d3, 0x0002), .driver_info = (unsigned long) &sniffer }, { } /* Terminating entry */ };@@ -910,12 +955,12 @@ static void btusb_waker(struct work_struct *work)usb_autopm_put_interface (data->intf); } -static int btusb_probe (struct usb_interface *intf, -const struct usb_device_id *id) +int btusb_probe (struct usb_interface *intf,const struct usb_device_id *id) {struct usb_endpoint_descriptor *ep_desc;struct btusb_data *data;struct hci_dev *hdev; +struct btusb_driver_info *info;int i, err;BT_DBG ("intf %p id %p" , intf, id);@@ -931,19 +976,28 @@ static int btusb_probe(struct usb_interface *intf, id = match; } -if (id->driver_info ==BTUSB_IGNORE ) +/* +* Make sure the driver_info is not null or 0 because the code below +* need to access the flags +*/ +if (!id->driver_info) + info = (struct btusb_driver_info *) &generic; +else + info = (struct btusb_driver_info *) id->driver_info; + +if (info->flags ==BTUSB_IGNORE )return -ENODEV ; -if (ignore_dga && id->driver_info &BTUSB_DIGIANSWER ) +if (ignore_dga && (info->flags &BTUSB_DIGIANSWER ))return -ENODEV ; -if (ignore_csr && id->driver_info &BTUSB_CSR ) +if (ignore_csr && (info->flags &BTUSB_CSR ))return -ENODEV ; -if (ignore_sniffer && id->driver_info &BTUSB_SNIFFER ) +if (ignore_sniffer && (info->flags &BTUSB_SNIFFER ))return -ENODEV ; -if (id->driver_info &BTUSB_ATH3012 ) { +if (info->flags &BTUSB_ATH3012 ) {struct usb_device *udev =interface_to_usbdev (intf);/* Old firmware would otherwise let ath3k driver load @@ -1012,26 +1066,30 @@ static int btusb_probe(struct usb_interface *intf, hdev->send = btusb_send_frame; hdev->notify = btusb_notify; +/* vendor specific device initialization routines */ + hdev->vsdev_init = info->vsdev_init; + hdev->vsdev_event = info->vsdev_event; +/* Interface numbers are hardcoded in the specification */ data->isoc =usb_ifnum_to_if (data->udev,1 );if (!reset)set_bit (HCI_QUIRK_RESET_ON_CLOSE , &hdev->quirks); -if (force_scofix || id->driver_info &BTUSB_WRONG_SCO_MTU ) { +if (force_scofix || (info->flags &BTUSB_WRONG_SCO_MTU )) {if (!disable_scofix)set_bit (HCI_QUIRK_FIXUP_BUFFER_SIZE , &hdev->quirks); } -if (id->driver_info &BTUSB_BROKEN_ISOC ) +if (info->flags &BTUSB_BROKEN_ISOC ) data->isoc =NULL ; -if (id->driver_info &BTUSB_DIGIANSWER ) { +if (info->flags &BTUSB_DIGIANSWER ) { data->cmdreq_type =USB_TYPE_VENDOR ;set_bit (HCI_QUIRK_RESET_ON_CLOSE , &hdev->quirks); } -if (id->driver_info &BTUSB_CSR ) { +if (info->flags &BTUSB_CSR ) {struct usb_device *udev = data->udev;/* Old firmware would otherwise execute USB reset */ @@ -1039,7 +1097,7 @@ static int btusb_probe(struct usb_interface *intf,set_bit (HCI_QUIRK_RESET_ON_CLOSE , &hdev->quirks); } -if (id->driver_info &BTUSB_SNIFFER ) { +if (info->flags &BTUSB_SNIFFER ) {struct usb_device *udev = data->udev;/* New sniffer firmware has crippled HCI interface */ @@ -1049,7 +1107,7 @@ static int btusb_probe(struct usb_interface *intf, data->isoc =NULL ; } -if (id->driver_info &BTUSB_BCM92035 ) { +if (info->flags &BTUSB_BCM92035 ) {unsigned char cmd[] = {0x3b ,0xfc ,0x01 ,0x00 };struct sk_buff *skb;@@ -1079,8 +1137,9 @@ static int btusb_probe(struct usb_interface *intf,return 0 ; } +EXPORT_SYMBOL_GPL (btusb_probe); -static void btusb_disconnect (struct usb_interface *intf) +void btusb_disconnect (struct usb_interface *intf) {struct btusb_data *data =usb_get_intfdata (intf);struct hci_dev *hdev;@@ -1105,9 +1164,10 @@ static void btusb_disconnect(struct usb_interface *intf)hci_free_dev (hdev); } +EXPORT_SYMBOL_GPL (btusb_disconnect);#ifdef CONFIG_PM -static int btusb_suspend (struct usb_interface *intf,pm_message_t message) +int btusb_suspend (struct usb_interface *intf,pm_message_t message) {struct btusb_data *data =usb_get_intfdata (intf);@@ -1133,6 +1193,7 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)return 0 ; } +EXPORT_SYMBOL_GPL (btusb_suspend);static void play_deferred (struct btusb_data *data) {@@ -1149,7 +1210,7 @@ static void play_deferred(struct btusb_data *data)usb_scuttle_anchored_urbs (&data->deferred); } -static int btusb_resume (struct usb_interface *intf) +int btusb_resume (struct usb_interface *intf) {struct btusb_data *data =usb_get_intfdata (intf);struct hci_dev *hdev = data->hdev;@@ -1205,8 +1266,10 @@ done:return err; } +EXPORT_SYMBOL_GPL (btusb_resume);#endif +static struct usb_driver btusb_driver = { .name ="btusb" , .probe = btusb_probe,drivers/bluetooth/btusb.h new file +30
-0@@ -0,0 +1,53 @@ +/* +* +* Generic Bluetooth USB driver +* +* Copyright (C) 2005-2008 Marcel Holtmann <[email protected]> +* +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +*/ +#ifndef _BTUSB_H +#define _BTUSB_H + +struct btusb_driver_info { + char *description; + int flags; +#define BTUSB_GENERIC 0x00 +#define BTUSB_IGNORE 0x01
drivers/bluetooth/btusb.h line 40
Quoted 10 lines
drivers/bluetooth/btusb.h new file +10
-0+#define BTUSB_DIGIANSWER 0x02 +#define BTUSB_CSR 0x04 +#define BTUSB_SNIFFER 0x08 +#define BTUSB_BCM92035 0x10 +#define BTUSB_BROKEN_ISOC 0x20 +#define BTUSB_WRONG_SCO_MTU 0x40 +#define BTUSB_ATH3012 0x80 + +/* entry point for vendor specific device initialization */ +int (*vsdev_init)(struct hci_dev *hdev);
Keep it simple. Call this (*setup).
drivers/bluetooth/btusb.h line 43
Quoted 3 lines
drivers/bluetooth/btusb.h new file +3
-0+ +/* event handler during vendor specific device initiation phase */ +void (*vsdev_event)(struct hci_dev *hdev,struct sk_buff *skb);
And this just (*event).
I am still curious if we would need the event part at all when using HCI command handling with callbacks, but I know at least that CSR is not following the HCI specification for command + event, so it might be a good idea.
Quoted 15 lines
drivers/bluetooth/btusb.h new file +10
-0+}; + +extern int btusb_probe (struct usb_interface *,const struct usb_device_id *); +extern void btusb_disconnect (struct usb_interface *); +#ifdef CONFIG_PM +extern int btusb_suspend (struct usb_interface *,pm_message_t ); +extern int btusb_resume (struct usb_interface *); +#endif + +#endif /* _BTUSB_H */ include/net/bluetooth/hci_core.h +0
-0
include/net/bluetooth/hci_core.h struct hci_dev { · line 284
Quoted 10 lines
include/net/bluetooth/hci_core.h +7
-0@@ -275,6 +275,16 @@ struct hci_dev {int (*send)(struct sk_buff *skb);void (*notify)(struct hci_dev *hdev,unsigned int evt);int (*ioctl)(struct hci_dev *hdev,unsigned int cmd,unsigned long arg); + +/* +* TODO: Added following members for vendor specific initialization to +* make the bluetooth.ko transparent to the interface. +* These members are set by the vendor provided driver +*/ +int vsdev_init_done;
For this, please use dev_flags. No need waste space with another variable.
include/net/bluetooth/hci_core.h struct hci_dev { · line 288
Quoted 4 lines
include/net/bluetooth/hci_core.h +3
-0+void *vsdev_priv_data; +int (*vsdev_init)(struct hci_dev *hdev); +void (*vsdev_event)(struct hci_dev *hdev,struct sk_buff *skb); };
Rather like vendor_setup and vendor_event here. I do not even want to know what vs stands for ;)
Hope we are not getting into trouble with driver id tables normally being const.
Quoted 9 lines
include/net/bluetooth/hci_core.h +0
-0struct hci_conn {net/bluetooth/hci_core.c +0
-0@@ -685,6 +685,15 @@ int hci_dev_open(__u16 dev)set_bit (HCI_INIT , &hdev->flags); hdev->init_last_cmd =0 ;
net/bluetooth/hci_core.c int hci_dev_open(__u16 dev) · line 696
Quoted 10 lines
net/bluetooth/hci_core.c +9
-0+/* vendor specific device initialization */ +if (hdev->vsdev_init) { + ret = hdev->vsdev_init (hdev); + hdev->vsdev_init_done =1 ; + hdev->vsdev_event =NULL ; +if (ret <0 ) + goto done; + } +
Do you really want to do this on every hciconfig hci0 up? I assumed this is a one time task. So you might better look at hci_power_on() for this.
Is a HCI_Reset command unloading the firmware patches.
Quoted 12 lines
net/bluetooth/hci_core.c +1
-0ret =__hci_request (hdev, hci_init_req,0 ,HCI_INIT_TIMEOUT );if (lmp_host_le_capable (hdev))@@ -2119,6 +2128,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)return 0 ; } +EXPORT_SYMBOL (hci_send_cmd);/* Get data from the previously sent command */ void *hci_sent_cmd_data (struct hci_dev *hdev,__u16 opcode)
net/bluetooth/hci_core.c static void hci_rx_work(struct work_struct *work) · line 2817
Quoted 9 lines
net/bluetooth/hci_core.c +4
-1@@ -2800,7 +2810,10 @@ static void hci_rx_work(struct work_struct *work)switch (bt_cb (skb)->pkt_type) {case HCI_EVENT_PKT :BT_DBG ("%s Event packet" , hdev->name); -hci_event_packet (hdev, skb); +if (hdev->vsdev_event && !hdev->vsdev_init_done) + hdev->vsdev_event (hdev, skb); +else +hci_event_packet (hdev, skb);break ;
Not going through hci_event_packet is a bad idea. That will screw over the flow control handling for commands.
Regards
Marcel
SGkgTWFyY2VsLA0KDQpJIGhhdmUgYSBxdWVzdGlvbiBhZnRlciBvdXIgY2hhdCB2aWEgSVJDLiAg U2VlIGJlbG93Lg0KIA0KDQo+IFRoaXMgcGF0Y2ggcHJvdmlkZXMgYW4gZXh0ZW5zaW9uIG9mIGJ0 dXNiIHRvIHN1cHBvcnQgZGV2aWNlIHZlbmRvciBjYW4gDQo+IGltcGxlbWVudCB0aGVpciBvd24g bW9kdWxlIHRvIGV4ZWN1dGUgdGhlIHZlbmRvciBzcGVjaWZpYyBkZXZpY2UgDQo+IGluaXRpYWxp emF0aW9uIGJlZm9yZSB0aGUgc3RhY2sgc2VuZHMgZ2VuZXJpYyBCVCBkZXZpY2UgDQo+IGluaXRp YWxpemF0aW9uLg0KPiANCj4gU2lnbmVkLW9mZi1ieTogVGVkZCBIby1KZW9uZyBBbiA8dGVkZC5h bkBpbnRlbC5jb20+DQo+IC0tLQ0KPiAgZHJpdmVycy9ibHVldG9vdGgvYnR1c2IuYyAgICAgICAg fCAgMTkxICsrKysrKysrKysrKysrKysrKysrKysrKystLS0tLS0tLS0tLS0tDQo+ICBkcml2ZXJz L2JsdWV0b290aC9idHVzYi5oICAgICAgICB8ICAgNTMgKysrKysrKysrKysNCj4gIGluY2x1ZGUv bmV0L2JsdWV0b290aC9oY2lfY29yZS5oIHwgICAxMCArKw0KPiAgbmV0L2JsdWV0b290aC9oY2lf Y29yZS5jICAgICAgICAgfCAgIDE1ICsrLQ0KPiAgNCBmaWxlcyBjaGFuZ2VkLCAyMDQgaW5zZXJ0 aW9ucygrKSwgNjUgZGVsZXRpb25zKC0pICBjcmVhdGUgbW9kZSANCj4gMTAwNjQ0IGRyaXZlcnMv Ymx1ZXRvb3RoL2J0dXNiLmgNCj4gDQo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2JsdWV0b290aC9i dHVzYi5jIGIvZHJpdmVycy9ibHVldG9vdGgvYnR1c2IuYyANCj4gaW5kZXggZjYzN2MyNS4uYWZh MTU1OCAxMDA2NDQNCj4gLS0tIGEvZHJpdmVycy9ibHVldG9vdGgvYnR1c2IuYw0KPiArKysgYi9k cml2ZXJzL2JsdWV0b290aC9idHVzYi5jDQo+IEBAIC0yNiw2ICsyNiw3IEBADQo+ICANCj4gICNp bmNsdWRlIDxuZXQvYmx1ZXRvb3RoL2JsdWV0b290aC5oPg0KPiAgI2luY2x1ZGUgPG5ldC9ibHVl dG9vdGgvaGNpX2NvcmUuaD4NCj4gKyNpbmNsdWRlICJidHVzYi5oIg0KPiAgDQo+ICAjZGVmaW5l IFZFUlNJT04gIjAuNiINCj4gIA0KPiBAQCAtMzksMTQgKzQwLDU5IEBAIHN0YXRpYyBib29sIHJl c2V0ID0gMTsNCj4gIA0KPiAgc3RhdGljIHN0cnVjdCB1c2JfZHJpdmVyIGJ0dXNiX2RyaXZlcjsN Cj4gIA0KPiAtI2RlZmluZSBCVFVTQl9JR05PUkUJCTB4MDENCj4gLSNkZWZpbmUgQlRVU0JfRElH SUFOU1dFUgkweDAyDQo+IC0jZGVmaW5lIEJUVVNCX0NTUgkJMHgwNA0KPiAtI2RlZmluZSBCVFVT Ql9TTklGRkVSCQkweDA4DQo+IC0jZGVmaW5lIEJUVVNCX0JDTTkyMDM1CQkweDEwDQo+IC0jZGVm aW5lIEJUVVNCX0JST0tFTl9JU09DCTB4MjANCj4gLSNkZWZpbmUgQlRVU0JfV1JPTkdfU0NPX01U VQkweDQwDQo+IC0jZGVmaW5lIEJUVVNCX0FUSDMwMTIJCTB4ODANCj4gKy8qDQo+ICsgKiBDcmVh dGUgYnR1c2JfZHJpdmVyX2luZm8gc3RydWN0IGZvciBlYWNoIGRyaXZlcl9pbmZvIGZsYWdzIHVz ZWQgYnkNCj4gKyAqIGJsYWNrbGlzdCBzaW5jZSB2ZW5kb3IncyBidHVzYiBkcml2ZXIgd2lsbCBy ZXR1cm4gYnR1c2JfZHJpdmVyX2luZm8gc3RydWN0Lg0KPiArICovDQo+ICsNCj4gKy8qDQo+ICsg KiBpZiB0aGUgZGV2aWNlIGlzIHNldCB0byB0aGlzLCB0aGlzIG1lbmFzIHRoYXQgdGhlIGRldmlj ZSBpcyANCj4gK2dlbmVyaWMgYW5kDQo+ICsgKiBkb2Vzbid0IHJlcXVpcmUgYW55IHZlbmRvciBz cGVjaWZpYyBoYW5kbGluZyAgKi8gc3RhdGljIGNvbnN0IA0KPiArc3RydWN0IGJ0dXNiX2RyaXZl cl9pbmZvIGdlbmVyaWMgPSB7DQo+ICsJLmRlc2NyaXB0aW9uCT0gIkJUVVNCIEdlbmVyaWMiLA0K PiArCS5mbGFncwkJPSBCVFVTQl9HRU5FUklDLA0KPiArfTsNCj4gKw0KPiArc3RhdGljIGNvbnN0 IHN0cnVjdCBidHVzYl9kcml2ZXJfaW5mbyBpZ25vcmUgPSB7DQo+ICsJLmRlc2NyaXB0aW9uCT0g IkJUVVNCIElnbm9yZSIsDQo+ICsJLmZsYWdzCQk9IEJUVVNCX0lHTk9SRSwNCj4gK307DQoNCj4+ IEkgbGlrZSB0aGUgZWZmb3J0LCBidXQgSSB0aGluayB5b3Ugd2VudCBhIGxpdHRsZSBiaXQgdG9v IGZhciBoZXJlLiBGb3IgdGhlc2Ugc2ltcGxlIG9uZXMsIHdlIGNhbiBlYXNpbHkga2VlcCBvdXIg c2ltcGxlIGJsYWNrbGlzdC4gSXQga2VlcHMgdGhlIGNvZGUgbW9yZSByZWFkYWJsZSB0aGFuIHRo aXMgcGFydC4gQnV0IEkgZG8gYXBwcmVjaWF0ZSB0aGUgYXR0ZW1wdCBpbiB1bmlmeWluZyB0aGlz Lg0KDQoNCj4gKw0KPiArc3RhdGljIGNvbnN0IHN0cnVjdCBidHVzYl9kcml2ZXJfaW5mbyBkaWdp YW5zd2VyID0gew0KPiArCS5kZXNjcmlwdGlvbgk9ICJCVFVTQiBESUdJQU5TV0VSIiwNCj4gKwku ZmxhZ3MJCT0gQlRVU0JfRElHSUFOU1dFUiwNCj4gK307DQo+ICsNCj4gK3N0YXRpYyBjb25zdCBz dHJ1Y3QgYnR1c2JfZHJpdmVyX2luZm8gY3NyID0gew0KPiArCS5kZXNjcmlwdGlvbgk9ICJCVFVT QiBDU1IiLA0KPiArCS5mbGFncwkJPSBCVFVTQl9DU1IsDQo+ICt9Ow0KPiArDQo+ICtzdGF0aWMg Y29uc3Qgc3RydWN0IGJ0dXNiX2RyaXZlcl9pbmZvIHNuaWZmZXIgPSB7DQo+ICsJLmRlc2NyaXB0 aW9uCT0gIkJUVVNCIFNuaWZmZXIiLA0KPiArCS5mbGFncwkJPSBCVFVTQl9TTklGRkVSLA0KPiAr fTsNCj4gKw0KPiArc3RhdGljIGNvbnN0IHN0cnVjdCBidHVzYl9kcml2ZXJfaW5mbyBiY205MjAz NSA9IHsNCj4gKwkuZGVzY3JpcHRpb24JPSAiQlRVU0IgQkNNOTIwMzUiLA0KPiArCS5mbGFncwkJ PSBCVFVTQl9CQ005MjAzNSwNCj4gK307DQo+ICsNCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgYnR1 c2JfZHJpdmVyX2luZm8gYnJva2VuX2lzb2MgPSB7DQo+ICsJLmRlc2NyaXB0aW9uCT0gIkJUVVNC IEJyb2tlbiBJU09DIiwNCj4gKwkuZmxhZ3MJCT0gQlRVU0JfQlJPS0VOX0lTT0MsDQo+ICt9Ow0K PiArDQo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGJ0dXNiX2RyaXZlcl9pbmZvIHdyb25nX3Njb19t dHUgPSB7DQo+ICsJLmRlc2NyaXB0aW9uCT0gIkJUVVNCIFdyb25nIFNDTyBNVFUiLA0KPiArCS5m bGFncwkJPSBCVFVTQl9XUk9OR19TQ09fTVRVLA0KPiArfTsNCj4gKw0KPiArc3RhdGljIGNvbnN0 IHN0cnVjdCBidHVzYl9kcml2ZXJfaW5mbyBhdGgzMDEyID0gew0KPiArCS5kZXNjcmlwdGlvbgk9 ICJCVFVTQiBBdGgzMDEyIiwNCj4gKwkuZmxhZ3MJCT0gQlRVU0JfQVRIMzAxMiwNCj4gK307DQo+ ICANCj4gIHN0YXRpYyBzdHJ1Y3QgdXNiX2RldmljZV9pZCBidHVzYl90YWJsZVtdID0gew0KPiAg CS8qIEdlbmVyaWMgQmx1ZXRvb3RoIFVTQiBkZXZpY2UgKi8NCj4gQEAgLTEwNSw5MCArMTUxLDg5 IEBAIHN0YXRpYyBzdHJ1Y3QgdXNiX2RldmljZV9pZCBidHVzYl90YWJsZVtdID0gew0KPiAgDQo+ ICAJeyB9CS8qIFRlcm1pbmF0aW5nIGVudHJ5ICovDQo+ICB9Ow0KPiAtDQo+ICBNT0RVTEVfREVW SUNFX1RBQkxFKHVzYiwgYnR1c2JfdGFibGUpOw0KPiAgDQo+ICBzdGF0aWMgc3RydWN0IHVzYl9k ZXZpY2VfaWQgYmxhY2tsaXN0X3RhYmxlW10gPSB7DQo+ICAJLyogQ1NSIEJsdWVDb3JlIGRldmlj ZXMgKi8NCj4gLQl7IFVTQl9ERVZJQ0UoMHgwYTEyLCAweDAwMDEpLCAuZHJpdmVyX2luZm8gPSBC VFVTQl9DU1IgfSwNCj4gKwl7IFVTQl9ERVZJQ0UoMHgwYTEyLCAweDAwMDEpLCAuZHJpdmVyX2lu Zm8gPSAodW5zaWduZWQgbG9uZykgJmNzciB9LA0KDQo+PiBLZWVwIHRoZSBibGFja2xpc3RfdGFi bGUgYXMgaXQgaXMuIFRoZSBpbXBvcnRhbnQgdGFibGUgdG8gbW9kaWZ5IGlzIGJ0dXNiX3RhYmxl IGFuZCB1c2UgYSBjb21tb24gZHJpdmVyX2luZm8gdGhhdCB3aWxsIGJlIHNoYXJlZCBiZXR3ZWVu IGRyaXZlcnMuDQoNCj4+IFRoYXQgd291bGQgYWxzbyBtYWtlIGl0IHNpbXBsZSB0byBqdXN0IGFk ZCBCVFVTQl9JR05PUkUgb3IgYSBuZXcgQlRVU0JfVkVORE9SIGZsYWcgdG8gY2FsbCBvdXQgdGhl IGRyaXZlcnMgdGhhdCBoYXZlIGEgc2VwYXJhdGUgZHJpdmVyIHdpdGggYSB2ZW5kb3IgaW5pdCBm dW5jdGlvbiwgYnV0IHdvdWxkIG1hdGNoID4+IHRoZSBCbHVldG9vdGggZ2VuZXJhbCBVU0IgZGVz Y3JpcHRvcnMuDQoNCkkgbG9va2VkIGF0IHVzYm5ldCBtaW5pZHJpdmVyIGFzIHlvdSBzdWdnZXN0 ZWQuICBJZiB3ZSBkbyBhIHNpbWlsYXIgc2NoZW1lIHN1Y2ggdGhhdCBidHVzYl9wcm9iZSgpIGlu dm9rZXMgdGhlIG1pbmlfZHJpdmVyJ3MgYmluZCgpL3VuYmluZCgpIHRoZW4gYnR1c2IncyB1c2Fn ZSBvZiBkcml2ZXJfaW5mbyB3aWxsIG5lZWQgdG8gY2hhbmdlIGZyb20gc3RvcmluZyBmbGFncyAo ZXg6IEJUVVNCX0lHTk9SRSkgYW5kIGNoYW5nZSB0byBzdG9yZSAic3RhdGljIGNvbnN0IHN0cnVj dCIgd2hlcmUgaXQgaG9sZHMgYSBzdHJ1Y3QgY29udGFpbmluZyB0aGUgbWluaS1kcml2ZXIncyBi aW5kL3VuYmluZCBmdW5jdGlvbnMgKGp1c3QgbGlrZSB1c2JuZXQgbWluaWRyaXZlcikuICAgQXJl IHlvdSBnb29kIHdpdGggdGhpcyBjaGFuZ2U/ICBJIGFsc28gd2FudCB0byBtZW50aW9uIHRoYXQg aW4gdGhlIHBhdGNoIGNvbnRhaW5pbmcgdGhlIEJUIFVTQiBtaW5pIGRyaXZlciB0ZW1wbGF0ZSwg aXQgYWxyZWFkeSBoYXMgaXRzIG93biBtb2R1bGVfdXNiX2RyaXZlcigpIHNlY3Rpb24gd2l0aCBp dHMgVklEL1BJRCBsaXN0ZWQuDQoNCg0KPj4gVGhlbiBvdmVyIHRpbWUsIHdlIGNhbiBtb3ZlIHRo ZSBCVFVTQl9CQ005MjAzNSBmb3IgZXhhbXBsZSBpbnRvIGl0cyBzZXBhcmF0ZSBkcml2ZXIuIEFu ZCBhbHNvIGRlYWwgd2l0aCBjbGVhbmluZyB1cCBhbGwgdGhlIG90aGVyIEJyb2FkY29tIHNwZWNp YWx0aWVzLg0KDQo+ICANCj4gIAkvKiBCcm9hZGNvbSBCQ00yMDMzIHdpdGhvdXQgZmlybXdhcmUg Ki8NCj4gLQl7IFVTQl9ERVZJQ0UoMHgwYTVjLCAweDIwMzMpLCAuZHJpdmVyX2luZm8gPSBCVFVT Ql9JR05PUkUgfSwNCj4gKwl7IFVTQl9ERVZJQ0UoMHgwYTVjLCAweDIwMzMpLCAuZHJpdmVyX2lu Zm8gPSAodW5zaWduZWQgbG9uZykgJmlnbm9yZSANCj4gK30sDQo+ICANCj4gIAkvKiBBdGhlcm9z IDMwMTEgd2l0aCBzZmxhc2ggZmlybXdhcmUgKi8NCj4gLQl7IFVTQl9ERVZJQ0UoMHgwY2YzLCAw eDMwMDIpLCAuZHJpdmVyX2luZm8gPSBCVFVTQl9JR05PUkUgfSwNCj4gLQl7IFVTQl9ERVZJQ0Uo MHgwY2YzLCAweGUwMTkpLCAuZHJpdmVyX2luZm8gPSBCVFVTQl9JR05PUkUgfSwNCj4gLQl7IFVT Ql9ERVZJQ0UoMHgxM2QzLCAweDMzMDQpLCAuZHJpdmVyX2luZm8gPSBCVFVTQl9JR05PUkUgfSwN Cj4gLQl7IFVTQl9ERVZJQ0UoMHgwOTMwLCAweDAyMTUpLCAuZHJpdmVyX2luZm8gPSBCVFVTQl9J R05PUkUgfSwNCj4gLQl7IFVTQl9ERVZJQ0UoMHgwNDg5LCAweGUwM2QpLCAuZHJpdmVyX2luZm8g PSBCVFVTQl9JR05PUkUgfSwNCj4gKwl7IFVTQl9ERVZJQ0UoMHgwY2YzLCAweDMwMDIpLCAuZHJp dmVyX2luZm8gPSAodW5zaWduZWQgbG9uZykgJmlnbm9yZSB9LA0KPiArCXsgVVNCX0RFVklDRSgw eDBjZjMsIDB4ZTAxOSksIC5kcml2ZXJfaW5mbyA9ICh1bnNpZ25lZCBsb25nKSAmaWdub3JlIH0s DQo+ICsJeyBVU0JfREVWSUNFKDB4MTNkMywgMHgzMzA0KSwgLmRyaXZlcl9pbmZvID0gKHVuc2ln bmVkIGxvbmcpICZpZ25vcmUgfSwNCj4gKwl7IFVTQl9ERVZJQ0UoMHgwOTMwLCAweDAyMTUpLCAu ZHJpdmVyX2luZm8gPSAodW5zaWduZWQgbG9uZykgJmlnbm9yZSB9LA0KPiArCXsgVVNCX0RFVklD RSgweDA0ODksIDB4ZTAzZCksIC5kcml2ZXJfaW5mbyA9ICh1bnNpZ25lZCBsb25nKSAmaWdub3Jl IA0KPiArfSwNCj4gIA0KPiAgCS8qIEF0aGVyb3MgQVI5Mjg1IE1hbGJlYyB3aXRoIHNmbGFzaCBm aXJtd2FyZSAqLw0KPiAtCXsgVVNCX0RFVklDRSgweDAzZjAsIDB4MzExZCksIC5kcml2ZXJfaW5m byA9IEJUVVNCX0lHTk9SRSB9LA0KPiArCXsgVVNCX0RFVklDRSgweDAzZjAsIDB4MzExZCksIC5k cml2ZXJfaW5mbyA9ICh1bnNpZ25lZCBsb25nKSAmaWdub3JlIA0KPiArfSwNCj4gIA0KPiAgCS8q IEF0aGVyb3MgMzAxMiB3aXRoIHNmbGFzaCBmaXJtd2FyZSAqLw0KPiAtCXsgVVNCX0RFVklDRSgw eDBjZjMsIDB4MzAwNCksIC5kcml2ZXJfaW5mbyA9IEJUVVNCX0FUSDMwMTIgfSwNCj4gLQl7IFVT Ql9ERVZJQ0UoMHgwY2YzLCAweDMxMWQpLCAuZHJpdmVyX2luZm8gPSBCVFVTQl9BVEgzMDEyIH0s DQo+IC0JeyBVU0JfREVWSUNFKDB4MTNkMywgMHgzMzc1KSwgLmRyaXZlcl9pbmZvID0gQlRVU0Jf QVRIMzAxMiB9LA0KPiAtCXsgVVNCX0RFVklDRSgweDA0Y2EsIDB4MzAwNSksIC5kcml2ZXJfaW5m byA9IEJUVVNCX0FUSDMwMTIgfSwNCj4gLQl7IFVTQl9ERVZJQ0UoMHgxM2QzLCAweDMzNjIpLCAu ZHJpdmVyX2luZm8gPSBCVFVTQl9BVEgzMDEyIH0sDQo+IC0JeyBVU0JfREVWSUNFKDB4MGNmMywg MHhlMDA0KSwgLmRyaXZlcl9pbmZvID0gQlRVU0JfQVRIMzAxMiB9LA0KPiAtCXsgVVNCX0RFVklD RSgweDA5MzAsIDB4MDIxOSksIC5kcml2ZXJfaW5mbyA9IEJUVVNCX0FUSDMwMTIgfSwNCj4gKwl7 IFVTQl9ERVZJQ0UoMHgwY2YzLCAweDMwMDQpLCAuZHJpdmVyX2luZm8gPSAodW5zaWduZWQgbG9u ZykgJmF0aDMwMTIgfSwNCj4gKwl7IFVTQl9ERVZJQ0UoMHgwY2YzLCAweDMxMWQpLCAuZHJpdmVy X2luZm8gPSAodW5zaWduZWQgbG9uZykgJmF0aDMwMTIgfSwNCj4gKwl7IFVTQl9ERVZJQ0UoMHgx M2QzLCAweDMzNzUpLCAuZHJpdmVyX2luZm8gPSAodW5zaWduZWQgbG9uZykgJmF0aDMwMTIgfSwN Cj4gKwl7IFVTQl9ERVZJQ0UoMHgwNGNhLCAweDMwMDUpLCAuZHJpdmVyX2luZm8gPSAodW5zaWdu ZWQgbG9uZykgJmF0aDMwMTIgfSwNCj4gKwl7IFVTQl9ERVZJQ0UoMHgxM2QzLCAweDMzNjIpLCAu ZHJpdmVyX2luZm8gPSAodW5zaWduZWQgbG9uZykgJmF0aDMwMTIgfSwNCj4gKwl7IFVTQl9ERVZJ Q0UoMHgwY2YzLCAweGUwMDQpLCAuZHJpdmVyX2luZm8gPSAodW5zaWduZWQgbG9uZykgJmF0aDMw MTIgfSwNCj4gKwl7IFVTQl9ERVZJQ0UoMHgwOTMwLCAweDAyMTkpLCAuZHJpdmVyX2luZm8gPSAo dW5zaWduZWQgbG9uZykgDQo+ICsmYXRoMzAxMiB9LA0KPiAgDQo+ICAJLyogQXRoZXJvcyBBUjVC QlUxMiB3aXRoIHNmbGFzaCBmaXJtd2FyZSAqLw0KPiAtCXsgVVNCX0RFVklDRSgweDA0ODksIDB4 ZTAyYyksIC5kcml2ZXJfaW5mbyA9IEJUVVNCX0lHTk9SRSB9LA0KPiArCXsgVVNCX0RFVklDRSgw eDA0ODksIDB4ZTAyYyksIC5kcml2ZXJfaW5mbyA9ICh1bnNpZ25lZCBsb25nKSAmaWdub3JlIA0K PiArfSwNCj4gIA0KPiAgCS8qIEF0aGVyb3MgQVI1QkJVMTIgd2l0aCBzZmxhc2ggZmlybXdhcmUg Ki8NCj4gLQl7IFVTQl9ERVZJQ0UoMHgwNDg5LCAweGUwM2MpLCAuZHJpdmVyX2luZm8gPSBCVFVT Ql9BVEgzMDEyIH0sDQo+ICsJeyBVU0JfREVWSUNFKDB4MDQ4OSwgMHhlMDNjKSwgLmRyaXZlcl9p bmZvID0gKHVuc2lnbmVkIGxvbmcpIA0KPiArJmF0aDMwMTIgfSwNCj4gIA0KPiAgCS8qIEJyb2Fk Y29tIEJDTTIwMzUgKi8NCj4gLQl7IFVTQl9ERVZJQ0UoMHgwYTVjLCAweDIwMzUpLCAuZHJpdmVy X2luZm8gPSBCVFVTQl9XUk9OR19TQ09fTVRVIH0sDQo+IC0JeyBVU0JfREVWSUNFKDB4MGE1Yywg MHgyMDBhKSwgLmRyaXZlcl9pbmZvID0gQlRVU0JfV1JPTkdfU0NPX01UVSB9LA0KPiAtCXsgVVNC X0RFVklDRSgweDBhNWMsIDB4MjAwOSksIC5kcml2ZXJfaW5mbyA9IEJUVVNCX0JDTTkyMDM1IH0s DQo+ICsJeyBVU0JfREVWSUNFKDB4MGE1YywgMHgyMDM1KSwgLmRyaXZlcl9pbmZvID0gKHVuc2ln bmVkIGxvbmcpICZ3cm9uZ19zY29fbXR1IH0sDQo+ICsJeyBVU0JfREVWSUNFKDB4MGE1YywgMHgy MDBhKSwgLmRyaXZlcl9pbmZvID0gKHVuc2lnbmVkIGxvbmcpICZ3cm9uZ19zY29fbXR1IH0sDQo+ ICsJeyBVU0JfREVWSUNFKDB4MGE1YywgMHgyMDA5KSwgLmRyaXZlcl9pbmZvID0gKHVuc2lnbmVk IGxvbmcpIA0KPiArJmJjbTkyMDM1IH0sDQo+ICANCj4gIAkvKiBCcm9hZGNvbSBCQ00yMDQ1ICov DQo+IC0JeyBVU0JfREVWSUNFKDB4MGE1YywgMHgyMDM5KSwgLmRyaXZlcl9pbmZvID0gQlRVU0Jf V1JPTkdfU0NPX01UVSB9LA0KPiAtCXsgVVNCX0RFVklDRSgweDBhNWMsIDB4MjEwMSksIC5kcml2 ZXJfaW5mbyA9IEJUVVNCX1dST05HX1NDT19NVFUgfSwNCj4gKwl7IFVTQl9ERVZJQ0UoMHgwYTVj LCAweDIwMzkpLCAuZHJpdmVyX2luZm8gPSAodW5zaWduZWQgbG9uZykgJndyb25nX3Njb19tdHUg fSwNCj4gKwl7IFVTQl9ERVZJQ0UoMHgwYTVjLCAweDIxMDEpLCAuZHJpdmVyX2luZm8gPSAodW5z aWduZWQgbG9uZykgDQo+ICsmd3Jvbmdfc2NvX210dSB9LA0KPiAgDQo+ICAJLyogSUJNL0xlbm92 byBUaGlua1BhZCB3aXRoIEJyb2FkY29tIGNoaXAgKi8NCj4gLQl7IFVTQl9ERVZJQ0UoMHgwYTVj LCAweDIwMWUpLCAuZHJpdmVyX2luZm8gPSBCVFVTQl9XUk9OR19TQ09fTVRVIH0sDQo+IC0JeyBV U0JfREVWSUNFKDB4MGE1YywgMHgyMTEwKSwgLmRyaXZlcl9pbmZvID0gQlRVU0JfV1JPTkdfU0NP X01UVSB9LA0KPiArCXsgVVNCX0RFVklDRSgweDBhNWMsIDB4MjAxZSksIC5kcml2ZXJfaW5mbyA9 ICh1bnNpZ25lZCBsb25nKSAmd3Jvbmdfc2NvX210dSB9LA0KPiArCXsgVVNCX0RFVklDRSgweDBh NWMsIDB4MjExMCksIC5kcml2ZXJfaW5mbyA9ICh1bnNpZ25lZCBsb25nKSANCj4gKyZ3cm9uZ19z Y29fbXR1IH0sDQo+ICANCj4gIAkvKiBIUCBsYXB0b3Agd2l0aCBCcm9hZGNvbSBjaGlwICovDQo+ IC0JeyBVU0JfREVWSUNFKDB4MDNmMCwgMHgxNzFkKSwgLmRyaXZlcl9pbmZvID0gQlRVU0JfV1JP TkdfU0NPX01UVSB9LA0KPiArCXsgVVNCX0RFVklDRSgweDAzZjAsIDB4MTcxZCksIC5kcml2ZXJf aW5mbyA9ICh1bnNpZ25lZCBsb25nKSANCj4gKyZ3cm9uZ19zY29fbXR1IH0sDQo+ICANCj4gIAkv KiBEZWxsIGxhcHRvcCB3aXRoIEJyb2FkY29tIGNoaXAgKi8NCj4gLQl7IFVTQl9ERVZJQ0UoMHg0 MTNjLCAweDgxMjYpLCAuZHJpdmVyX2luZm8gPSBCVFVTQl9XUk9OR19TQ09fTVRVIH0sDQo+ICsJ eyBVU0JfREVWSUNFKDB4NDEzYywgMHg4MTI2KSwgLmRyaXZlcl9pbmZvID0gKHVuc2lnbmVkIGxv bmcpIA0KPiArJndyb25nX3Njb19tdHUgfSwNCj4gIA0KPiAgCS8qIERlbGwgV2lyZWxlc3MgMzcw IGFuZCA0MTAgZGV2aWNlcyAqLw0KPiAtCXsgVVNCX0RFVklDRSgweDQxM2MsIDB4ODE1MiksIC5k cml2ZXJfaW5mbyA9IEJUVVNCX1dST05HX1NDT19NVFUgfSwNCj4gLQl7IFVTQl9ERVZJQ0UoMHg0 MTNjLCAweDgxNTYpLCAuZHJpdmVyX2luZm8gPSBCVFVTQl9XUk9OR19TQ09fTVRVIH0sDQo+ICsJ eyBVU0JfREVWSUNFKDB4NDEzYywgMHg4MTUyKSwgLmRyaXZlcl9pbmZvID0gKHVuc2lnbmVkIGxv bmcpICZ3cm9uZ19zY29fbXR1IH0sDQo+ICsJeyBVU0JfREVWSUNFKDB4NDEzYywgMHg4MTU2KSwg LmRyaXZlcl9pbmZvID0gKHVuc2lnbmVkIGxvbmcpIA0KPiArJndyb25nX3Njb19tdHUgfSwNCj4g IA0KPiAgCS8qIEJlbGtpbiBGOFQwMTIgYW5kIEY4VDAxMyBkZXZpY2VzICovDQo+IC0JeyBVU0Jf REVWSUNFKDB4MDUwZCwgMHgwMDEyKSwgLmRyaXZlcl9pbmZvID0gQlRVU0JfV1JPTkdfU0NPX01U VSB9LA0KPiAtCXsgVVNCX0RFVklDRSgweDA1MGQsIDB4MDAxMyksIC5kcml2ZXJfaW5mbyA9IEJU VVNCX1dST05HX1NDT19NVFUgfSwNCj4gKwl7IFVTQl9ERVZJQ0UoMHgwNTBkLCAweDAwMTIpLCAu ZHJpdmVyX2luZm8gPSAodW5zaWduZWQgbG9uZykgJndyb25nX3Njb19tdHUgfSwNCj4gKwl7IFVT Ql9ERVZJQ0UoMHgwNTBkLCAweDAwMTMpLCAuZHJpdmVyX2luZm8gPSAodW5zaWduZWQgbG9uZykg DQo+ICsmd3Jvbmdfc2NvX210dSB9LA0KPiAgDQo+ICAJLyogQXN1cyBXTC1CVEQyMDIgZGV2aWNl ICovDQo+IC0JeyBVU0JfREVWSUNFKDB4MGIwNSwgMHgxNzE1KSwgLmRyaXZlcl9pbmZvID0gQlRV U0JfV1JPTkdfU0NPX01UVSB9LA0KPiArCXsgVVNCX0RFVklDRSgweDBiMDUsIDB4MTcxNSksIC5k cml2ZXJfaW5mbyA9ICh1bnNpZ25lZCBsb25nKSANCj4gKyZ3cm9uZ19zY29fbXR1IH0sDQo+ICAN Cj4gIAkvKiBLZW5zaW5ndG9uIEJsdWV0b290aCBVU0IgYWRhcHRlciAqLw0KPiAtCXsgVVNCX0RF VklDRSgweDA0N2QsIDB4MTA1ZSksIC5kcml2ZXJfaW5mbyA9IEJUVVNCX1dST05HX1NDT19NVFUg fSwNCj4gKwl7IFVTQl9ERVZJQ0UoMHgwNDdkLCAweDEwNWUpLCAuZHJpdmVyX2luZm8gPSAodW5z aWduZWQgbG9uZykgDQo+ICsmd3Jvbmdfc2NvX210dSB9LA0KPiAgDQo+ICAJLyogUlRYIFRlbGVj b20gYmFzZWQgYWRhcHRlcnMgd2l0aCBidWdneSBTQ08gc3VwcG9ydCAqLw0KPiAtCXsgVVNCX0RF VklDRSgweDA0MDAsIDB4MDgwNyksIC5kcml2ZXJfaW5mbyA9IEJUVVNCX0JST0tFTl9JU09DIH0s DQo+IC0JeyBVU0JfREVWSUNFKDB4MDQwMCwgMHgwODBhKSwgLmRyaXZlcl9pbmZvID0gQlRVU0Jf QlJPS0VOX0lTT0MgfSwNCj4gKwl7IFVTQl9ERVZJQ0UoMHgwNDAwLCAweDA4MDcpLCAuZHJpdmVy X2luZm8gPSAodW5zaWduZWQgbG9uZykgJmJyb2tlbl9pc29jIH0sDQo+ICsJeyBVU0JfREVWSUNF KDB4MDQwMCwgMHgwODBhKSwgLmRyaXZlcl9pbmZvID0gKHVuc2lnbmVkIGxvbmcpIA0KPiArJmJy b2tlbl9pc29jIH0sDQo+ICANCj4gIAkvKiBDT05XSVNFIFRlY2hub2xvZ3kgYmFzZWQgYWRhcHRl cnMgd2l0aCBidWdneSBTQ08gc3VwcG9ydCAqLw0KPiAtCXsgVVNCX0RFVklDRSgweDBlNWUsIDB4 NjYyMiksIC5kcml2ZXJfaW5mbyA9IEJUVVNCX0JST0tFTl9JU09DIH0sDQo+ICsJeyBVU0JfREVW SUNFKDB4MGU1ZSwgMHg2NjIyKSwgLmRyaXZlcl9pbmZvID0gKHVuc2lnbmVkIGxvbmcpIA0KPiAr JmJyb2tlbl9pc29jIH0sDQo+ICANCj4gIAkvKiBEaWdpYW5zd2VyIGRldmljZXMgKi8NCj4gLQl7 IFVTQl9ERVZJQ0UoMHgwOGZkLCAweDAwMDEpLCAuZHJpdmVyX2luZm8gPSBCVFVTQl9ESUdJQU5T V0VSIH0sDQo+IC0JeyBVU0JfREVWSUNFKDB4MDhmZCwgMHgwMDAyKSwgLmRyaXZlcl9pbmZvID0g QlRVU0JfSUdOT1JFIH0sDQo+ICsJeyBVU0JfREVWSUNFKDB4MDhmZCwgMHgwMDAxKSwgLmRyaXZl cl9pbmZvID0gKHVuc2lnbmVkIGxvbmcpICZkaWdpYW5zd2VyIH0sDQo+ICsJeyBVU0JfREVWSUNF KDB4MDhmZCwgMHgwMDAyKSwgLmRyaXZlcl9pbmZvID0gKHVuc2lnbmVkIGxvbmcpICZpZ25vcmUg DQo+ICt9LA0KPiAgDQo+ICAJLyogQ1NSIEJsdWVDb3JlIEJsdWV0b290aCBTbmlmZmVyICovDQo+ IC0JeyBVU0JfREVWSUNFKDB4MGExMiwgMHgwMDAyKSwgLmRyaXZlcl9pbmZvID0gQlRVU0JfU05J RkZFUiB9LA0KPiArCXsgVVNCX0RFVklDRSgweDBhMTIsIDB4MDAwMiksIC5kcml2ZXJfaW5mbyA9 ICh1bnNpZ25lZCBsb25nKSANCj4gKyZzbmlmZmVyIH0sDQo+ICANCj4gIAkvKiBGcm9udGxpbmUg Q29tUHJvYmUgQmx1ZXRvb3RoIFNuaWZmZXIgKi8NCj4gLQl7IFVTQl9ERVZJQ0UoMHgxNmQzLCAw eDAwMDIpLCAuZHJpdmVyX2luZm8gPSBCVFVTQl9TTklGRkVSIH0sDQo+ICsJeyBVU0JfREVWSUNF KDB4MTZkMywgMHgwMDAyKSwgLmRyaXZlcl9pbmZvID0gKHVuc2lnbmVkIGxvbmcpIA0KPiArJnNu aWZmZXIgfSwNCj4gIA0KPiAgCXsgfQkvKiBUZXJtaW5hdGluZyBlbnRyeSAqLw0KPiAgfTsNCj4g QEAgLTkxMCwxMiArOTU1LDEyIEBAIHN0YXRpYyB2b2lkIGJ0dXNiX3dha2VyKHN0cnVjdCB3b3Jr X3N0cnVjdCAqd29yaykNCj4gIAl1c2JfYXV0b3BtX3B1dF9pbnRlcmZhY2UoZGF0YS0+aW50Zik7 DQo+ICB9DQo+ICANCj4gLXN0YXRpYyBpbnQgYnR1c2JfcHJvYmUoc3RydWN0IHVzYl9pbnRlcmZh Y2UgKmludGYsDQo+IC0JCQkJY29uc3Qgc3RydWN0IHVzYl9kZXZpY2VfaWQgKmlkKQ0KPiAraW50 IGJ0dXNiX3Byb2JlKHN0cnVjdCB1c2JfaW50ZXJmYWNlICppbnRmLCBjb25zdCBzdHJ1Y3QgDQo+ ICt1c2JfZGV2aWNlX2lkICppZCkNCj4gIHsNCj4gIAlzdHJ1Y3QgdXNiX2VuZHBvaW50X2Rlc2Ny aXB0b3IgKmVwX2Rlc2M7DQo+ICAJc3RydWN0IGJ0dXNiX2RhdGEgKmRhdGE7DQo+ICAJc3RydWN0 IGhjaV9kZXYgKmhkZXY7DQo+ICsJc3RydWN0IGJ0dXNiX2RyaXZlcl9pbmZvICppbmZvOw0KPiAg CWludCBpLCBlcnI7DQo+ICANCj4gIAlCVF9EQkcoImludGYgJXAgaWQgJXAiLCBpbnRmLCBpZCk7 DQo+IEBAIC05MzEsMTkgKzk3NiwyOCBAQCBzdGF0aWMgaW50IGJ0dXNiX3Byb2JlKHN0cnVjdCB1 c2JfaW50ZXJmYWNlICppbnRmLA0KPiAgCQkJaWQgPSBtYXRjaDsNCj4gIAl9DQo+ICANCj4gLQlp ZiAoaWQtPmRyaXZlcl9pbmZvID09IEJUVVNCX0lHTk9SRSkNCj4gKwkvKg0KPiArCSAqIE1ha2Ug c3VyZSB0aGUgZHJpdmVyX2luZm8gaXMgbm90IG51bGwgb3IgMCBiZWNhdXNlIHRoZSBjb2RlIGJl bG93DQo+ICsJICogbmVlZCB0byBhY2Nlc3MgdGhlIGZsYWdzDQo+ICsJICovDQo+ICsJaWYgKCFp ZC0+ZHJpdmVyX2luZm8pDQo+ICsJCWluZm8gPSAoc3RydWN0IGJ0dXNiX2RyaXZlcl9pbmZvICop ICZnZW5lcmljOw0KPiArCWVsc2UNCj4gKwkJaW5mbyA9IChzdHJ1Y3QgYnR1c2JfZHJpdmVyX2lu Zm8gKikgaWQtPmRyaXZlcl9pbmZvOw0KPiArDQo+ICsJaWYgKGluZm8tPmZsYWdzID09IEJUVVNC X0lHTk9SRSkNCj4gIAkJcmV0dXJuIC1FTk9ERVY7DQo+ICANCj4gLQlpZiAoaWdub3JlX2RnYSAm JiBpZC0+ZHJpdmVyX2luZm8gJiBCVFVTQl9ESUdJQU5TV0VSKQ0KPiArCWlmIChpZ25vcmVfZGdh ICYmIChpbmZvLT5mbGFncyAmIEJUVVNCX0RJR0lBTlNXRVIpKQ0KPiAgCQlyZXR1cm4gLUVOT0RF VjsNCj4gIA0KPiAtCWlmIChpZ25vcmVfY3NyICYmIGlkLT5kcml2ZXJfaW5mbyAmIEJUVVNCX0NT UikNCj4gKwlpZiAoaWdub3JlX2NzciAmJiAoaW5mby0+ZmxhZ3MgJiBCVFVTQl9DU1IpKQ0KPiAg CQlyZXR1cm4gLUVOT0RFVjsNCj4gIA0KPiAtCWlmIChpZ25vcmVfc25pZmZlciAmJiBpZC0+ZHJp dmVyX2luZm8gJiBCVFVTQl9TTklGRkVSKQ0KPiArCWlmIChpZ25vcmVfc25pZmZlciAmJiAoaW5m by0+ZmxhZ3MgJiBCVFVTQl9TTklGRkVSKSkNCj4gIAkJcmV0dXJuIC1FTk9ERVY7DQo+ICANCj4g LQlpZiAoaWQtPmRyaXZlcl9pbmZvICYgQlRVU0JfQVRIMzAxMikgew0KPiArCWlmIChpbmZvLT5m bGFncyAmIEJUVVNCX0FUSDMwMTIpIHsNCj4gIAkJc3RydWN0IHVzYl9kZXZpY2UgKnVkZXYgPSBp bnRlcmZhY2VfdG9fdXNiZGV2KGludGYpOw0KPiAgDQo+ICAJCS8qIE9sZCBmaXJtd2FyZSB3b3Vs ZCBvdGhlcndpc2UgbGV0IGF0aDNrIGRyaXZlciBsb2FkIEBAIC0xMDEyLDI2IA0KPiArMTA2Niwz MCBAQCBzdGF0aWMgaW50IGJ0dXNiX3Byb2JlKHN0cnVjdCB1c2JfaW50ZXJmYWNlICppbnRmLA0K PiAgCWhkZXYtPnNlbmQgICAgID0gYnR1c2Jfc2VuZF9mcmFtZTsNCj4gIAloZGV2LT5ub3RpZnkg ICA9IGJ0dXNiX25vdGlmeTsNCj4gIA0KPiArCS8qIHZlbmRvciBzcGVjaWZpYyBkZXZpY2UgaW5p dGlhbGl6YXRpb24gcm91dGluZXMgKi8NCj4gKwloZGV2LT52c2Rldl9pbml0ID0gaW5mby0+dnNk ZXZfaW5pdDsNCj4gKwloZGV2LT52c2Rldl9ldmVudCA9IGluZm8tPnZzZGV2X2V2ZW50Ow0KPiAr DQo+ICAJLyogSW50ZXJmYWNlIG51bWJlcnMgYXJlIGhhcmRjb2RlZCBpbiB0aGUgc3BlY2lmaWNh dGlvbiAqLw0KPiAgCWRhdGEtPmlzb2MgPSB1c2JfaWZudW1fdG9faWYoZGF0YS0+dWRldiwgMSk7 DQo+ICANCj4gIAlpZiAoIXJlc2V0KQ0KPiAgCQlzZXRfYml0KEhDSV9RVUlSS19SRVNFVF9PTl9D TE9TRSwgJmhkZXYtPnF1aXJrcyk7DQo+ICANCj4gLQlpZiAoZm9yY2Vfc2NvZml4IHx8IGlkLT5k cml2ZXJfaW5mbyAmIEJUVVNCX1dST05HX1NDT19NVFUpIHsNCj4gKwlpZiAoZm9yY2Vfc2NvZml4 IHx8IChpbmZvLT5mbGFncyAmIEJUVVNCX1dST05HX1NDT19NVFUpKSB7DQo+ICAJCWlmICghZGlz YWJsZV9zY29maXgpDQo+ICAJCQlzZXRfYml0KEhDSV9RVUlSS19GSVhVUF9CVUZGRVJfU0laRSwg JmhkZXYtPnF1aXJrcyk7DQo+ICAJfQ0KPiAgDQo+IC0JaWYgKGlkLT5kcml2ZXJfaW5mbyAmIEJU VVNCX0JST0tFTl9JU09DKQ0KPiArCWlmIChpbmZvLT5mbGFncyAmIEJUVVNCX0JST0tFTl9JU09D KQ0KPiAgCQlkYXRhLT5pc29jID0gTlVMTDsNCj4gIA0KPiAtCWlmIChpZC0+ZHJpdmVyX2luZm8g JiBCVFVTQl9ESUdJQU5TV0VSKSB7DQo+ICsJaWYgKGluZm8tPmZsYWdzICYgQlRVU0JfRElHSUFO U1dFUikgew0KPiAgCQlkYXRhLT5jbWRyZXFfdHlwZSA9IFVTQl9UWVBFX1ZFTkRPUjsNCj4gIAkJ c2V0X2JpdChIQ0lfUVVJUktfUkVTRVRfT05fQ0xPU0UsICZoZGV2LT5xdWlya3MpOw0KPiAgCX0N Cj4gIA0KPiAtCWlmIChpZC0+ZHJpdmVyX2luZm8gJiBCVFVTQl9DU1IpIHsNCj4gKwlpZiAoaW5m by0+ZmxhZ3MgJiBCVFVTQl9DU1IpIHsNCj4gIAkJc3RydWN0IHVzYl9kZXZpY2UgKnVkZXYgPSBk YXRhLT51ZGV2Ow0KPiAgDQo+ICAJCS8qIE9sZCBmaXJtd2FyZSB3b3VsZCBvdGhlcndpc2UgZXhl Y3V0ZSBVU0IgcmVzZXQgKi8gQEAgLTEwMzksNyANCj4gKzEwOTcsNyBAQCBzdGF0aWMgaW50IGJ0 dXNiX3Byb2JlKHN0cnVjdCB1c2JfaW50ZXJmYWNlICppbnRmLA0KPiAgCQkJc2V0X2JpdChIQ0lf UVVJUktfUkVTRVRfT05fQ0xPU0UsICZoZGV2LT5xdWlya3MpOw0KPiAgCX0NCj4gIA0KPiAtCWlm IChpZC0+ZHJpdmVyX2luZm8gJiBCVFVTQl9TTklGRkVSKSB7DQo+ICsJaWYgKGluZm8tPmZsYWdz ICYgQlRVU0JfU05JRkZFUikgew0KPiAgCQlzdHJ1Y3QgdXNiX2RldmljZSAqdWRldiA9IGRhdGEt PnVkZXY7DQo+ICANCj4gIAkJLyogTmV3IHNuaWZmZXIgZmlybXdhcmUgaGFzIGNyaXBwbGVkIEhD SSBpbnRlcmZhY2UgKi8gQEAgLTEwNDksNyANCj4gKzExMDcsNyBAQCBzdGF0aWMgaW50IGJ0dXNi X3Byb2JlKHN0cnVjdCB1c2JfaW50ZXJmYWNlICppbnRmLA0KPiAgCQlkYXRhLT5pc29jID0gTlVM TDsNCj4gIAl9DQo+ICANCj4gLQlpZiAoaWQtPmRyaXZlcl9pbmZvICYgQlRVU0JfQkNNOTIwMzUp IHsNCj4gKwlpZiAoaW5mby0+ZmxhZ3MgJiBCVFVTQl9CQ005MjAzNSkgew0KPiAgCQl1bnNpZ25l ZCBjaGFyIGNtZFtdID0geyAweDNiLCAweGZjLCAweDAxLCAweDAwIH07DQo+ICAJCXN0cnVjdCBz a19idWZmICpza2I7DQo+ICANCj4gQEAgLTEwNzksOCArMTEzNyw5IEBAIHN0YXRpYyBpbnQgYnR1 c2JfcHJvYmUoc3RydWN0IHVzYl9pbnRlcmZhY2UgDQo+ICppbnRmLA0KPiAgDQo+ICAJcmV0dXJu IDA7DQo+ICB9DQo+ICtFWFBPUlRfU1lNQk9MX0dQTChidHVzYl9wcm9iZSk7DQo+ICANCj4gLXN0 YXRpYyB2b2lkIGJ0dXNiX2Rpc2Nvbm5lY3Qoc3RydWN0IHVzYl9pbnRlcmZhY2UgKmludGYpDQo+ ICt2b2lkIGJ0dXNiX2Rpc2Nvbm5lY3Qoc3RydWN0IHVzYl9pbnRlcmZhY2UgKmludGYpDQo+ICB7 DQo+ICAJc3RydWN0IGJ0dXNiX2RhdGEgKmRhdGEgPSB1c2JfZ2V0X2ludGZkYXRhKGludGYpOw0K PiAgCXN0cnVjdCBoY2lfZGV2ICpoZGV2Ow0KPiBAQCAtMTEwNSw5ICsxMTY0LDEwIEBAIHN0YXRp YyB2b2lkIGJ0dXNiX2Rpc2Nvbm5lY3Qoc3RydWN0IA0KPiB1c2JfaW50ZXJmYWNlICppbnRmKQ0K PiAgDQo+ICAJaGNpX2ZyZWVfZGV2KGhkZXYpOw0KPiAgfQ0KPiArRVhQT1JUX1NZTUJPTF9HUEwo YnR1c2JfZGlzY29ubmVjdCk7DQo+ICANCj4gICNpZmRlZiBDT05GSUdfUE0NCj4gLXN0YXRpYyBp bnQgYnR1c2Jfc3VzcGVuZChzdHJ1Y3QgdXNiX2ludGVyZmFjZSAqaW50ZiwgcG1fbWVzc2FnZV90 IA0KPiBtZXNzYWdlKQ0KPiAraW50IGJ0dXNiX3N1c3BlbmQoc3RydWN0IHVzYl9pbnRlcmZhY2Ug KmludGYsIHBtX21lc3NhZ2VfdCBtZXNzYWdlKQ0KPiAgew0KPiAgCXN0cnVjdCBidHVzYl9kYXRh ICpkYXRhID0gdXNiX2dldF9pbnRmZGF0YShpbnRmKTsNCj4gIA0KPiBAQCAtMTEzMyw2ICsxMTkz LDcgQEAgc3RhdGljIGludCBidHVzYl9zdXNwZW5kKHN0cnVjdCB1c2JfaW50ZXJmYWNlIA0KPiAq aW50ZiwgcG1fbWVzc2FnZV90IG1lc3NhZ2UpDQo+ICANCj4gIAlyZXR1cm4gMDsNCj4gIH0NCj4g K0VYUE9SVF9TWU1CT0xfR1BMKGJ0dXNiX3N1c3BlbmQpOw0KPiAgDQo+ICBzdGF0aWMgdm9pZCBw bGF5X2RlZmVycmVkKHN0cnVjdCBidHVzYl9kYXRhICpkYXRhKSAgeyBAQCAtMTE0OSw3IA0KPiAr MTIxMCw3IEBAIHN0YXRpYyB2b2lkIHBsYXlfZGVmZXJyZWQoc3RydWN0IGJ0dXNiX2RhdGEgKmRh dGEpDQo+ICAJdXNiX3NjdXR0bGVfYW5jaG9yZWRfdXJicygmZGF0YS0+ZGVmZXJyZWQpOw0KPiAg fQ0KPiAgDQo+IC1zdGF0aWMgaW50IGJ0dXNiX3Jlc3VtZShzdHJ1Y3QgdXNiX2ludGVyZmFjZSAq aW50ZikNCj4gK2ludCBidHVzYl9yZXN1bWUoc3RydWN0IHVzYl9pbnRlcmZhY2UgKmludGYpDQo+ ICB7DQo+ICAJc3RydWN0IGJ0dXNiX2RhdGEgKmRhdGEgPSB1c2JfZ2V0X2ludGZkYXRhKGludGYp Ow0KPiAgCXN0cnVjdCBoY2lfZGV2ICpoZGV2ID0gZGF0YS0+aGRldjsNCj4gQEAgLTEyMDUsOCAr MTI2NiwxMCBAQCBkb25lOg0KPiAgDQo+ICAJcmV0dXJuIGVycjsNCj4gIH0NCj4gK0VYUE9SVF9T WU1CT0xfR1BMKGJ0dXNiX3Jlc3VtZSk7DQo+ICAjZW5kaWYNCj4gIA0KPiArDQo+ICBzdGF0aWMg c3RydWN0IHVzYl9kcml2ZXIgYnR1c2JfZHJpdmVyID0gew0KPiAgCS5uYW1lCQk9ICJidHVzYiIs DQo+ICAJLnByb2JlCQk9IGJ0dXNiX3Byb2JlLA0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ibHVl dG9vdGgvYnR1c2IuaCBiL2RyaXZlcnMvYmx1ZXRvb3RoL2J0dXNiLmggbmV3IA0KPiBmaWxlIG1v ZGUgMTAwNjQ0IGluZGV4IDAwMDAwMDAuLmMyNmE4NDUNCj4gLS0tIC9kZXYvbnVsbA0KPiArKysg Yi9kcml2ZXJzL2JsdWV0b290aC9idHVzYi5oDQo+IEBAIC0wLDAgKzEsNTMgQEANCj4gKy8qDQo+ ICsgKg0KPiArICogIEdlbmVyaWMgQmx1ZXRvb3RoIFVTQiBkcml2ZXINCj4gKyAqDQo+ICsgKiAg Q29weXJpZ2h0IChDKSAyMDA1LTIwMDggIE1hcmNlbCBIb2x0bWFubiA8bWFyY2VsQGhvbHRtYW5u Lm9yZz4NCj4gKyAqDQo+ICsgKg0KPiArICogIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJl OyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgDQo+ICttb2RpZnkNCj4gKyAqICBpdCB1 bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxp c2hlZCANCj4gK2J5DQo+ICsgKiAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVy IHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3INCj4gKyAqICAoYXQgeW91ciBvcHRpb24pIGFu eSBsYXRlciB2ZXJzaW9uLg0KPiArICoNCj4gKyAqICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0 ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwNCj4gKyAqICBidXQgV0lUSE9V VCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZg0KPiAr ICogIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4g IFNlZSB0aGUNCj4gKyAqICBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRh aWxzLg0KPiArICoNCj4gKyAqICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRo ZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQ0KPiArICogIGFsb25nIHdpdGggdGhpcyBwcm9n cmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlDQo+ICsgKiAgRm91bmRhdGlv biwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIA0KPiArMDIx MTEtMTMwNyAgVVNBDQo+ICsgKg0KPiArICovDQo+ICsjaWZuZGVmIF9CVFVTQl9IDQo+ICsjZGVm aW5lIF9CVFVTQl9IDQo+ICsNCj4gK3N0cnVjdCBidHVzYl9kcml2ZXJfaW5mbyB7DQo+ICsJY2hh cgkqZGVzY3JpcHRpb247DQo+ICsJaW50CWZsYWdzOw0KPiArI2RlZmluZSBCVFVTQl9HRU5FUklD CQkweDAwDQo+ICsjZGVmaW5lIEJUVVNCX0lHTk9SRQkJMHgwMQ0KPiArI2RlZmluZSBCVFVTQl9E SUdJQU5TV0VSCTB4MDINCj4gKyNkZWZpbmUgQlRVU0JfQ1NSCQkweDA0DQo+ICsjZGVmaW5lIEJU VVNCX1NOSUZGRVIJCTB4MDgNCj4gKyNkZWZpbmUgQlRVU0JfQkNNOTIwMzUJCTB4MTANCj4gKyNk ZWZpbmUgQlRVU0JfQlJPS0VOX0lTT0MJMHgyMA0KPiArI2RlZmluZSBCVFVTQl9XUk9OR19TQ09f TVRVCTB4NDANCj4gKyNkZWZpbmUgQlRVU0JfQVRIMzAxMgkJMHg4MA0KPiArDQo+ICsJLyogZW50 cnkgcG9pbnQgZm9yIHZlbmRvciBzcGVjaWZpYyBkZXZpY2UgaW5pdGlhbGl6YXRpb24gKi8NCj4g KwlpbnQJKCp2c2Rldl9pbml0KShzdHJ1Y3QgaGNpX2RldiAqaGRldik7DQoNCj4+IEtlZXAgaXQg c2ltcGxlLiBDYWxsIHRoaXMgKCpzZXR1cCkuDQoNCj4gKw0KPiArCS8qIGV2ZW50IGhhbmRsZXIg ZHVyaW5nIHZlbmRvciBzcGVjaWZpYyBkZXZpY2UgaW5pdGlhdGlvbiBwaGFzZSAqLw0KPiArCXZv aWQJKCp2c2Rldl9ldmVudCkoc3RydWN0IGhjaV9kZXYgKmhkZXYsIHN0cnVjdCBza19idWZmICpz a2IpOw0KDQo+PkFuZCB0aGlzIGp1c3QgKCpldmVudCkuDQoNCj4+IEkgYW0gc3RpbGwgY3VyaW91 cyBpZiB3ZSB3b3VsZCBuZWVkIHRoZSBldmVudCBwYXJ0IGF0IGFsbCB3aGVuIHVzaW5nIEhDSSBj b21tYW5kIGhhbmRsaW5nIHdpdGggY2FsbGJhY2tzLCBidXQgSSBrbm93IGF0IGxlYXN0IHRoYXQg Q1NSIGlzIG5vdCBmb2xsb3dpbmcgdGhlIEhDSSBzcGVjaWZpY2F0aW9uIGZvciBjb21tYW5kICsg ZXZlbnQsIHNvIGl0IG1pZ2h0IGJlIGEgZ29vZCBpZGVhLg0KDQo+ICt9Ow0KPiArDQo+ICtleHRl cm4gaW50IGJ0dXNiX3Byb2JlKHN0cnVjdCB1c2JfaW50ZXJmYWNlICosIGNvbnN0IHN0cnVjdCAN Cj4gK3VzYl9kZXZpY2VfaWQgKik7IGV4dGVybiB2b2lkIGJ0dXNiX2Rpc2Nvbm5lY3Qoc3RydWN0 IHVzYl9pbnRlcmZhY2UgDQo+ICsqKTsgI2lmZGVmIENPTkZJR19QTSBleHRlcm4gaW50IGJ0dXNi X3N1c3BlbmQoc3RydWN0IHVzYl9pbnRlcmZhY2UgKiwgDQo+ICtwbV9tZXNzYWdlX3QpOyBleHRl cm4gaW50IGJ0dXNiX3Jlc3VtZShzdHJ1Y3QgdXNiX2ludGVyZmFjZSAqKTsgDQo+ICsjZW5kaWYN Cj4gKw0KPiArI2VuZGlmIC8qIF9CVFVTQl9IICovDQo+IGRpZmYgLS1naXQgYS9pbmNsdWRlL25l dC9ibHVldG9vdGgvaGNpX2NvcmUuaCANCj4gYi9pbmNsdWRlL25ldC9ibHVldG9vdGgvaGNpX2Nv cmUuaA0KPiBpbmRleCA2YTMzMzdlLi40YWY2MDFkIDEwMDY0NA0KPiAtLS0gYS9pbmNsdWRlL25l dC9ibHVldG9vdGgvaGNpX2NvcmUuaA0KPiArKysgYi9pbmNsdWRlL25ldC9ibHVldG9vdGgvaGNp X2NvcmUuaA0KPiBAQCAtMjc1LDYgKzI3NSwxNiBAQCBzdHJ1Y3QgaGNpX2RldiB7DQo+ICAJaW50 ICgqc2VuZCkoc3RydWN0IHNrX2J1ZmYgKnNrYik7DQo+ICAJdm9pZCAoKm5vdGlmeSkoc3RydWN0 IGhjaV9kZXYgKmhkZXYsIHVuc2lnbmVkIGludCBldnQpOw0KPiAgCWludCAoKmlvY3RsKShzdHJ1 Y3QgaGNpX2RldiAqaGRldiwgdW5zaWduZWQgaW50IGNtZCwgdW5zaWduZWQgbG9uZyANCj4gYXJn KTsNCj4gKw0KPiArCS8qDQo+ICsJICogVE9ETzogQWRkZWQgZm9sbG93aW5nIG1lbWJlcnMgZm9y IHZlbmRvciBzcGVjaWZpYyBpbml0aWFsaXphdGlvbiB0bw0KPiArCSAqIG1ha2UgdGhlIGJsdWV0 b290aC5rbyB0cmFuc3BhcmVudCB0byB0aGUgaW50ZXJmYWNlLg0KPiArCSAqIFRoZXNlIG1lbWJl cnMgYXJlIHNldCBieSB0aGUgdmVuZG9yIHByb3ZpZGVkIGRyaXZlcg0KPiArCSAqLw0KPiArCWlu dAkJCXZzZGV2X2luaXRfZG9uZTsNCg0KPj4gRm9yIHRoaXMsIHBsZWFzZSB1c2UgZGV2X2ZsYWdz LiBObyBuZWVkIHdhc3RlIHNwYWNlIHdpdGggYW5vdGhlciB2YXJpYWJsZS4NCg0KPiArCXZvaWQJ CQkqdnNkZXZfcHJpdl9kYXRhOw0KPiArCWludCAoKnZzZGV2X2luaXQpKHN0cnVjdCBoY2lfZGV2 ICpoZGV2KTsNCj4gKwl2b2lkICgqdnNkZXZfZXZlbnQpKHN0cnVjdCBoY2lfZGV2ICpoZGV2LCBz dHJ1Y3Qgc2tfYnVmZiAqc2tiKTsNCj4gIH07DQoNCj4+IFJhdGhlciBsaWtlIHZlbmRvcl9zZXR1 cCBhbmQgdmVuZG9yX2V2ZW50IGhlcmUuIEkgZG8gbm90IGV2ZW4gd2FudCB0byBrbm93IHdoYXQg dnMgc3RhbmRzIGZvciA7KQ0KDQo+PiBIb3BlIHdlIGFyZSBub3QgZ2V0dGluZyBpbnRvIHRyb3Vi bGUgd2l0aCBkcml2ZXIgaWQgdGFibGVzIG5vcm1hbGx5IGJlaW5nIGNvbnN0Lg0KDQo+ICANCj4g IHN0cnVjdCBoY2lfY29ubiB7DQo+IGRpZmYgLS1naXQgYS9uZXQvYmx1ZXRvb3RoL2hjaV9jb3Jl LmMgYi9uZXQvYmx1ZXRvb3RoL2hjaV9jb3JlLmMgaW5kZXggDQo+IGU0MDcwNTEuLjgwYWExM2Yg MTAwNjQ0DQo+IC0tLSBhL25ldC9ibHVldG9vdGgvaGNpX2NvcmUuYw0KPiArKysgYi9uZXQvYmx1 ZXRvb3RoL2hjaV9jb3JlLmMNCj4gQEAgLTY4NSw2ICs2ODUsMTUgQEAgaW50IGhjaV9kZXZfb3Bl bihfX3UxNiBkZXYpDQo+ICAJCXNldF9iaXQoSENJX0lOSVQsICZoZGV2LT5mbGFncyk7DQo+ICAJ CWhkZXYtPmluaXRfbGFzdF9jbWQgPSAwOw0KPiAgDQo+ICsJCS8qIHZlbmRvciBzcGVjaWZpYyBk ZXZpY2UgaW5pdGlhbGl6YXRpb24gKi8NCj4gKwkJaWYgKGhkZXYtPnZzZGV2X2luaXQpIHsNCj4g KwkJCXJldCA9IGhkZXYtPnZzZGV2X2luaXQoaGRldik7DQo+ICsJCQloZGV2LT52c2Rldl9pbml0 X2RvbmUgPSAxOw0KPiArCQkJaGRldi0+dnNkZXZfZXZlbnQgPSBOVUxMOw0KPiArCQkJaWYgKHJl dCA8IDApDQo+ICsJCQkJZ290byBkb25lOw0KPiArCQl9DQo+ICsNCg0KPj4gRG8geW91IHJlYWxs eSB3YW50IHRvIGRvIHRoaXMgb24gZXZlcnkgaGNpY29uZmlnIGhjaTAgdXA/IEkgYXNzdW1lZCB0 aGlzIGlzIGEgb25lIHRpbWUgdGFzay4gU28geW91IG1pZ2h0IGJldHRlciBsb29rIGF0IGhjaV9w b3dlcl9vbigpIGZvciB0aGlzLg0KDQo+PiBJcyBhIEhDSV9SZXNldCBjb21tYW5kIHVubG9hZGlu ZyB0aGUgZmlybXdhcmUgcGF0Y2hlcy4NCg0KPiAgCQlyZXQgPSBfX2hjaV9yZXF1ZXN0KGhkZXYs IGhjaV9pbml0X3JlcSwgMCwgSENJX0lOSVRfVElNRU9VVCk7DQo+ICANCj4gIAkJaWYgKGxtcF9o b3N0X2xlX2NhcGFibGUoaGRldikpDQo+IEBAIC0yMTE5LDYgKzIxMjgsNyBAQCBpbnQgaGNpX3Nl bmRfY21kKHN0cnVjdCBoY2lfZGV2ICpoZGV2LCBfX3UxNiANCj4gb3Bjb2RlLCBfX3UzMiBwbGVu LCB2b2lkICpwYXJhbSkNCj4gIA0KPiAgCXJldHVybiAwOw0KPiAgfQ0KPiArRVhQT1JUX1NZTUJP TChoY2lfc2VuZF9jbWQpOw0KPiAgDQo+ICAvKiBHZXQgZGF0YSBmcm9tIHRoZSBwcmV2aW91c2x5 IHNlbnQgY29tbWFuZCAqLyAgdm9pZCANCj4gKmhjaV9zZW50X2NtZF9kYXRhKHN0cnVjdCBoY2lf ZGV2ICpoZGV2LCBfX3UxNiBvcGNvZGUpIEBAIC0yODAwLDcgDQo+ICsyODEwLDEwIEBAIHN0YXRp YyB2b2lkIGhjaV9yeF93b3JrKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykNCj4gIAkJc3dpdGNo IChidF9jYihza2IpLT5wa3RfdHlwZSkgew0KPiAgCQljYXNlIEhDSV9FVkVOVF9QS1Q6DQo+ICAJ CQlCVF9EQkcoIiVzIEV2ZW50IHBhY2tldCIsIGhkZXYtPm5hbWUpOw0KPiAtCQkJaGNpX2V2ZW50 X3BhY2tldChoZGV2LCBza2IpOw0KPiArCQkJaWYgKGhkZXYtPnZzZGV2X2V2ZW50ICYmICFoZGV2 LT52c2Rldl9pbml0X2RvbmUpDQo+ICsJCQkJaGRldi0+dnNkZXZfZXZlbnQoaGRldiwgc2tiKTsN Cj4gKwkJCWVsc2UNCj4gKwkJCQloY2lfZXZlbnRfcGFja2V0KGhkZXYsIHNrYik7DQo+ICAJCQli cmVhazsNCg0KPj4gTm90IGdvaW5nIHRocm91Z2ggaGNpX2V2ZW50X3BhY2tldCBpcyBhIGJhZCBp ZGVhLiBUaGF0IHdpbGwgc2NyZXcgb3ZlciB0aGUgZmxvdyBjb250cm9sIGhhbmRsaW5nIGZvciBj b21tYW5kcy4NCg0KPj4gUmVnYXJkcw0KDQo+PiBNYXJjZWwNCg0KUmVnYXJkcywNCkFsYmVydA0K DQoNCg0K
Marcel Holtmann
maintainerHi Albert,
Quoted 110 lines
Quoted 109 lines
This patch provides an extension of btusb to support device vendor can implement their own module to execute the vendor specific device initialization before the stack sends generic BT device initialization.
Signed-off-by Tedd Ho-Jeong An <[email protected]>--- drivers/bluetooth/btusb.c | 191 +++++++++++++++++++++++++------------- drivers/bluetooth/btusb.h | 53 +++++++++++ include/net/bluetooth/hci_core.h | 10 ++ net/bluetooth/hci_core.c | 15 ++- 4 files changed, 204 insertions(+), 65 deletions(-) create mode100644
drivers/bluetooth/btusb.hdrivers/bluetooth/btusb.c +19
-8@@ -26,6 +26,7 @@#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> +#include "btusb.h" #define VERSION "0.6"@@ -39,14 +40,59 @@ static bool reset = 1;static struct usb_driver btusb_driver; -#define BTUSB_IGNORE 0x01 -#define BTUSB_DIGIANSWER 0x02 -#define BTUSB_CSR 0x04 -#define BTUSB_SNIFFER 0x08 -#define BTUSB_BCM92035 0x10 -#define BTUSB_BROKEN_ISOC 0x20 -#define BTUSB_WRONG_SCO_MTU 0x40 -#define BTUSB_ATH3012 0x80 +/* +* Create btusb_driver_info struct for each driver_info flags used by +* blacklist since vendor's btusb driver will return btusb_driver_info struct. +*/ + +/* +* if the device is set to this, this menas that the device is +generic and +* doesn't require any vendor specific handling */ static const +struct btusb_driver_info generic = { + .description ="BTUSB Generic" , + .flags =BTUSB_GENERIC , +}; + +static const struct btusb_driver_info ignore = { + .description ="BTUSB Ignore" , + .flags =BTUSB_IGNORE , +};Quoted 1 line
I like the effort, but I think you went a little bit too far here. For these simple ones, we can easily keep our simple blacklist. It keeps the code more readable than this part. But I do appreciate the attempt in unifying this.
drivers/bluetooth/btusb.c +36
-2+ +static const struct btusb_driver_info digianswer = { + .description ="BTUSB DIGIANSWER" , + .flags =BTUSB_DIGIANSWER , +}; + +static const struct btusb_driver_info csr = { + .description ="BTUSB CSR" , + .flags =BTUSB_CSR , +}; + +static const struct btusb_driver_info sniffer = { + .description ="BTUSB Sniffer" , + .flags =BTUSB_SNIFFER , +}; + +static const struct btusb_driver_info bcm92035 = { + .description ="BTUSB BCM92035" , + .flags =BTUSB_BCM92035 , +}; + +static const struct btusb_driver_info broken_isoc = { + .description ="BTUSB Broken ISOC" , + .flags =BTUSB_BROKEN_ISOC , +}; + +static const struct btusb_driver_info wrong_sco_mtu = { + .description ="BTUSB Wrong SCO MTU" , + .flags =BTUSB_WRONG_SCO_MTU , +}; + +static const struct btusb_driver_info ath3012 = { + .description ="BTUSB Ath3012" , + .flags =BTUSB_ATH3012 , +};static struct usb_device_id btusb_table[] = {/* Generic Bluetooth USB device */ @@ -105,90 +151,89 @@ static struct usb_device_id btusb_table[] = { { }/* Terminating entry */ }; -MODULE_DEVICE_TABLE (usb, btusb_table);static struct usb_device_id blacklist_table[] = {/* CSR BlueCore devices */ - {USB_DEVICE (0x0a12 ,0x0001 ), .driver_info =BTUSB_CSR }, + {USB_DEVICE (0x0a12 ,0x0001 ), .driver_info = (unsigned long ) &csr },
Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
Keep the
blacklist_tableas it is. The important table to modify isbtusb_tableand use a commondriver_infothat will be shared between drivers.That would also make it simple to just add
BTUSB_IGNOREor a newBTUSB_VENDORflag to call out the drivers that have a separate driver with a vendor init function, but would match >> the Bluetooth general USB descriptors.I looked at usbnet minidriver as you suggested. If we do a similar scheme such that
btusb_probe()invokes the mini_driver's bind()/unbind() then btusb's usage ofdriver_infowill need to change from storing flags (ex:BTUSB_IGNORE) and change to store "static const struct" where it holds a struct containing the mini-driver's bind/unbind functions (just like usbnet minidriver). Are you good with this change? I also want to mention that in the patch containing the BT USB mini driver template, it already has its ownmodule_usb_driver()section with its VID/PID listed.
you know what. Just send around what you have right now after the cleanup and then I can take another look at it.
Regards
Marcel
QWNrbm93bGVkZ2VkLg0KDQpSZWdhcmRzLA0KQWxiZXJ0DQoNCg0KLS0tLS1PcmlnaW5hbCBNZXNz YWdlLS0tLS0NCkZyb206IE1hcmNlbCBIb2x0bWFubiBbbWFpbHRvOm1hcmNlbEBob2x0bWFubi5v cmddIA0KU2VudDogV2VkbmVzZGF5LCBPY3RvYmVyIDI0LCAyMDEyIDg6MTggQU0NClRvOiBIbywg QWxiZXJ0IE8NCkNjOiBsaW51eC1ibHVldG9vdGg7IEhlZGJlcmcsIEpvaGFuOyB0ZWRkLmhqLmFu QGdtYWlsLmNvbTsgQW4sIFRlZGQNClN1YmplY3Q6IFJlOiBbUkZDIDEvMl0gQmx1ZXRvb3RoOiBB ZGQgZHJpdmVyIGV4dGVuc2lvbiBmb3IgdmVuZG9yIHNwZWNpZmljIGluaXQNCg0KSGkgQWxiZXJ0 LA0KDQo+ID4gVGhpcyBwYXRjaCBwcm92aWRlcyBhbiBleHRlbnNpb24gb2YgYnR1c2IgdG8gc3Vw cG9ydCBkZXZpY2UgdmVuZG9yIA0KPiA+IGNhbiBpbXBsZW1lbnQgdGhlaXIgb3duIG1vZHVsZSB0 byBleGVjdXRlIHRoZSB2ZW5kb3Igc3BlY2lmaWMgZGV2aWNlIA0KPiA+IGluaXRpYWxpemF0aW9u IGJlZm9yZSB0aGUgc3RhY2sgc2VuZHMgZ2VuZXJpYyBCVCBkZXZpY2UgDQo+ID4gaW5pdGlhbGl6 YXRpb24uDQo+ID4gDQo+ID4gU2lnbmVkLW9mZi1ieTogVGVkZCBIby1KZW9uZyBBbiA8dGVkZC5h bkBpbnRlbC5jb20+DQo+ID4gLS0tDQo+ID4gIGRyaXZlcnMvYmx1ZXRvb3RoL2J0dXNiLmMgICAg ICAgIHwgIDE5MSArKysrKysrKysrKysrKysrKysrKysrKysrLS0tLS0tLS0tLS0tLQ0KPiA+ICBk cml2ZXJzL2JsdWV0b290aC9idHVzYi5oICAgICAgICB8ICAgNTMgKysrKysrKysrKysNCj4gPiAg aW5jbHVkZS9uZXQvYmx1ZXRvb3RoL2hjaV9jb3JlLmggfCAgIDEwICsrDQo+ID4gIG5ldC9ibHVl dG9vdGgvaGNpX2NvcmUuYyAgICAgICAgIHwgICAxNSArKy0NCj4gPiAgNCBmaWxlcyBjaGFuZ2Vk LCAyMDQgaW5zZXJ0aW9ucygrKSwgNjUgZGVsZXRpb25zKC0pICBjcmVhdGUgbW9kZQ0KPiA+IDEw MDY0NCBkcml2ZXJzL2JsdWV0b290aC9idHVzYi5oDQo+ID4gDQo+ID4gZGlmZiAtLWdpdCBhL2Ry aXZlcnMvYmx1ZXRvb3RoL2J0dXNiLmMgYi9kcml2ZXJzL2JsdWV0b290aC9idHVzYi5jIA0KPiA+ IGluZGV4IGY2MzdjMjUuLmFmYTE1NTggMTAwNjQ0DQo+ID4gLS0tIGEvZHJpdmVycy9ibHVldG9v dGgvYnR1c2IuYw0KPiA+ICsrKyBiL2RyaXZlcnMvYmx1ZXRvb3RoL2J0dXNiLmMNCj4gPiBAQCAt MjYsNiArMjYsNyBAQA0KPiA+ICANCj4gPiAgI2luY2x1ZGUgPG5ldC9ibHVldG9vdGgvYmx1ZXRv b3RoLmg+ICAjaW5jbHVkZSANCj4gPiA8bmV0L2JsdWV0b290aC9oY2lfY29yZS5oPg0KPiA+ICsj aW5jbHVkZSAiYnR1c2IuaCINCj4gPiAgDQo+ID4gICNkZWZpbmUgVkVSU0lPTiAiMC42Ig0KPiA+ ICANCj4gPiBAQCAtMzksMTQgKzQwLDU5IEBAIHN0YXRpYyBib29sIHJlc2V0ID0gMTsNCj4gPiAg DQo+ID4gIHN0YXRpYyBzdHJ1Y3QgdXNiX2RyaXZlciBidHVzYl9kcml2ZXI7DQo+ID4gIA0KPiA+ IC0jZGVmaW5lIEJUVVNCX0lHTk9SRQkJMHgwMQ0KPiA+IC0jZGVmaW5lIEJUVVNCX0RJR0lBTlNX RVIJMHgwMg0KPiA+IC0jZGVmaW5lIEJUVVNCX0NTUgkJMHgwNA0KPiA+IC0jZGVmaW5lIEJUVVNC X1NOSUZGRVIJCTB4MDgNCj4gPiAtI2RlZmluZSBCVFVTQl9CQ005MjAzNQkJMHgxMA0KPiA+IC0j ZGVmaW5lIEJUVVNCX0JST0tFTl9JU09DCTB4MjANCj4gPiAtI2RlZmluZSBCVFVTQl9XUk9OR19T Q09fTVRVCTB4NDANCj4gPiAtI2RlZmluZSBCVFVTQl9BVEgzMDEyCQkweDgwDQo+ID4gKy8qDQo+ ID4gKyAqIENyZWF0ZSBidHVzYl9kcml2ZXJfaW5mbyBzdHJ1Y3QgZm9yIGVhY2ggZHJpdmVyX2lu Zm8gZmxhZ3MgdXNlZCANCj4gPiArYnkNCj4gPiArICogYmxhY2tsaXN0IHNpbmNlIHZlbmRvcidz IGJ0dXNiIGRyaXZlciB3aWxsIHJldHVybiBidHVzYl9kcml2ZXJfaW5mbyBzdHJ1Y3QuDQo+ID4g KyAqLw0KPiA+ICsNCj4gPiArLyoNCj4gPiArICogaWYgdGhlIGRldmljZSBpcyBzZXQgdG8gdGhp cywgdGhpcyBtZW5hcyB0aGF0IHRoZSBkZXZpY2UgaXMgDQo+ID4gK2dlbmVyaWMgYW5kDQo+ID4g KyAqIGRvZXNuJ3QgcmVxdWlyZSBhbnkgdmVuZG9yIHNwZWNpZmljIGhhbmRsaW5nICAqLyBzdGF0 aWMgY29uc3QgDQo+ID4gK3N0cnVjdCBidHVzYl9kcml2ZXJfaW5mbyBnZW5lcmljID0gew0KPiA+ ICsJLmRlc2NyaXB0aW9uCT0gIkJUVVNCIEdlbmVyaWMiLA0KPiA+ICsJLmZsYWdzCQk9IEJUVVNC X0dFTkVSSUMsDQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGJ0dXNi X2RyaXZlcl9pbmZvIGlnbm9yZSA9IHsNCj4gPiArCS5kZXNjcmlwdGlvbgk9ICJCVFVTQiBJZ25v cmUiLA0KPiA+ICsJLmZsYWdzCQk9IEJUVVNCX0lHTk9SRSwNCj4gPiArfTsNCj4gDQo+ID4+IEkg bGlrZSB0aGUgZWZmb3J0LCBidXQgSSB0aGluayB5b3Ugd2VudCBhIGxpdHRsZSBiaXQgdG9vIGZh ciBoZXJlLiBGb3IgdGhlc2Ugc2ltcGxlIG9uZXMsIHdlIGNhbiBlYXNpbHkga2VlcCBvdXIgc2lt cGxlIGJsYWNrbGlzdC4gSXQga2VlcHMgdGhlIGNvZGUgbW9yZSByZWFkYWJsZSB0aGFuIHRoaXMg cGFydC4gQnV0IEkgZG8gYXBwcmVjaWF0ZSB0aGUgYXR0ZW1wdCBpbiB1bmlmeWluZyB0aGlzLg0K PiANCj4gDQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGJ0dXNiX2RyaXZlcl9pbmZv IGRpZ2lhbnN3ZXIgPSB7DQo+ID4gKwkuZGVzY3JpcHRpb24JPSAiQlRVU0IgRElHSUFOU1dFUiIs DQo+ID4gKwkuZmxhZ3MJCT0gQlRVU0JfRElHSUFOU1dFUiwNCj4gPiArfTsNCj4gPiArDQo+ID4g K3N0YXRpYyBjb25zdCBzdHJ1Y3QgYnR1c2JfZHJpdmVyX2luZm8gY3NyID0gew0KPiA+ICsJLmRl c2NyaXB0aW9uCT0gIkJUVVNCIENTUiIsDQo+ID4gKwkuZmxhZ3MJCT0gQlRVU0JfQ1NSLA0KPiA+ ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCBidHVzYl9kcml2ZXJfaW5mbyBz bmlmZmVyID0gew0KPiA+ICsJLmRlc2NyaXB0aW9uCT0gIkJUVVNCIFNuaWZmZXIiLA0KPiA+ICsJ LmZsYWdzCQk9IEJUVVNCX1NOSUZGRVIsDQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29u c3Qgc3RydWN0IGJ0dXNiX2RyaXZlcl9pbmZvIGJjbTkyMDM1ID0gew0KPiA+ICsJLmRlc2NyaXB0 aW9uCT0gIkJUVVNCIEJDTTkyMDM1IiwNCj4gPiArCS5mbGFncwkJPSBCVFVTQl9CQ005MjAzNSwN Cj4gPiArfTsNCj4gPiArDQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgYnR1c2JfZHJpdmVyX2lu Zm8gYnJva2VuX2lzb2MgPSB7DQo+ID4gKwkuZGVzY3JpcHRpb24JPSAiQlRVU0IgQnJva2VuIElT T0MiLA0KPiA+ICsJLmZsYWdzCQk9IEJUVVNCX0JST0tFTl9JU09DLA0KPiA+ICt9Ow0KPiA+ICsN Cj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCBidHVzYl9kcml2ZXJfaW5mbyB3cm9uZ19zY29fbXR1 ID0gew0KPiA+ICsJLmRlc2NyaXB0aW9uCT0gIkJUVVNCIFdyb25nIFNDTyBNVFUiLA0KPiA+ICsJ LmZsYWdzCQk9IEJUVVNCX1dST05HX1NDT19NVFUsDQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdGF0 aWMgY29uc3Qgc3RydWN0IGJ0dXNiX2RyaXZlcl9pbmZvIGF0aDMwMTIgPSB7DQo+ID4gKwkuZGVz Y3JpcHRpb24JPSAiQlRVU0IgQXRoMzAxMiIsDQo+ID4gKwkuZmxhZ3MJCT0gQlRVU0JfQVRIMzAx MiwNCj4gPiArfTsNCj4gPiAgDQo+ID4gIHN0YXRpYyBzdHJ1Y3QgdXNiX2RldmljZV9pZCBidHVz Yl90YWJsZVtdID0gew0KPiA+ICAJLyogR2VuZXJpYyBCbHVldG9vdGggVVNCIGRldmljZSAqLyBA QCAtMTA1LDkwICsxNTEsODkgQEAgc3RhdGljIA0KPiA+IHN0cnVjdCB1c2JfZGV2aWNlX2lkIGJ0 dXNiX3RhYmxlW10gPSB7DQo+ID4gIA0KPiA+ICAJeyB9CS8qIFRlcm1pbmF0aW5nIGVudHJ5ICov DQo+ID4gIH07DQo+ID4gLQ0KPiA+ICBNT0RVTEVfREVWSUNFX1RBQkxFKHVzYiwgYnR1c2JfdGFi bGUpOw0KPiA+ICANCj4gPiAgc3RhdGljIHN0cnVjdCB1c2JfZGV2aWNlX2lkIGJsYWNrbGlzdF90 YWJsZVtdID0gew0KPiA+ICAJLyogQ1NSIEJsdWVDb3JlIGRldmljZXMgKi8NCj4gPiAtCXsgVVNC X0RFVklDRSgweDBhMTIsIDB4MDAwMSksIC5kcml2ZXJfaW5mbyA9IEJUVVNCX0NTUiB9LA0KPiA+ ICsJeyBVU0JfREVWSUNFKDB4MGExMiwgMHgwMDAxKSwgLmRyaXZlcl9pbmZvID0gKHVuc2lnbmVk IGxvbmcpICZjc3IgDQo+ID4gK30sDQo+IA0KPiA+PiBLZWVwIHRoZSBibGFja2xpc3RfdGFibGUg YXMgaXQgaXMuIFRoZSBpbXBvcnRhbnQgdGFibGUgdG8gbW9kaWZ5IGlzIGJ0dXNiX3RhYmxlIGFu ZCB1c2UgYSBjb21tb24gZHJpdmVyX2luZm8gdGhhdCB3aWxsIGJlIHNoYXJlZCBiZXR3ZWVuIGRy aXZlcnMuDQo+IA0KPiA+PiBUaGF0IHdvdWxkIGFsc28gbWFrZSBpdCBzaW1wbGUgdG8ganVzdCBh ZGQgQlRVU0JfSUdOT1JFIG9yIGEgbmV3IEJUVVNCX1ZFTkRPUiBmbGFnIHRvIGNhbGwgb3V0IHRo ZSBkcml2ZXJzIHRoYXQgaGF2ZSBhIHNlcGFyYXRlIGRyaXZlciB3aXRoIGEgdmVuZG9yIGluaXQg ZnVuY3Rpb24sIGJ1dCB3b3VsZCBtYXRjaCA+PiB0aGUgQmx1ZXRvb3RoIGdlbmVyYWwgVVNCIGRl c2NyaXB0b3JzLg0KPiANCj4gSSBsb29rZWQgYXQgdXNibmV0IG1pbmlkcml2ZXIgYXMgeW91IHN1 Z2dlc3RlZC4gIElmIHdlIGRvIGEgc2ltaWxhciBzY2hlbWUgc3VjaCB0aGF0IGJ0dXNiX3Byb2Jl KCkgaW52b2tlcyB0aGUgbWluaV9kcml2ZXIncyBiaW5kKCkvdW5iaW5kKCkgdGhlbiBidHVzYidz IHVzYWdlIG9mIGRyaXZlcl9pbmZvIHdpbGwgbmVlZCB0byBjaGFuZ2UgZnJvbSBzdG9yaW5nIGZs YWdzIChleDogQlRVU0JfSUdOT1JFKSBhbmQgY2hhbmdlIHRvIHN0b3JlICJzdGF0aWMgY29uc3Qg c3RydWN0IiB3aGVyZSBpdCBob2xkcyBhIHN0cnVjdCBjb250YWluaW5nIHRoZSBtaW5pLWRyaXZl cidzIGJpbmQvdW5iaW5kIGZ1bmN0aW9ucyAoanVzdCBsaWtlIHVzYm5ldCBtaW5pZHJpdmVyKS4g ICBBcmUgeW91IGdvb2Qgd2l0aCB0aGlzIGNoYW5nZT8gIEkgYWxzbyB3YW50IHRvIG1lbnRpb24g dGhhdCBpbiB0aGUgcGF0Y2ggY29udGFpbmluZyB0aGUgQlQgVVNCIG1pbmkgZHJpdmVyIHRlbXBs YXRlLCBpdCBhbHJlYWR5IGhhcyBpdHMgb3duIG1vZHVsZV91c2JfZHJpdmVyKCkgc2VjdGlvbiB3 aXRoIGl0cyBWSUQvUElEIGxpc3RlZC4NCg0KeW91IGtub3cgd2hhdC4gSnVzdCBzZW5kIGFyb3Vu ZCB3aGF0IHlvdSBoYXZlIHJpZ2h0IG5vdyBhZnRlciB0aGUgY2xlYW51cCBhbmQgdGhlbiBJIGNh biB0YWtlIGFub3RoZXIgbG9vayBhdCBpdC4NCg0KUmVnYXJkcw0KDQpNYXJjZWwNCg0KDQo=