Loading drivers/char/diag/diag_usb.c +36 −7 Original line number Diff line number Diff line Loading @@ -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); } /* Loading @@ -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); } Loading Loading @@ -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; Loading Loading @@ -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. Loading @@ -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); Loading @@ -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: Loading drivers/char/diag/diag_usb.h +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 Loading Loading @@ -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; Loading @@ -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 Loading drivers/usb/gadget/function/f_diag.c +12 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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); Loading Loading
drivers/char/diag/diag_usb.c +36 −7 Original line number Diff line number Diff line Loading @@ -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); } /* Loading @@ -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); } Loading Loading @@ -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; Loading Loading @@ -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. Loading @@ -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); Loading @@ -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: Loading
drivers/char/diag/diag_usb.h +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 Loading Loading @@ -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; Loading @@ -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 Loading
drivers/usb/gadget/function/f_diag.c +12 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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); Loading