Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51d6c043 authored by Liangliang Lu's avatar Liangliang Lu
Browse files

usb: gadget: f_diag: allocate diag USB channel when not found



Currently usb function instance driver depends on diag char driver to
create the channel (using usb_diag_open api). Failing to create channel
can result in enumeration failure. Avoid this dependency by creating
diag channel from function instance if not available. Same channel
will be reused when diag char driver creates/opens the channel.

Change-Id: Ie9f1b5d87257eb019552a3121abc77b7fb8ac544
Signed-off-by: default avatarLiangliang Lu <luliang@codeaurora.org>
parent bf10764e
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 * Diag Function Device - Route ARM9 and ARM11 DIAG messages
 * between HOST and DEVICE.
 * Copyright (C) 2007 Google, Inc.
 * Copyright (c) 2008-2016, The Linux Foundation. All rights reserved.
 * Copyright (c) 2008-2017, The Linux Foundation. All rights reserved.
 * Author: Brian Swetland <swetland@google.com>
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
@@ -322,9 +322,11 @@ struct usb_diag_ch *usb_diag_open(const char *name, void *priv,
	ch->priv = priv;
	ch->notify = notify;

	if (!found) {
		spin_lock_irqsave(&ch_lock, flags);
		list_add_tail(&ch->list, &usb_diag_ch_list);
		spin_unlock_irqrestore(&ch_lock, flags);
	}

	return ch;
}
@@ -791,6 +793,7 @@ int diag_function_add(struct usb_configuration *c, const char *name,
	struct diag_context *dev;
	struct usb_diag_ch *_ch;
	int found = 0, ret;
	unsigned long flags;

	DBG(c->cdev, "diag_function_add\n");

@@ -800,9 +803,19 @@ int diag_function_add(struct usb_configuration *c, const char *name,
			break;
		}
	}

	if (!found) {
		ERROR(c->cdev, "unable to get diag usb channel\n");
		return -ENODEV;
		DBG(c->cdev, "%s: unable to get diag usb channel\n", __func__);

		_ch = kzalloc(sizeof(*_ch), GFP_KERNEL);
		if (_ch == NULL)
			return -ENOMEM;

		_ch->name = name;

		spin_lock_irqsave(&ch_lock, flags);
		list_add_tail(&_ch->list, &usb_diag_ch_list);
		spin_unlock_irqrestore(&ch_lock, flags);
	}

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);