usb: gadget: f_qdss: Add ipc logging for qdss driver

This change adds ipc logging support for qdss function
driver.

Change-Id: I53be137a161bd7a4b0c4be250938e8fa46b2254e
Signed-off-by: Pratham Pratap <prathampratap@codeaurora.org>
Signed-off-by: Mayank Rana <mrana@codeaurora.org>
This commit is contained in:
Pratham Pratap 2020-05-04 11:18:33 -07:00 • committed by Mayank Rana
commit 4860f89018
2 changed files with 58 additions and 31 deletions

View file

@ -227,8 +227,6 @@ static void qdss_write_complete(struct usb_ep *ep,
enum qdss_state state;
unsigned long flags;
pr_debug("%s\n", __func__);
if (qdss->debug_inface_enabled) {
in = qdss->port.ctrl_in;
list_pool = &qdss->ctrl_write_pool;
@ -239,6 +237,8 @@ static void qdss_write_complete(struct usb_ep *ep,
state = USB_QDSS_DATA_WRITE_DONE;
}
qdss_log("channel:%s ep:%s req:%pK req->status:%d req->length:%d\n",
qdss->ch.name, ep->name, req, req->status, req->length);
spin_lock_irqsave(&qdss->lock, flags);
if (!qdss->debug_inface_enabled)
list_del(&qreq->list);
@ -259,8 +259,7 @@ void usb_qdss_free_req(struct usb_qdss_ch *ch)
struct f_qdss *qdss;
struct list_head *act, *tmp;
struct qdss_req *qreq;
pr_debug("%s\n", __func__);
int data_write_req = 0, ctrl_write_req = 0;
qdss = ch->priv_usb;
if (!qdss) {
@ -273,7 +272,7 @@ void usb_qdss_free_req(struct usb_qdss_ch *ch)
list_del(&qreq->list);
usb_ep_free_request(qdss->port.data, qreq->usb_req);
kfree(qreq);
data_write_req++;
}
list_for_each_safe(act, tmp, &qdss->ctrl_write_pool) {
@ -281,8 +280,11 @@ void usb_qdss_free_req(struct usb_qdss_ch *ch)
list_del(&qreq->list);
usb_ep_free_request(qdss->port.ctrl_in, qreq->usb_req);
kfree(qreq);
ctrl_write_req++;
}
qdss_log("channel:%s data_write_req:%d ctrl_write_req:%d freed\n",
qdss->ch.name, data_write_req, ctrl_write_req);
}
EXPORT_SYMBOL(usb_qdss_free_req);
@ -295,7 +297,7 @@ int usb_qdss_alloc_req(struct usb_qdss_ch *ch, int no_write_buf)
int i;
struct qdss_req *qreq;
pr_debug("%s\n", __func__);
qdss_log("channel:%s num_write_buf:%d\n", ch->name, no_write_buf);
if (!qdss) {
pr_err("%s: %s closed\n", __func__, ch->name);
@ -342,7 +344,7 @@ static void clear_eps(struct usb_function *f)
{
struct f_qdss *qdss = func_to_qdss(f);
pr_debug("%s\n", __func__);
qdss_log("channel:%s\n", qdss->ch.name);
if (qdss->port.ctrl_in)
qdss->port.ctrl_in->driver_data = NULL;
@ -356,7 +358,9 @@ static void clear_eps(struct usb_function *f)
static void clear_desc(struct usb_gadget *gadget, struct usb_function *f)
{
pr_debug("%s\n", __func__);
struct f_qdss *qdss = func_to_qdss(f);
qdss_log("channel:%s\n", qdss->ch.name);
usb_free_all_descriptors(f);
}
@ -368,7 +372,7 @@ static int qdss_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_ep *ep;
int iface, id, ret;
pr_debug("%s\n", __func__);
qdss_log("channel:%s\n", qdss->ch.name);
/* Allocate data I/F */
iface = usb_interface_id(c, f);
@ -505,7 +509,7 @@ static void qdss_unbind(struct usb_configuration *c, struct usb_function *f)
struct f_qdss *qdss = func_to_qdss(f);
struct usb_gadget *gadget = c->cdev->gadget;
pr_debug("%s\n", __func__);
qdss_log("channel:%s\n", qdss->ch.name);
flush_workqueue(qdss->wq);
@ -529,7 +533,7 @@ static void qdss_eps_disable(struct usb_function *f)
{
struct f_qdss *qdss = func_to_qdss(f);
pr_debug("%s\n", __func__);
qdss_log("channel:%s\n", qdss->ch.name);
if (qdss->ctrl_in_enabled) {
usb_ep_disable(qdss->port.ctrl_in);
@ -553,8 +557,7 @@ static void usb_qdss_disconnect_work(struct work_struct *work)
int status;
qdss = container_of(work, struct f_qdss, disconnect_w);
pr_debug("%s\n", __func__);
qdss_log("channel:%s\n", qdss->ch.name);
/* Notify qdss to cancel all active transfers */
if (qdss->ch.notify)
@ -586,7 +589,7 @@ static void qdss_disable(struct usb_function *f)
struct f_qdss *qdss = func_to_qdss(f);
unsigned long flags;
pr_debug("%s\n", __func__);
qdss_log("channel:%s\n", qdss->ch.name);
spin_lock_irqsave(&qdss->lock, flags);
if (!qdss->usb_connected) {
spin_unlock_irqrestore(&qdss->lock, flags);
@ -611,12 +614,11 @@ static void usb_qdss_connect_work(struct work_struct *work)
/* If cable is already removed, discard connect_work */
if (qdss->usb_connected == 0) {
pr_debug("%s: discard connect_work\n", __func__);
cancel_work_sync(&qdss->disconnect_w);
return;
}
pr_debug("%s\n", __func__);
qdss_log("channel:%s\n", qdss->ch.name);
if (!strcmp(qdss->ch.name, USB_QDSS_CH_MDM))
goto notify;
@ -653,7 +655,7 @@ static int qdss_set_alt(struct usb_function *f, unsigned int intf,
struct usb_qdss_ch *ch = &qdss->ch;
int ret = 0;
pr_debug("%s qdss pointer = %pK\n", __func__, qdss);
qdss_log("qdss pointer = %pK\n", qdss);
qdss->gadget = gadget;
if (alt != 0)
@ -716,12 +718,12 @@ static int qdss_set_alt(struct usb_function *f, unsigned int intf,
if (qdss->ctrl_out_enabled && qdss->ctrl_in_enabled &&
qdss->data_enabled) {
qdss->usb_connected = 1;
pr_debug("%s usb_connected INTF enabled\n", __func__);
qdss_log("usb_connected INTF enabled\n");
}
} else {
if (qdss->data_enabled) {
qdss->usb_connected = 1;
pr_debug("%s usb_connected INTF disabled\n", __func__);
qdss_log("usb_connected INTF disabled\n");
}
}
@ -796,11 +798,10 @@ int usb_qdss_ctrl_write(struct usb_qdss_ch *ch, struct qdss_request *d_req)
struct usb_request *req = NULL;
struct qdss_req *qreq;
pr_debug("%s\n", __func__);
if (!qdss)
return -ENODEV;
qdss_log("channel:%s d_req:%pK\n", ch->name, d_req);
spin_lock_irqsave(&qdss->lock, flags);
if (qdss->usb_connected == 0) {
@ -842,15 +843,16 @@ int usb_qdss_write(struct usb_qdss_ch *ch, struct qdss_request *d_req)
struct usb_request *req = NULL;
struct qdss_req *qreq;
pr_debug("usb_qdss_data_write\n");
if (!qdss)
return -ENODEV;
qdss_log("channel:%s d_req:%pK\n", ch->name, d_req);
spin_lock_irqsave(&qdss->lock, flags);
if (qdss->qdss_close || qdss->usb_connected == 0) {
spin_unlock_irqrestore(&qdss->lock, flags);
qdss_log("return -EIO\n");
return -EIO;
}
@ -873,6 +875,12 @@ int usb_qdss_write(struct usb_qdss_ch *ch, struct qdss_request *d_req)
req->num_sgs = d_req->num_sgs;
req->num_mapped_sgs = d_req->num_mapped_sgs;
reinit_completion(&qreq->write_done);
if (req->sg)
qdss_log("%s: req:%pK req->num_sgs:0x%x\n",
ch->name, req, req->num_sgs);
else
qdss_log("%s: req:%pK rq->length:0x%x\n",
ch->name, req, req->length);
if (usb_ep_queue(qdss->port.data, req, GFP_ATOMIC)) {
spin_lock_irqsave(&qdss->lock, flags);
/* Remove from queued pool and add back to data pool */
@ -896,8 +904,7 @@ struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv,
unsigned long flags;
int found = 0;
pr_debug("%s\n", __func__);
qdss_log("called for channel:%s\n", name);
if (!notify) {
pr_err("%s: notification func is missing\n", __func__);
return NULL;
@ -914,11 +921,11 @@ struct usb_qdss_ch *usb_qdss_open(const char *name, void *priv,
if (!found) {
spin_unlock_irqrestore(&qdss_lock, flags);
pr_debug("%s failed as %s not found\n", __func__, name);
qdss_log("failed to find channel:%s\n", name);
return NULL;
}
pr_debug("%s: qdss ctx found\n", __func__);
qdss_log("qdss ctx found for channel:%s\n", name);
qdss = container_of(ch, struct f_qdss, ch);
ch->priv_usb = qdss;
ch->priv = priv;
@ -943,8 +950,6 @@ void usb_qdss_close(struct usb_qdss_ch *ch)
int status;
struct qdss_req *qreq;
pr_debug("%s\n", __func__);
spin_lock_irqsave(&qdss_lock, flags);
if (!ch->priv_usb) {
spin_unlock_irqrestore(&qdss_lock, flags);
@ -953,12 +958,14 @@ void usb_qdss_close(struct usb_qdss_ch *ch)
return;
}
qdss_log("channel:%s\n", ch->name);
qdss = ch->priv_usb;
qdss->qdss_close = true;
while (!list_empty(&qdss->queued_data_pool)) {
qreq = list_first_entry(&qdss->queued_data_pool,
struct qdss_req, list);
spin_unlock_irqrestore(&qdss_lock, flags);
qdss_log("dequeue req:%pK\n", qreq->usb_req);
usb_ep_dequeue(qdss->port.data, qreq->usb_req);
wait_for_completion(&qreq->write_done);
spin_lock_irqsave(&qdss_lock, flags);
@ -999,7 +1006,7 @@ static void qdss_cleanup(void)
struct usb_qdss_ch *_ch;
unsigned long flags;
pr_debug("%s\n", __func__);
qdss_log("cleaning up channel resources.\n");
list_for_each_safe(act, tmp, &usb_qdss_ch_list) {
_ch = list_entry(act, struct usb_qdss_ch, list);
@ -1111,7 +1118,7 @@ static int usb_qdss_set_inst_name(struct usb_function_instance *f,
}
opts->channel_name = ptr;
pr_debug("qdss: channel_name:%s\n", opts->channel_name);
qdss_log("qdss: channel_name:%s\n", opts->channel_name);
usb_qdss = alloc_usb_qdss(opts->channel_name);
if (IS_ERR(usb_qdss)) {
@ -1164,6 +1171,10 @@ static int __init usb_qdss_init(void)
{
int ret;
_qdss_ipc_log = ipc_log_context_create(NUM_PAGES, "usb_qdss", 0);
if (IS_ERR_OR_NULL(_qdss_ipc_log))
_qdss_ipc_log = NULL;
INIT_LIST_HEAD(&usb_qdss_ch_list);
ret = usb_function_register(&qdssusb_func);
if (ret) {
@ -1175,6 +1186,7 @@ static int __init usb_qdss_init(void)
static void __exit usb_qdss_exit(void)
{
ipc_log_context_destroy(_qdss_ipc_log);
usb_function_unregister(&qdssusb_func);
qdss_cleanup();
}

View file

@ -7,6 +7,7 @@
#define _F_QDSS_H
#include <linux/kernel.h>
#include <linux/ipc_logging.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/composite.h>
@ -65,6 +66,20 @@ struct f_qdss {
bool qdss_close;
};
static void *_qdss_ipc_log;
#define NUM_PAGES 10 /* # of pages for ipc logging */
#ifdef CONFIG_DYNAMIC_DEBUG
#define qdss_log(fmt, ...) do { \
ipc_log_string(_qdss_ipc_log, "%s: " fmt, __func__, ##__VA_ARGS__); \
dynamic_pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \
} while (0)
#else
#define qdss_log(fmt, ...) \
ipc_log_string(_qdss_ipc_log, "%s: " fmt, __func__, ##__VA_ARGS__)
#endif
struct usb_qdss_opts {
struct usb_function_instance func_inst;
struct f_qdss *usb_qdss;