usb: mdm_data: Add support for QDLOADER bridging

Add necessary support to flash images to connected MDM in EDL
mode from host PC, via external AP. Also, add a module parameter
'prevent_edl_probe' to prevent 9008 PID (EDL PID) to bind to
ks_bridge driver.

Usage:
  To prevent binding to ks_bridge and bind to mdm_data_bridge:
    echo 1 > /sys/module/ks_bridge/parameters/prevent_edl_probe

  To switch back to default behavior (allow bind to ks_bridge):
    echo 0 > /sys/module/ks_bridge/parameters/prevent_edl_probe

While at it, fix potential null pointer dereference in
data_bridge_write.

Change-Id: I170c820803f016a03dcc5952424358e1a9835cfa
Signed-off-by: Ajay Agarwal <ajaya@codeaurora.org>
This commit is contained in:
Ajay Agarwal 2019-11-29 17:27:29 +05:30
parent 2ba5ea332f
commit 64fc8cb766
4 changed files with 15 additions and 1 deletions

View File

@ -1231,6 +1231,7 @@ mdm_data_set_alt(struct usb_function *f, unsigned int intf, unsigned int alt)
pr_debug("%s: mdm_data_port: %pK\n", __func__, port);
port->tx_q_size = mdm_data_tx_q_size;
port->rx_q_size = mdm_data_rx_q_size;
ret = config_ep_by_speed(cdev->gadget, f, port->in);
if (ret) {
port->in->desc = NULL;

View File

@ -88,6 +88,9 @@ static rwlock_t dbg_lock = __RW_LOCK_UNLOCKED(lck);
static unsigned int enable_dbg = 1;
module_param(enable_dbg, uint, 0644);
static bool prevent_edl_probe;
module_param(prevent_edl_probe, bool, 0644);
/*get_timestamp - returns time of day in us */
static unsigned int get_timestamp(void)
{
@ -633,6 +636,11 @@ ksb_usb_probe(struct usb_interface *ifc, const struct usb_device_id *id)
pr_debug("%s: id: %lu\n", __func__, id->driver_info);
if (prevent_edl_probe && (le16_to_cpu(id->idProduct) == 0x9008)) {
pr_err("%s: Preventing EDL device enumeration\n", __func__);
return -EINVAL;
}
udev = interface_to_usbdev(ifc);
if (udev->actconfig->desc.bNumInterfaces > 1) {
pr_err("%s: Invalid configuration: More than 1 interface\n",

View File

@ -513,7 +513,7 @@ int data_bridge_write(unsigned int id, struct sk_buff *skb)
struct urb *txurb;
struct timestamp_info *info = (struct timestamp_info *)skb->cb;
struct data_bridge *dev = __mdm_dev[id];
struct bridge *brdg;
struct bridge *brdg = dev->brdg;
if (!dev->brdg || dev->err) {
pr_err("%s: Bridge closed or device disconnected\n", __func__);
@ -968,6 +968,8 @@ static void bridge_disconnect(struct usb_interface *intf)
/*driver info stores data bridge name used to match bridge xport name*/
static const struct usb_device_id bridge_ids[] = {
{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9008, 0),
.driver_info = (kernel_ulong_t)("edl"), },
{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9102, 6),
.driver_info = (kernel_ulong_t)("qdss"), },
{ USB_DEVICE_INTERFACE_NUMBER(0x05c6, 0x9102, 7),

View File

@ -22,6 +22,7 @@
enum bridge_id {
USB_BRIDGE_QDSS,
USB_BRIDGE_DPL,
USB_BRIDGE_EDL,
MAX_BRIDGE_DEVICES,
};
@ -34,6 +35,8 @@ static int bridge_name_to_id(const char *name)
return USB_BRIDGE_QDSS;
if (!strncasecmp(name, "dpl", MAX_INST_NAME_LEN))
return USB_BRIDGE_DPL;
if (!strncasecmp(name, "edl", MAX_INST_NAME_LEN))
return USB_BRIDGE_EDL;
fail:
return -EINVAL;