Loading drivers/char/diag/Kconfig +11 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,17 @@ config DIAGFWD_BRIDGE_CODE become available, this bridge driver enables DIAG traffic over MHI and SMUX. config DIAG_OVER_PCIE bool "Enable Diag traffic to go over PCIE" depends on DIAG_CHAR depends on MSM_MHI help Diag over PCIE enables sending diag traffic over PCIE endpoint when pcie is available. Diag PCIE channels should be configured and connected to use the transport. If PCIE is not configured diag will switch to usb mode and diag traffic will be routed over USB. config DIAG_USES_SMD bool "Enable diag internal interface over SMD" depends on DIAG_CHAR && MSM_SMD Loading drivers/char/diag/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -3,5 +3,6 @@ obj-$(CONFIG_DIAGFWD_BRIDGE_CODE) += diagfwd_bridge.o obj-$(CONFIG_USB_QCOM_DIAG_BRIDGE) += diagfwd_hsic.o obj-$(CONFIG_USB_QCOM_DIAG_BRIDGE) += diagfwd_smux.o obj-$(CONFIG_MSM_MHI) += diagfwd_mhi.o obj-$(CONFIG_DIAG_OVER_PCIE) += diag_pcie.o obj-$(CONFIG_DIAG_USES_SMD) += diagfwd_smd.o diagchar-objs := diagchar_core.o diagchar_hdlc.o diagfwd.o diagfwd_glink.o diagfwd_peripheral.o diagfwd_socket.o diag_mux.o diag_memorydevice.o diag_usb.o diagmem.o diagfwd_cntl.o diag_dci.o diag_masks.o diag_debugfs.o drivers/char/diag/diag_debugfs.c +79 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ #include "diagfwd_smd.h" #include "diagfwd_socket.h" #include "diagfwd_glink.h" #include "diag_pcie.h" #include "diag_debugfs.h" #include "diag_ipc_logging.h" Loading @@ -43,6 +44,9 @@ static struct dentry *diag_dbgfs_dent; static int diag_dbgfs_table_index; static int diag_dbgfs_mempool_index; static int diag_dbgfs_usbinfo_index; #ifdef CONFIG_DIAG_OVER_PCIE static int diag_dbgfs_pcieinfo_index; #endif static int diag_dbgfs_smdinfo_index; static int diag_dbgfs_socketinfo_index; static int diag_dbgfs_glinkinfo_index; Loading Loading @@ -481,6 +485,68 @@ static ssize_t diag_dbgfs_read_usbinfo(struct file *file, char __user *ubuf, return ret; } #ifdef CONFIG_DIAG_OVER_PCIE static ssize_t diag_dbgfs_read_pcieinfo(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { char *buf = NULL; int ret = 0; int i = 0; unsigned int buf_size; unsigned int bytes_remaining = 0; unsigned int bytes_written = 0; unsigned int bytes_in_buffer = 0; struct diag_pcie_info *pcie_info = NULL; unsigned int temp_size = sizeof(char) * DEBUG_BUF_SIZE; if (diag_dbgfs_pcieinfo_index >= NUM_DIAG_PCIE_DEV) { /* Done. Reset to prepare for future requests */ diag_dbgfs_pcieinfo_index = 0; return 0; } buf = kzalloc(temp_size, GFP_KERNEL); if (ZERO_OR_NULL_PTR(buf)) return -ENOMEM; buf_size = ksize(buf); bytes_remaining = buf_size; for (i = diag_dbgfs_pcieinfo_index; i < NUM_DIAG_PCIE_DEV; i++) { pcie_info = &diag_pcie[i]; bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining, "id: %d\n" "name: %s\n" "in channel hdl: %pK\n" "out channel hdl: %pK\n" "mempool: %s\n" "read count: %lu\n" "write count: %lu\n" "read work pending: %d\n", pcie_info->id, pcie_info->name, pcie_info->in_handle, pcie_info->out_handle, DIAG_MEMPOOL_GET_NAME(pcie_info->mempool), pcie_info->read_cnt, pcie_info->write_cnt, work_pending(&pcie_info->read_work)); bytes_in_buffer += bytes_written; /* Check if there is room to add another table entry */ bytes_remaining = buf_size - bytes_in_buffer; if (bytes_remaining < bytes_written) break; } diag_dbgfs_pcieinfo_index = i+1; *ppos = 0; ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer); kfree(buf); return ret; } #endif #ifdef CONFIG_DIAG_USES_SMD static ssize_t diag_dbgfs_read_smdinfo(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) Loading Loading @@ -1080,6 +1146,12 @@ const struct file_operations diag_dbgfs_usbinfo_ops = { .read = diag_dbgfs_read_usbinfo, }; #ifdef CONFIG_DIAG_OVER_PCIE const struct file_operations diag_dbgfs_pcieinfo_ops = { .read = diag_dbgfs_read_pcieinfo, }; #endif const struct file_operations diag_dbgfs_dcistats_ops = { .read = diag_dbgfs_read_dcistats, }; Loading Loading @@ -1139,6 +1211,13 @@ int diag_debugfs_init(void) if (!entry) goto err; #ifdef CONFIG_DIAG_OVER_PCIE entry = debugfs_create_file("pcieinfo", 0444, diag_dbgfs_dent, 0, &diag_dbgfs_pcieinfo_ops); if (!entry) goto err; #endif entry = debugfs_create_file("dci_stats", 0444, diag_dbgfs_dent, 0, &diag_dbgfs_dcistats_ops); if (!entry) Loading drivers/char/diag/diag_mux.c +114 −10 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 @@ -27,12 +27,20 @@ #include "diag_mux.h" #include "diag_usb.h" #include "diag_memorydevice.h" #include "diag_pcie.h" #include "diagfwd_peripheral.h" #include "diag_ipc_logging.h" #ifdef CONFIG_DIAG_OVER_PCIE #define diag_mux_register_ops diag_pcie_register_ops #else #define diag_mux_register_ops diag_usb_register_ops #endif struct diag_mux_state_t *diag_mux; static struct diag_logger_t usb_logger; static struct diag_logger_t md_logger; static struct diag_logger_t pcie_logger; static struct diag_logger_ops usb_log_ops = { .open = diag_usb_connect_all, Loading @@ -50,6 +58,16 @@ static struct diag_logger_ops md_log_ops = { .close_peripheral = diag_md_close_peripheral, }; #ifdef CONFIG_DIAG_OVER_PCIE static struct diag_logger_ops pcie_log_ops = { .open = diag_pcie_connect_all, .close = diag_pcie_disconnect_all, .queue_read = NULL, .write = diag_pcie_write, .close_peripheral = NULL }; #endif int diag_mux_init(void) { diag_mux = kzalloc(sizeof(struct diag_mux_state_t), Loading @@ -64,16 +82,29 @@ int diag_mux_init(void) md_logger.mode = DIAG_MEMORY_DEVICE_MODE; md_logger.log_ops = &md_log_ops; diag_md_init(); #ifdef CONFIG_DIAG_OVER_PCIE pcie_logger.mode = DIAG_PCIE_MODE; pcie_logger.log_ops = &pcie_log_ops; diag_mux->pcie_ptr = &pcie_logger; #endif /* * Set USB logging as the default logger. This is the mode * Diag should be in when it initializes. */ diag_mux->usb_ptr = &usb_logger; diag_mux->md_ptr = &md_logger; switch (driver->transport_set) { case DIAG_ROUTE_TO_PCIE: diag_mux->logger = &pcie_logger; diag_mux->mode = DIAG_PCIE_MODE; break; case DIAG_ROUTE_TO_USB: default: diag_mux->logger = &usb_logger; diag_mux->mux_mask = 0; diag_mux->mode = DIAG_USB_MODE; break; } diag_mux->mux_mask = 0; return 0; } Loading @@ -82,7 +113,8 @@ void diag_mux_exit(void) kfree(diag_mux); } int diag_mux_register(int proc, int ctx, struct diag_mux_ops *ops) #ifdef CONFIG_DIAG_OVER_PCIE int diag_pcie_register_ops(int proc, int ctx, struct diag_mux_ops *ops) { int err = 0; Loading @@ -92,7 +124,12 @@ int diag_mux_register(int proc, int ctx, struct diag_mux_ops *ops) if (proc < 0 || proc >= NUM_MUX_PROC) return 0; /* Register with USB logger */ pcie_logger.ops[proc] = ops; err = diag_pcie_register(proc, ctx, ops); if (err) { driver->transport_set == DIAG_ROUTE_TO_USB; diag_mux->logger = &usb_logger; diag_mux->mode = DIAG_USB_MODE; usb_logger.ops[proc] = ops; err = diag_usb_register(proc, ctx, ops); if (err) { Loading @@ -100,7 +137,44 @@ int diag_mux_register(int proc, int ctx, struct diag_mux_ops *ops) proc, err); return err; } pr_err("diag: MUX: unable to register pcie operations for proc: %d, err: %d\n", proc, err); } return 0; } #else int diag_usb_register_ops(int proc, int ctx, struct diag_mux_ops *ops) { int err = 0; if (!ops) return -EINVAL; if (proc < 0 || proc >= NUM_MUX_PROC) return 0; usb_logger.ops[proc] = ops; err = diag_usb_register(proc, ctx, ops); if (err) { pr_err("diag: MUX: unable to register usb operations for proc: %d, err: %d\n", proc, err); return err; } return 0; } #endif int diag_mux_register(int proc, int ctx, struct diag_mux_ops *ops) { int err = 0; if (!ops) return -EINVAL; if (proc < 0 || proc >= NUM_MUX_PROC) return 0; err = diag_mux_register_ops(proc, ctx, ops); if (err) return err; md_logger.ops[proc] = ops; err = diag_md_register(proc, ctx, ops); if (err) { Loading Loading @@ -150,10 +224,19 @@ int diag_mux_write(int proc, unsigned char *buf, int len, int ctx) return -EINVAL; } if (MD_PERIPHERAL_MASK(peripheral) & diag_mux->mux_mask) if (MD_PERIPHERAL_MASK(peripheral) & diag_mux->mux_mask) { logger = diag_mux->md_ptr; else } else { switch (driver->transport_set) { case DIAG_ROUTE_TO_PCIE: logger = diag_mux->pcie_ptr; break; case DIAG_ROUTE_TO_USB: default: logger = diag_mux->usb_ptr; break; } } if (logger && logger->log_ops && logger->log_ops->write) return logger->log_ops->write(proc, buf, len, ctx); Loading Loading @@ -201,6 +284,7 @@ int diag_mux_switch_logging(int *req_mode, int *peripheral_mask) } switch (*req_mode) { case DIAG_PCIE_MODE: case DIAG_USB_MODE: new_mask = ~(*peripheral_mask) & diag_mux->mux_mask; if (new_mask != DIAG_CON_NONE) Loading @@ -219,6 +303,16 @@ int diag_mux_switch_logging(int *req_mode, int *peripheral_mask) } switch (diag_mux->mode) { case DIAG_PCIE_MODE: if (*req_mode == DIAG_MEMORY_DEVICE_MODE) { diag_mux->pcie_ptr->log_ops->close(); diag_mux->logger = diag_mux->md_ptr; diag_mux->md_ptr->log_ops->open(); } else if (*req_mode == DIAG_MULTI_MODE) { diag_mux->md_ptr->log_ops->open(); diag_mux->logger = NULL; } break; case DIAG_USB_MODE: if (*req_mode == DIAG_MEMORY_DEVICE_MODE) { diag_mux->usb_ptr->log_ops->close(); Loading @@ -234,7 +328,14 @@ int diag_mux_switch_logging(int *req_mode, int *peripheral_mask) diag_mux->md_ptr->log_ops->close(); diag_mux->logger = diag_mux->usb_ptr; diag_mux->usb_ptr->log_ops->open(); } else if (*req_mode == DIAG_PCIE_MODE) { diag_mux->md_ptr->log_ops->close(); diag_mux->logger = diag_mux->pcie_ptr; diag_mux->pcie_ptr->log_ops->open(); } else if (*req_mode == DIAG_MULTI_MODE) { if (driver->transport_set == DIAG_ROUTE_TO_PCIE) diag_mux->pcie_ptr->log_ops->open(); else diag_mux->usb_ptr->log_ops->open(); diag_mux->logger = NULL; } Loading @@ -243,6 +344,9 @@ int diag_mux_switch_logging(int *req_mode, int *peripheral_mask) if (*req_mode == DIAG_USB_MODE) { diag_mux->md_ptr->log_ops->close(); diag_mux->logger = diag_mux->usb_ptr; } else if (*req_mode == DIAG_PCIE_MODE) { diag_mux->md_ptr->log_ops->close(); diag_mux->logger = diag_mux->pcie_ptr; } else if (*req_mode == DIAG_MEMORY_DEVICE_MODE) { diag_mux->usb_ptr->log_ops->close(); diag_mux->logger = diag_mux->md_ptr; Loading drivers/char/diag/diag_mux.h +6 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2016, 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 @@ -17,6 +17,7 @@ struct diag_mux_state_t { struct diag_logger_t *logger; struct diag_logger_t *usb_ptr; struct diag_logger_t *md_ptr; struct diag_logger_t *pcie_ptr; unsigned int mux_mask; unsigned int mode; }; Loading @@ -33,6 +34,7 @@ struct diag_mux_ops { #define DIAG_MEMORY_DEVICE_MODE 1 #define DIAG_NO_LOGGING_MODE 2 #define DIAG_MULTI_MODE 3 #define DIAG_PCIE_MODE 4 #define DIAG_MUX_LOCAL 0 #define DIAG_MUX_LOCAL_LAST 1 Loading Loading @@ -73,4 +75,7 @@ int diag_mux_close_peripheral(int proc, uint8_t peripheral); int diag_mux_open_all(struct diag_logger_t *logger); int diag_mux_close_all(void); int diag_mux_switch_logging(int *new_mode, int *peripheral_mask); int diag_pcie_register_ops(int proc, int ctx, struct diag_mux_ops *ops); int diag_usb_register_ops(int proc, int ctx, struct diag_mux_ops *ops); int diag_mux_register_ops(int proc, int ctx, struct diag_mux_ops *ops); #endif Loading
drivers/char/diag/Kconfig +11 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,17 @@ config DIAGFWD_BRIDGE_CODE become available, this bridge driver enables DIAG traffic over MHI and SMUX. config DIAG_OVER_PCIE bool "Enable Diag traffic to go over PCIE" depends on DIAG_CHAR depends on MSM_MHI help Diag over PCIE enables sending diag traffic over PCIE endpoint when pcie is available. Diag PCIE channels should be configured and connected to use the transport. If PCIE is not configured diag will switch to usb mode and diag traffic will be routed over USB. config DIAG_USES_SMD bool "Enable diag internal interface over SMD" depends on DIAG_CHAR && MSM_SMD Loading
drivers/char/diag/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -3,5 +3,6 @@ obj-$(CONFIG_DIAGFWD_BRIDGE_CODE) += diagfwd_bridge.o obj-$(CONFIG_USB_QCOM_DIAG_BRIDGE) += diagfwd_hsic.o obj-$(CONFIG_USB_QCOM_DIAG_BRIDGE) += diagfwd_smux.o obj-$(CONFIG_MSM_MHI) += diagfwd_mhi.o obj-$(CONFIG_DIAG_OVER_PCIE) += diag_pcie.o obj-$(CONFIG_DIAG_USES_SMD) += diagfwd_smd.o diagchar-objs := diagchar_core.o diagchar_hdlc.o diagfwd.o diagfwd_glink.o diagfwd_peripheral.o diagfwd_socket.o diag_mux.o diag_memorydevice.o diag_usb.o diagmem.o diagfwd_cntl.o diag_dci.o diag_masks.o diag_debugfs.o
drivers/char/diag/diag_debugfs.c +79 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ #include "diagfwd_smd.h" #include "diagfwd_socket.h" #include "diagfwd_glink.h" #include "diag_pcie.h" #include "diag_debugfs.h" #include "diag_ipc_logging.h" Loading @@ -43,6 +44,9 @@ static struct dentry *diag_dbgfs_dent; static int diag_dbgfs_table_index; static int diag_dbgfs_mempool_index; static int diag_dbgfs_usbinfo_index; #ifdef CONFIG_DIAG_OVER_PCIE static int diag_dbgfs_pcieinfo_index; #endif static int diag_dbgfs_smdinfo_index; static int diag_dbgfs_socketinfo_index; static int diag_dbgfs_glinkinfo_index; Loading Loading @@ -481,6 +485,68 @@ static ssize_t diag_dbgfs_read_usbinfo(struct file *file, char __user *ubuf, return ret; } #ifdef CONFIG_DIAG_OVER_PCIE static ssize_t diag_dbgfs_read_pcieinfo(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { char *buf = NULL; int ret = 0; int i = 0; unsigned int buf_size; unsigned int bytes_remaining = 0; unsigned int bytes_written = 0; unsigned int bytes_in_buffer = 0; struct diag_pcie_info *pcie_info = NULL; unsigned int temp_size = sizeof(char) * DEBUG_BUF_SIZE; if (diag_dbgfs_pcieinfo_index >= NUM_DIAG_PCIE_DEV) { /* Done. Reset to prepare for future requests */ diag_dbgfs_pcieinfo_index = 0; return 0; } buf = kzalloc(temp_size, GFP_KERNEL); if (ZERO_OR_NULL_PTR(buf)) return -ENOMEM; buf_size = ksize(buf); bytes_remaining = buf_size; for (i = diag_dbgfs_pcieinfo_index; i < NUM_DIAG_PCIE_DEV; i++) { pcie_info = &diag_pcie[i]; bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining, "id: %d\n" "name: %s\n" "in channel hdl: %pK\n" "out channel hdl: %pK\n" "mempool: %s\n" "read count: %lu\n" "write count: %lu\n" "read work pending: %d\n", pcie_info->id, pcie_info->name, pcie_info->in_handle, pcie_info->out_handle, DIAG_MEMPOOL_GET_NAME(pcie_info->mempool), pcie_info->read_cnt, pcie_info->write_cnt, work_pending(&pcie_info->read_work)); bytes_in_buffer += bytes_written; /* Check if there is room to add another table entry */ bytes_remaining = buf_size - bytes_in_buffer; if (bytes_remaining < bytes_written) break; } diag_dbgfs_pcieinfo_index = i+1; *ppos = 0; ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer); kfree(buf); return ret; } #endif #ifdef CONFIG_DIAG_USES_SMD static ssize_t diag_dbgfs_read_smdinfo(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) Loading Loading @@ -1080,6 +1146,12 @@ const struct file_operations diag_dbgfs_usbinfo_ops = { .read = diag_dbgfs_read_usbinfo, }; #ifdef CONFIG_DIAG_OVER_PCIE const struct file_operations diag_dbgfs_pcieinfo_ops = { .read = diag_dbgfs_read_pcieinfo, }; #endif const struct file_operations diag_dbgfs_dcistats_ops = { .read = diag_dbgfs_read_dcistats, }; Loading Loading @@ -1139,6 +1211,13 @@ int diag_debugfs_init(void) if (!entry) goto err; #ifdef CONFIG_DIAG_OVER_PCIE entry = debugfs_create_file("pcieinfo", 0444, diag_dbgfs_dent, 0, &diag_dbgfs_pcieinfo_ops); if (!entry) goto err; #endif entry = debugfs_create_file("dci_stats", 0444, diag_dbgfs_dent, 0, &diag_dbgfs_dcistats_ops); if (!entry) Loading
drivers/char/diag/diag_mux.c +114 −10 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 @@ -27,12 +27,20 @@ #include "diag_mux.h" #include "diag_usb.h" #include "diag_memorydevice.h" #include "diag_pcie.h" #include "diagfwd_peripheral.h" #include "diag_ipc_logging.h" #ifdef CONFIG_DIAG_OVER_PCIE #define diag_mux_register_ops diag_pcie_register_ops #else #define diag_mux_register_ops diag_usb_register_ops #endif struct diag_mux_state_t *diag_mux; static struct diag_logger_t usb_logger; static struct diag_logger_t md_logger; static struct diag_logger_t pcie_logger; static struct diag_logger_ops usb_log_ops = { .open = diag_usb_connect_all, Loading @@ -50,6 +58,16 @@ static struct diag_logger_ops md_log_ops = { .close_peripheral = diag_md_close_peripheral, }; #ifdef CONFIG_DIAG_OVER_PCIE static struct diag_logger_ops pcie_log_ops = { .open = diag_pcie_connect_all, .close = diag_pcie_disconnect_all, .queue_read = NULL, .write = diag_pcie_write, .close_peripheral = NULL }; #endif int diag_mux_init(void) { diag_mux = kzalloc(sizeof(struct diag_mux_state_t), Loading @@ -64,16 +82,29 @@ int diag_mux_init(void) md_logger.mode = DIAG_MEMORY_DEVICE_MODE; md_logger.log_ops = &md_log_ops; diag_md_init(); #ifdef CONFIG_DIAG_OVER_PCIE pcie_logger.mode = DIAG_PCIE_MODE; pcie_logger.log_ops = &pcie_log_ops; diag_mux->pcie_ptr = &pcie_logger; #endif /* * Set USB logging as the default logger. This is the mode * Diag should be in when it initializes. */ diag_mux->usb_ptr = &usb_logger; diag_mux->md_ptr = &md_logger; switch (driver->transport_set) { case DIAG_ROUTE_TO_PCIE: diag_mux->logger = &pcie_logger; diag_mux->mode = DIAG_PCIE_MODE; break; case DIAG_ROUTE_TO_USB: default: diag_mux->logger = &usb_logger; diag_mux->mux_mask = 0; diag_mux->mode = DIAG_USB_MODE; break; } diag_mux->mux_mask = 0; return 0; } Loading @@ -82,7 +113,8 @@ void diag_mux_exit(void) kfree(diag_mux); } int diag_mux_register(int proc, int ctx, struct diag_mux_ops *ops) #ifdef CONFIG_DIAG_OVER_PCIE int diag_pcie_register_ops(int proc, int ctx, struct diag_mux_ops *ops) { int err = 0; Loading @@ -92,7 +124,12 @@ int diag_mux_register(int proc, int ctx, struct diag_mux_ops *ops) if (proc < 0 || proc >= NUM_MUX_PROC) return 0; /* Register with USB logger */ pcie_logger.ops[proc] = ops; err = diag_pcie_register(proc, ctx, ops); if (err) { driver->transport_set == DIAG_ROUTE_TO_USB; diag_mux->logger = &usb_logger; diag_mux->mode = DIAG_USB_MODE; usb_logger.ops[proc] = ops; err = diag_usb_register(proc, ctx, ops); if (err) { Loading @@ -100,7 +137,44 @@ int diag_mux_register(int proc, int ctx, struct diag_mux_ops *ops) proc, err); return err; } pr_err("diag: MUX: unable to register pcie operations for proc: %d, err: %d\n", proc, err); } return 0; } #else int diag_usb_register_ops(int proc, int ctx, struct diag_mux_ops *ops) { int err = 0; if (!ops) return -EINVAL; if (proc < 0 || proc >= NUM_MUX_PROC) return 0; usb_logger.ops[proc] = ops; err = diag_usb_register(proc, ctx, ops); if (err) { pr_err("diag: MUX: unable to register usb operations for proc: %d, err: %d\n", proc, err); return err; } return 0; } #endif int diag_mux_register(int proc, int ctx, struct diag_mux_ops *ops) { int err = 0; if (!ops) return -EINVAL; if (proc < 0 || proc >= NUM_MUX_PROC) return 0; err = diag_mux_register_ops(proc, ctx, ops); if (err) return err; md_logger.ops[proc] = ops; err = diag_md_register(proc, ctx, ops); if (err) { Loading Loading @@ -150,10 +224,19 @@ int diag_mux_write(int proc, unsigned char *buf, int len, int ctx) return -EINVAL; } if (MD_PERIPHERAL_MASK(peripheral) & diag_mux->mux_mask) if (MD_PERIPHERAL_MASK(peripheral) & diag_mux->mux_mask) { logger = diag_mux->md_ptr; else } else { switch (driver->transport_set) { case DIAG_ROUTE_TO_PCIE: logger = diag_mux->pcie_ptr; break; case DIAG_ROUTE_TO_USB: default: logger = diag_mux->usb_ptr; break; } } if (logger && logger->log_ops && logger->log_ops->write) return logger->log_ops->write(proc, buf, len, ctx); Loading Loading @@ -201,6 +284,7 @@ int diag_mux_switch_logging(int *req_mode, int *peripheral_mask) } switch (*req_mode) { case DIAG_PCIE_MODE: case DIAG_USB_MODE: new_mask = ~(*peripheral_mask) & diag_mux->mux_mask; if (new_mask != DIAG_CON_NONE) Loading @@ -219,6 +303,16 @@ int diag_mux_switch_logging(int *req_mode, int *peripheral_mask) } switch (diag_mux->mode) { case DIAG_PCIE_MODE: if (*req_mode == DIAG_MEMORY_DEVICE_MODE) { diag_mux->pcie_ptr->log_ops->close(); diag_mux->logger = diag_mux->md_ptr; diag_mux->md_ptr->log_ops->open(); } else if (*req_mode == DIAG_MULTI_MODE) { diag_mux->md_ptr->log_ops->open(); diag_mux->logger = NULL; } break; case DIAG_USB_MODE: if (*req_mode == DIAG_MEMORY_DEVICE_MODE) { diag_mux->usb_ptr->log_ops->close(); Loading @@ -234,7 +328,14 @@ int diag_mux_switch_logging(int *req_mode, int *peripheral_mask) diag_mux->md_ptr->log_ops->close(); diag_mux->logger = diag_mux->usb_ptr; diag_mux->usb_ptr->log_ops->open(); } else if (*req_mode == DIAG_PCIE_MODE) { diag_mux->md_ptr->log_ops->close(); diag_mux->logger = diag_mux->pcie_ptr; diag_mux->pcie_ptr->log_ops->open(); } else if (*req_mode == DIAG_MULTI_MODE) { if (driver->transport_set == DIAG_ROUTE_TO_PCIE) diag_mux->pcie_ptr->log_ops->open(); else diag_mux->usb_ptr->log_ops->open(); diag_mux->logger = NULL; } Loading @@ -243,6 +344,9 @@ int diag_mux_switch_logging(int *req_mode, int *peripheral_mask) if (*req_mode == DIAG_USB_MODE) { diag_mux->md_ptr->log_ops->close(); diag_mux->logger = diag_mux->usb_ptr; } else if (*req_mode == DIAG_PCIE_MODE) { diag_mux->md_ptr->log_ops->close(); diag_mux->logger = diag_mux->pcie_ptr; } else if (*req_mode == DIAG_MEMORY_DEVICE_MODE) { diag_mux->usb_ptr->log_ops->close(); diag_mux->logger = diag_mux->md_ptr; Loading
drivers/char/diag/diag_mux.h +6 −1 Original line number Diff line number Diff line /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2016, 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 @@ -17,6 +17,7 @@ struct diag_mux_state_t { struct diag_logger_t *logger; struct diag_logger_t *usb_ptr; struct diag_logger_t *md_ptr; struct diag_logger_t *pcie_ptr; unsigned int mux_mask; unsigned int mode; }; Loading @@ -33,6 +34,7 @@ struct diag_mux_ops { #define DIAG_MEMORY_DEVICE_MODE 1 #define DIAG_NO_LOGGING_MODE 2 #define DIAG_MULTI_MODE 3 #define DIAG_PCIE_MODE 4 #define DIAG_MUX_LOCAL 0 #define DIAG_MUX_LOCAL_LAST 1 Loading Loading @@ -73,4 +75,7 @@ int diag_mux_close_peripheral(int proc, uint8_t peripheral); int diag_mux_open_all(struct diag_logger_t *logger); int diag_mux_close_all(void); int diag_mux_switch_logging(int *new_mode, int *peripheral_mask); int diag_pcie_register_ops(int proc, int ctx, struct diag_mux_ops *ops); int diag_usb_register_ops(int proc, int ctx, struct diag_mux_ops *ops); int diag_mux_register_ops(int proc, int ctx, struct diag_mux_ops *ops); #endif