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

Commit 381b504a authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "diag: Wait until usb diag channel opens during cable connect"

parents ea21f53b 99e899ad
Loading
Loading
Loading
Loading
+36 −7
Original line number Diff line number Diff line
@@ -206,7 +206,19 @@ static void usb_connect_work_fn(struct work_struct *work)
{
	struct diag_usb_info *ch = container_of(work, struct diag_usb_info,
						connect_work);

	wait_event_interruptible(ch->wait_q, ch->enabled > 0);
	ch->max_size = usb_diag_request_size(ch->hdl);
	atomic_set(&ch->connected, 1);

	DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
	"diag: USB channel %s: disconnected_status: %d, connected_status: %d\n",
	ch->name, atomic_read(&ch->disconnected), atomic_read(&ch->connected));

	usb_connect(ch);

	if (atomic_read(&ch->disconnected))
		wake_up_interruptible(&ch->wait_q);
}

/*
@@ -231,6 +243,19 @@ static void usb_disconnect_work_fn(struct work_struct *work)
{
	struct diag_usb_info *ch = container_of(work, struct diag_usb_info,
						disconnect_work);

	atomic_set(&ch->disconnected, 1);
	DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
	"diag: USB channel %s: disconnected_status: %d, connected_status: %d\n",
	ch->name, atomic_read(&ch->disconnected), atomic_read(&ch->connected));

	wait_event_interruptible(ch->wait_q, atomic_read(&ch->connected) > 0);
	atomic_set(&ch->connected, 0);
	atomic_set(&ch->disconnected, 0);
	DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
	"diag: USB channel %s: Cleared disconnected(%d) and connected(%d) status\n",
	ch->name, atomic_read(&ch->disconnected), atomic_read(&ch->connected));

	usb_disconnect(ch);
}

@@ -357,15 +382,15 @@ static void diag_usb_notifier(void *priv, unsigned int event,

	switch (event) {
	case USB_DIAG_CONNECT:
		usb_info->max_size = usb_diag_request_size(usb_info->hdl);
		atomic_set(&usb_info->connected, 1);
		pr_info("diag: USB channel %s connected\n", usb_info->name);
		pr_info("diag: USB channel %s: Received Connect event\n",
			usb_info->name);
		if (!atomic_read(&usb_info->connected))
			queue_work(usb_info->usb_wq,
			   &usb_info->connect_work);
		break;
	case USB_DIAG_DISCONNECT:
		atomic_set(&usb_info->connected, 0);
		pr_info("diag: USB channel %s disconnected\n", usb_info->name);
		pr_info("diag: USB channel %s: Received Disconnect event\n",
			usb_info->name);
		queue_work(usb_info->usb_wq,
			   &usb_info->disconnect_work);
		break;
@@ -618,6 +643,7 @@ int diag_usb_register(int id, int ctxt, struct diag_mux_ops *ops)
	if (!ch->read_ptr)
		goto err;
	atomic_set(&ch->connected, 0);
	atomic_set(&ch->disconnected, 0);
	atomic_set(&ch->read_pending, 0);
	/*
	 * This function is called when the mux registers with Diag-USB.
@@ -631,6 +657,7 @@ int diag_usb_register(int id, int ctxt, struct diag_mux_ops *ops)
	INIT_WORK(&(ch->read_done_work), usb_read_done_work_fn);
	INIT_WORK(&(ch->connect_work), usb_connect_work_fn);
	INIT_WORK(&(ch->disconnect_work), usb_disconnect_work_fn);
	init_waitqueue_head(&ch->wait_q);
	strlcpy(wq_name, "DIAG_USB_", DIAG_USB_STRING_SZ);
	strlcat(wq_name, ch->name, sizeof(ch->name));
	ch->usb_wq = create_singlethread_workqueue(wq_name);
@@ -643,7 +670,9 @@ int diag_usb_register(int id, int ctxt, struct diag_mux_ops *ops)
		goto err;
	}
	ch->enabled = 1;
	pr_debug("diag: Successfully registered USB %s\n", ch->name);
	wake_up_interruptible(&ch->wait_q);
	DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
		"diag: Successfully registered USB %s\n", ch->name);
	return 0;

err:
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -53,6 +53,7 @@ struct diag_usb_info {
	atomic_t connected;
	atomic_t diag_state;
	atomic_t read_pending;
	atomic_t disconnected;
	int enabled;
	int mempool;
	int max_size;
@@ -70,6 +71,7 @@ struct diag_usb_info {
	struct work_struct connect_work;
	struct work_struct disconnect_work;
	struct workqueue_struct *usb_wq;
	wait_queue_head_t wait_q;
};

#ifdef CONFIG_DIAG_OVER_USB
+12 −0
Original line number Diff line number Diff line
@@ -331,6 +331,8 @@ struct usb_diag_ch *usb_diag_open(const char *name, void *priv,
	struct usb_diag_ch *ch;
	unsigned long flags;
	int found = 0;
	bool connected = false;
	struct diag_context  *dev;

	spin_lock_irqsave(&ch_lock, flags);
	/* Check if we already have a channel with this name */
@@ -358,6 +360,16 @@ struct usb_diag_ch *usb_diag_open(const char *name, void *priv,
		spin_unlock_irqrestore(&ch_lock, flags);
	}

	if (ch->priv_usb) {
		dev = ch->priv_usb;
		spin_lock_irqsave(&dev->lock, flags);
		connected = dev->configured;
		spin_unlock_irqrestore(&dev->lock, flags);
	}

	if (ch->notify && connected)
		ch->notify(priv, USB_DIAG_CONNECT, NULL);

	return ch;
}
EXPORT_SYMBOL(usb_diag_open);