Loading drivers/char/diag/diag_debugfs.c +4 −4 Original line number Diff line number Diff line /* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2011-2014, 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 @@ -451,7 +451,7 @@ static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf, diag_pools_array[POOL_DCI_IDX], driver->count_dci_pool); for (i = 0; i < MAX_HSIC_CH; i++) { for (i = 0; i < MAX_HSIC_DATA_CH; i++) { if (!diag_hsic[i].hsic_inited) continue; ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret, Loading @@ -462,7 +462,7 @@ static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf, diag_hsic[i].count_hsic_pool); } for (i = 0; i < MAX_HSIC_CH; i++) { for (i = 0; i < MAX_HSIC_DATA_CH; i++) { if (!diag_hsic[i].hsic_inited) continue; ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret, Loading Loading @@ -569,7 +569,7 @@ static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf, bytes_in_buffer += bytes_written; bytes_remaining = buf_size - bytes_in_buffer; for (i = 0; i < MAX_HSIC_CH; i++) { for (i = 0; i < MAX_HSIC_DATA_CH; i++) { if (diag_hsic[i].hsic_inited) { /* Check if there is room to add another HSIC entry */ if (bytes_remaining < bytes_hsic_inited) Loading drivers/char/diag/diagchar.h +13 −4 Original line number Diff line number Diff line Loading @@ -41,8 +41,12 @@ #define POOL_TYPE_WRITE_STRUCT 4 #define POOL_TYPE_HSIC 5 #define POOL_TYPE_HSIC_2 6 #define POOL_TYPE_HSIC_DCI 7 #define POOL_TYPE_HSIC_DCI_2 8 #define POOL_TYPE_HSIC_WRITE 11 #define POOL_TYPE_HSIC_2_WRITE 12 #define POOL_TYPE_HSIC_DCI_WRITE 13 #define POOL_TYPE_HSIC_DCI_2_WRITE 14 #define POOL_TYPE_ALL 10 #define POOL_TYPE_DCI 20 Loading @@ -53,11 +57,11 @@ #define POOL_DCI_IDX 4 #define POOL_BRIDGE_BASE POOL_DCI_IDX #define POOL_HSIC_IDX (POOL_BRIDGE_BASE + 1) #define POOL_HSIC_2_IDX (POOL_BRIDGE_BASE + 2) #define POOL_HSIC_DCI_IDX (POOL_BRIDGE_BASE + 2) #define POOL_HSIC_3_IDX (POOL_BRIDGE_BASE + 3) #define POOL_HSIC_4_IDX (POOL_BRIDGE_BASE + 4) #define POOL_HSIC_WRITE_IDX (POOL_BRIDGE_BASE + 5) #define POOL_HSIC_2_WRITE_IDX (POOL_BRIDGE_BASE + 6) #define POOL_HSIC_DCI_WRITE_IDX (POOL_BRIDGE_BASE + 6) #define POOL_HSIC_3_WRITE_IDX (POOL_BRIDGE_BASE + 7) #define POOL_HSIC_4_WRITE_IDX (POOL_BRIDGE_BASE + 8) Loading Loading @@ -170,6 +174,11 @@ #define DIAG_TS_SIZE 50 #define MAX_HSIC_DATA_CH 2 #define MAX_HSIC_DCI_CH 2 #define MAX_HSIC_CH (MAX_HSIC_DATA_CH + MAX_HSIC_DCI_CH) /* Maximum number of pkt reg supported at initialization*/ extern int diag_max_reg; extern int diag_threshold_reg; Loading @@ -185,8 +194,6 @@ do { \ enum remote_procs { MDM = 1, MDM2 = 2, MDM3 = 3, MDM4 = 4, QSC = 5, }; Loading Loading @@ -471,7 +478,9 @@ struct diagchar_dev { }; extern struct diag_bridge_dev *diag_bridge; extern struct diag_bridge_dci_dev *diag_bridge_dci; extern struct diag_hsic_dev *diag_hsic; extern struct diag_hsic_dci_dev *diag_hsic_dci; extern struct diagchar_dev *driver; extern int wrap_enabled; Loading drivers/char/diag/diagchar_core.c +35 −15 Original line number Diff line number Diff line Loading @@ -165,7 +165,7 @@ void diag_clear_hsic_tbl(void) int i, j; /* Clear for all active HSIC bridges */ for (j = 0; j < MAX_HSIC_CH; j++) { for (j = 0; j < MAX_HSIC_DATA_CH; j++) { if (diag_hsic[j].hsic_ch) { diag_hsic[j].num_hsic_buf_tbl_entries = 0; for (i = 0; i < diag_hsic[j].poolsize_hsic_write; i++) { Loading Loading @@ -428,8 +428,6 @@ static int diag_get_remote(int remote_info) switch (val) { case MDM: case MDM2: case MDM3: case MDM4: case QSC: remote_val = -remote_info; break; Loading @@ -448,7 +446,7 @@ uint16_t diag_get_remote_device_mask(void) int i; /* Check for MDM processor */ for (i = 0; i < MAX_HSIC_CH; i++) for (i = 0; i < MAX_HSIC_DATA_CH; i++) if (diag_hsic[i].hsic_inited) remote_dev |= 1 << i; Loading @@ -471,7 +469,7 @@ int diag_copy_remote(char __user *buf, size_t count, int *pret, int *pnum_data) struct diag_write_device hsic_buf_tbl[NUM_HSIC_BUF_TBL_ENTRIES]; remote_token = diag_get_remote(MDM); for (index = 0; index < MAX_HSIC_CH; index++) { for (index = 0; index < MAX_HSIC_DATA_CH; index++) { if (!diag_hsic[index].hsic_inited) { remote_token--; continue; Loading Loading @@ -784,7 +782,7 @@ void diag_cmp_logging_modes_diagfwd_bridge(int old_mode, int new_mode) } else if (old_mode == NO_LOGGING_MODE && new_mode == MEMORY_DEVICE_MODE) { int i; for (i = 0; i < MAX_HSIC_CH; i++) for (i = 0; i < MAX_HSIC_DATA_CH; i++) if (diag_hsic[i].hsic_inited) diag_hsic[i].hsic_data_requested = driver->real_time_mode ? 1 : 0; Loading Loading @@ -1605,7 +1603,7 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf, #endif #ifdef CONFIG_DIAGFWD_BRIDGE_CODE /* send masks to All 9k */ if ((remote_proc >= MDM) && (remote_proc <= MDM4)) { if ((remote_proc >= MDM) && (remote_proc <= MDM2)) { index = remote_proc - MDM; if (diag_hsic[index].hsic_ch && (payload_size > 0)) { /* wait sending mask updates Loading @@ -1618,7 +1616,8 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf, diag_hsic[index].in_busy_hsic_write = 1; diag_hsic[index].in_busy_hsic_read_on_device = 0; err = diag_bridge_write(index, err = diag_bridge_write( hsic_data_bridge_map[index], (char *)buf_hdlc, payload_size + 3); if (err) { pr_err("diag: err sending mask to MDM: %d\n", Loading Loading @@ -1703,7 +1702,7 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf, #endif #ifdef CONFIG_DIAGFWD_BRIDGE_CODE /* send masks to All 9k */ if ((remote_proc >= MDM) && (remote_proc <= MDM4) && if ((remote_proc >= MDM) && (remote_proc <= MDM2) && (payload_size > 0)) { index = remote_proc - MDM; /* Loading @@ -1726,7 +1725,8 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf, diag_hsic[index].in_busy_hsic_write = 1; diag_hsic[index].in_busy_hsic_read_on_device = 0; err = diag_bridge_write(index, err = diag_bridge_write( hsic_data_bridge_map[index], driver->user_space_data_buf + token_offset, payload_size); if (err) { Loading Loading @@ -2119,8 +2119,10 @@ inline void diag_sdio_fn(int type) {} #ifdef CONFIG_DIAGFWD_BRIDGE_CODE void diagfwd_bridge_fn(int type) { if (type == EXIT) if (type == EXIT) { diagfwd_bridge_exit(); diagfwd_bridge_dci_exit(); } } #else inline void diagfwd_bridge_fn(int type) { } Loading @@ -2135,14 +2137,26 @@ static int __init diagchar_init(void) ret = 0; driver = kzalloc(sizeof(struct diagchar_dev) + 5, GFP_KERNEL); #ifdef CONFIG_DIAGFWD_BRIDGE_CODE diag_bridge = kzalloc(MAX_BRIDGES * sizeof(struct diag_bridge_dev), diag_bridge = kzalloc(MAX_BRIDGES_DATA * sizeof(struct diag_bridge_dev), GFP_KERNEL); if (!diag_bridge) pr_warn("diag: could not allocate memory for bridges\n"); diag_hsic = kzalloc(MAX_HSIC_CH * sizeof(struct diag_hsic_dev), diag_bridge_dci = kzalloc(MAX_BRIDGES_DCI * sizeof(struct diag_bridge_dci_dev), GFP_KERNEL); if (!diag_bridge_dci) { pr_warn("diag: could not allocate memory for dci bridges\n"); goto fail; } diag_hsic = kzalloc(MAX_HSIC_DATA_CH * sizeof(struct diag_hsic_dev), GFP_KERNEL); if (!diag_hsic) pr_warn("diag: could not allocate memory for hsic ch\n"); diag_hsic_dci = kzalloc(MAX_HSIC_DCI_CH * sizeof(struct diag_hsic_dci_dev), GFP_KERNEL); if (!diag_hsic_dci) { pr_warn("diag: could not allocate memory for hsic dci ch\n"); goto fail; } #endif if (driver) { Loading Loading @@ -2177,8 +2191,14 @@ static int __init diagchar_init(void) diag_masks_init(); diagfwd_init(); #ifdef CONFIG_DIAGFWD_BRIDGE_CODE diagfwd_bridge_init(HSIC); diagfwd_bridge_init(HSIC_2); diagfwd_bridge_init(HSIC_DATA_CH); diagfwd_bridge_init(HSIC_DATA_CH_2); ret = diagfwd_bridge_dci_init(HSIC_DCI_CH); if (ret) goto fail; ret = diagfwd_bridge_dci_init(HSIC_DCI_CH_2); if (ret) goto fail; /* register HSIC device */ ret = platform_driver_register(&msm_hsic_ch_driver); if (ret) Loading drivers/char/diag/diagfwd_bridge.c +70 −16 Original line number Diff line number Diff line /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2014, 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 @@ -31,6 +31,7 @@ #include "diagfwd_bridge.h" struct diag_bridge_dev *diag_bridge; struct diag_bridge_dci_dev *diag_bridge_dci; /* diagfwd_connect_bridge is called when the USB mdm channel is connected */ int diagfwd_connect_bridge(int process_cable) Loading @@ -39,7 +40,7 @@ int diagfwd_connect_bridge(int process_cable) pr_debug("diag: in %s\n", __func__); for (i = 0; i < MAX_BRIDGES; i++) for (i = 0; i < MAX_BRIDGES_DATA; i++) if (diag_bridge[i].enabled) connect_bridge(process_cable, i); return 0; Loading Loading @@ -67,7 +68,7 @@ void connect_bridge(int process_cable, uint8_t index) diagfwd_connect_smux(); } } else { if (index >= MAX_HSIC_CH) { if (index >= MAX_HSIC_DATA_CH) { pr_err("diag: Invalid hsic channel index %d in %s\n", index, __func__); mutex_unlock(&diag_bridge[index].bridge_mutex); Loading @@ -83,7 +84,8 @@ void connect_bridge(int process_cable, uint8_t index) if (!diag_hsic[index].hsic_device_opened) { hsic_diag_bridge_ops[index].ctxt = (void *)(int)(index); err = diag_bridge_open(index, err = diag_bridge_open( hsic_data_bridge_map[index], &hsic_diag_bridge_ops[index]); if (err) { pr_err("diag: HSIC channel open error: %d\n", Loading Loading @@ -127,7 +129,7 @@ int diagfwd_disconnect_bridge(int process_cable) int i; pr_debug("diag: In %s, process_cable: %d\n", __func__, process_cable); for (i = 0; i < MAX_BRIDGES; i++) { for (i = 0; i < MAX_BRIDGES_DATA; i++) { if (diag_bridge[i].enabled) { mutex_lock(&diag_bridge[i].bridge_mutex); /* If the usb cable is being disconnected */ Loading Loading @@ -271,10 +273,8 @@ void diagfwd_bridge_init(int index) int ret; unsigned char name[20]; if (index == HSIC) { if (index == HSIC_DATA_CH) { strlcpy(name, "hsic", sizeof(name)); } else if (index == HSIC_2) { strlcpy(name, "hsic_2", sizeof(name)); } else if (index == SMUX) { strlcpy(name, "smux", sizeof(name)); } else { Loading Loading @@ -306,18 +306,15 @@ void diagfwd_bridge_init(int index) goto err; mutex_init(&diag_bridge[index].bridge_mutex); if (index == HSIC || index == HSIC_2) { if (index == HSIC_DATA_CH) { INIT_WORK(&(diag_bridge[index].usb_read_complete_work), diag_usb_read_complete_hsic_fn); #ifdef CONFIG_DIAG_OVER_USB INIT_WORK(&(diag_bridge[index].diag_read_work), diag_read_usb_hsic_work_fn); if (index == HSIC) if (index == HSIC_DATA_CH) diag_bridge[index].ch = usb_diag_open(DIAG_MDM, (void *)index, diagfwd_bridge_notifier); else if (index == HSIC_2) diag_bridge[index].ch = usb_diag_open(DIAG_MDM2, (void *)index, diagfwd_bridge_notifier); if (IS_ERR(diag_bridge[index].ch)) { pr_err("diag: Unable to open USB MDM ch = %d\n", index); goto err; Loading Loading @@ -360,7 +357,7 @@ void diagfwd_bridge_exit(void) int i; pr_debug("diag: in %s\n", __func__); for (i = 0; i < MAX_HSIC_CH; i++) { for (i = 0; i < MAX_HSIC_DATA_CH; i++) { if (diag_hsic[i].hsic_device_enabled) { diag_hsic_close(i); diag_hsic[i].hsic_device_enabled = 0; Loading @@ -379,7 +376,7 @@ void diagfwd_bridge_exit(void) platform_driver_unregister(&msm_hsic_ch_driver); platform_driver_unregister(&msm_diagfwd_smux_driver); /* destroy USB MDM specific variables */ for (i = 0; i < MAX_BRIDGES; i++) { for (i = 0; i < MAX_BRIDGES_DATA; i++) { if (diag_bridge[i].enabled) { #ifdef CONFIG_DIAG_OVER_USB usb_diag_close(diag_bridge[i].ch); Loading @@ -392,3 +389,60 @@ void diagfwd_bridge_exit(void) } kfree(driver->write_ptr_mdm); } int diagfwd_bridge_dci_init(int index) { unsigned char name[20]; if (!diag_bridge_dci) return -EIO; /* * Don't return an error code if the channel is not supported. The rest * of the driver initialization should proceed. * diag_bridge_dci[index].enabled is used to check if a particular * bridge instance is initialized. */ if (index == HSIC_DCI_CH) strlcpy(name, "hsic_dci", sizeof(name)); else return 0; strlcpy(diag_bridge_dci[index].name, name, sizeof(diag_bridge_dci[index].name)); strlcat(name, "_diag_wq", sizeof(diag_bridge_dci[index].name)); diag_bridge_dci[index].id = index; diag_bridge_dci[index].wq = create_singlethread_workqueue(name); if (!diag_bridge_dci[index].wq) return -ENOMEM; diag_bridge_dci[index].read_len = 0; diag_bridge_dci[index].write_len = 0; diag_bridge_dci[index].enabled = 1; mutex_init(&diag_bridge_dci[index].bridge_mutex); return 0; } void diagfwd_bridge_dci_exit(void) { int i; pr_debug("diag: in %s\n", __func__); for (i = 0; i < MAX_HSIC_DCI_CH; i++) { if (diag_hsic_dci[i].hsic_device_enabled) { diag_hsic_dci_close(i); diag_hsic_dci[i].hsic_device_enabled = 0; diag_bridge_dci[i].enabled = 0; } diag_hsic_dci[i].hsic_inited = 0; } diagmem_exit(driver, POOL_TYPE_ALL); for (i = 0; i < MAX_BRIDGES_DCI; i++) { if (diag_bridge_dci[i].enabled) { destroy_workqueue(diag_bridge_dci[i].wq); diag_bridge_dci[i].enabled = 0; } } } drivers/char/diag/diagfwd_bridge.h +26 −5 Original line number Diff line number Diff line /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2014, 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 @@ -15,16 +15,26 @@ #include "diagfwd.h" #define MAX_BRIDGES 5 #define HSIC 0 #define HSIC_2 1 #define SMUX 4 #define MAX_BRIDGES_DATA 3 #define MAX_BRIDGES_DCI 2 #define HSIC_DATA_CH 0 #define HSIC_DATA_CH_2 1 #define HSIC_DCI_CH 0 #define HSIC_DCI_CH_2 1 #define SMUX 2 #define DIAG_DATA_BRIDGE_IDX 0 #define DIAG_DCI_BRIDGE_IDX 1 #define DIAG_DATA_BRIDGE_IDX_2 2 #define DIAG_DCI_BRIDGE_IDX_2 3 int diagfwd_connect_bridge(int); void connect_bridge(int, uint8_t); int diagfwd_disconnect_bridge(int); void diagfwd_bridge_init(int index); int diagfwd_bridge_dci_init(int index); void diagfwd_bridge_exit(void); void diagfwd_bridge_dci_exit(void); int diagfwd_read_complete_bridge(struct diag_request *diag_read_ptr); /* Diag-Bridge structure, n bridges can be used at same time Loading @@ -46,4 +56,15 @@ struct diag_bridge_dev { struct work_struct usb_read_complete_work; }; struct diag_bridge_dci_dev { int id; char name[20]; int enabled; struct mutex bridge_mutex; int read_len; int write_len; struct workqueue_struct *wq; struct work_struct read_complete_work; }; #endif Loading
drivers/char/diag/diag_debugfs.c +4 −4 Original line number Diff line number Diff line /* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2011-2014, 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 @@ -451,7 +451,7 @@ static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf, diag_pools_array[POOL_DCI_IDX], driver->count_dci_pool); for (i = 0; i < MAX_HSIC_CH; i++) { for (i = 0; i < MAX_HSIC_DATA_CH; i++) { if (!diag_hsic[i].hsic_inited) continue; ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret, Loading @@ -462,7 +462,7 @@ static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf, diag_hsic[i].count_hsic_pool); } for (i = 0; i < MAX_HSIC_CH; i++) { for (i = 0; i < MAX_HSIC_DATA_CH; i++) { if (!diag_hsic[i].hsic_inited) continue; ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret, Loading Loading @@ -569,7 +569,7 @@ static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf, bytes_in_buffer += bytes_written; bytes_remaining = buf_size - bytes_in_buffer; for (i = 0; i < MAX_HSIC_CH; i++) { for (i = 0; i < MAX_HSIC_DATA_CH; i++) { if (diag_hsic[i].hsic_inited) { /* Check if there is room to add another HSIC entry */ if (bytes_remaining < bytes_hsic_inited) Loading
drivers/char/diag/diagchar.h +13 −4 Original line number Diff line number Diff line Loading @@ -41,8 +41,12 @@ #define POOL_TYPE_WRITE_STRUCT 4 #define POOL_TYPE_HSIC 5 #define POOL_TYPE_HSIC_2 6 #define POOL_TYPE_HSIC_DCI 7 #define POOL_TYPE_HSIC_DCI_2 8 #define POOL_TYPE_HSIC_WRITE 11 #define POOL_TYPE_HSIC_2_WRITE 12 #define POOL_TYPE_HSIC_DCI_WRITE 13 #define POOL_TYPE_HSIC_DCI_2_WRITE 14 #define POOL_TYPE_ALL 10 #define POOL_TYPE_DCI 20 Loading @@ -53,11 +57,11 @@ #define POOL_DCI_IDX 4 #define POOL_BRIDGE_BASE POOL_DCI_IDX #define POOL_HSIC_IDX (POOL_BRIDGE_BASE + 1) #define POOL_HSIC_2_IDX (POOL_BRIDGE_BASE + 2) #define POOL_HSIC_DCI_IDX (POOL_BRIDGE_BASE + 2) #define POOL_HSIC_3_IDX (POOL_BRIDGE_BASE + 3) #define POOL_HSIC_4_IDX (POOL_BRIDGE_BASE + 4) #define POOL_HSIC_WRITE_IDX (POOL_BRIDGE_BASE + 5) #define POOL_HSIC_2_WRITE_IDX (POOL_BRIDGE_BASE + 6) #define POOL_HSIC_DCI_WRITE_IDX (POOL_BRIDGE_BASE + 6) #define POOL_HSIC_3_WRITE_IDX (POOL_BRIDGE_BASE + 7) #define POOL_HSIC_4_WRITE_IDX (POOL_BRIDGE_BASE + 8) Loading Loading @@ -170,6 +174,11 @@ #define DIAG_TS_SIZE 50 #define MAX_HSIC_DATA_CH 2 #define MAX_HSIC_DCI_CH 2 #define MAX_HSIC_CH (MAX_HSIC_DATA_CH + MAX_HSIC_DCI_CH) /* Maximum number of pkt reg supported at initialization*/ extern int diag_max_reg; extern int diag_threshold_reg; Loading @@ -185,8 +194,6 @@ do { \ enum remote_procs { MDM = 1, MDM2 = 2, MDM3 = 3, MDM4 = 4, QSC = 5, }; Loading Loading @@ -471,7 +478,9 @@ struct diagchar_dev { }; extern struct diag_bridge_dev *diag_bridge; extern struct diag_bridge_dci_dev *diag_bridge_dci; extern struct diag_hsic_dev *diag_hsic; extern struct diag_hsic_dci_dev *diag_hsic_dci; extern struct diagchar_dev *driver; extern int wrap_enabled; Loading
drivers/char/diag/diagchar_core.c +35 −15 Original line number Diff line number Diff line Loading @@ -165,7 +165,7 @@ void diag_clear_hsic_tbl(void) int i, j; /* Clear for all active HSIC bridges */ for (j = 0; j < MAX_HSIC_CH; j++) { for (j = 0; j < MAX_HSIC_DATA_CH; j++) { if (diag_hsic[j].hsic_ch) { diag_hsic[j].num_hsic_buf_tbl_entries = 0; for (i = 0; i < diag_hsic[j].poolsize_hsic_write; i++) { Loading Loading @@ -428,8 +428,6 @@ static int diag_get_remote(int remote_info) switch (val) { case MDM: case MDM2: case MDM3: case MDM4: case QSC: remote_val = -remote_info; break; Loading @@ -448,7 +446,7 @@ uint16_t diag_get_remote_device_mask(void) int i; /* Check for MDM processor */ for (i = 0; i < MAX_HSIC_CH; i++) for (i = 0; i < MAX_HSIC_DATA_CH; i++) if (diag_hsic[i].hsic_inited) remote_dev |= 1 << i; Loading @@ -471,7 +469,7 @@ int diag_copy_remote(char __user *buf, size_t count, int *pret, int *pnum_data) struct diag_write_device hsic_buf_tbl[NUM_HSIC_BUF_TBL_ENTRIES]; remote_token = diag_get_remote(MDM); for (index = 0; index < MAX_HSIC_CH; index++) { for (index = 0; index < MAX_HSIC_DATA_CH; index++) { if (!diag_hsic[index].hsic_inited) { remote_token--; continue; Loading Loading @@ -784,7 +782,7 @@ void diag_cmp_logging_modes_diagfwd_bridge(int old_mode, int new_mode) } else if (old_mode == NO_LOGGING_MODE && new_mode == MEMORY_DEVICE_MODE) { int i; for (i = 0; i < MAX_HSIC_CH; i++) for (i = 0; i < MAX_HSIC_DATA_CH; i++) if (diag_hsic[i].hsic_inited) diag_hsic[i].hsic_data_requested = driver->real_time_mode ? 1 : 0; Loading Loading @@ -1605,7 +1603,7 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf, #endif #ifdef CONFIG_DIAGFWD_BRIDGE_CODE /* send masks to All 9k */ if ((remote_proc >= MDM) && (remote_proc <= MDM4)) { if ((remote_proc >= MDM) && (remote_proc <= MDM2)) { index = remote_proc - MDM; if (diag_hsic[index].hsic_ch && (payload_size > 0)) { /* wait sending mask updates Loading @@ -1618,7 +1616,8 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf, diag_hsic[index].in_busy_hsic_write = 1; diag_hsic[index].in_busy_hsic_read_on_device = 0; err = diag_bridge_write(index, err = diag_bridge_write( hsic_data_bridge_map[index], (char *)buf_hdlc, payload_size + 3); if (err) { pr_err("diag: err sending mask to MDM: %d\n", Loading Loading @@ -1703,7 +1702,7 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf, #endif #ifdef CONFIG_DIAGFWD_BRIDGE_CODE /* send masks to All 9k */ if ((remote_proc >= MDM) && (remote_proc <= MDM4) && if ((remote_proc >= MDM) && (remote_proc <= MDM2) && (payload_size > 0)) { index = remote_proc - MDM; /* Loading @@ -1726,7 +1725,8 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf, diag_hsic[index].in_busy_hsic_write = 1; diag_hsic[index].in_busy_hsic_read_on_device = 0; err = diag_bridge_write(index, err = diag_bridge_write( hsic_data_bridge_map[index], driver->user_space_data_buf + token_offset, payload_size); if (err) { Loading Loading @@ -2119,8 +2119,10 @@ inline void diag_sdio_fn(int type) {} #ifdef CONFIG_DIAGFWD_BRIDGE_CODE void diagfwd_bridge_fn(int type) { if (type == EXIT) if (type == EXIT) { diagfwd_bridge_exit(); diagfwd_bridge_dci_exit(); } } #else inline void diagfwd_bridge_fn(int type) { } Loading @@ -2135,14 +2137,26 @@ static int __init diagchar_init(void) ret = 0; driver = kzalloc(sizeof(struct diagchar_dev) + 5, GFP_KERNEL); #ifdef CONFIG_DIAGFWD_BRIDGE_CODE diag_bridge = kzalloc(MAX_BRIDGES * sizeof(struct diag_bridge_dev), diag_bridge = kzalloc(MAX_BRIDGES_DATA * sizeof(struct diag_bridge_dev), GFP_KERNEL); if (!diag_bridge) pr_warn("diag: could not allocate memory for bridges\n"); diag_hsic = kzalloc(MAX_HSIC_CH * sizeof(struct diag_hsic_dev), diag_bridge_dci = kzalloc(MAX_BRIDGES_DCI * sizeof(struct diag_bridge_dci_dev), GFP_KERNEL); if (!diag_bridge_dci) { pr_warn("diag: could not allocate memory for dci bridges\n"); goto fail; } diag_hsic = kzalloc(MAX_HSIC_DATA_CH * sizeof(struct diag_hsic_dev), GFP_KERNEL); if (!diag_hsic) pr_warn("diag: could not allocate memory for hsic ch\n"); diag_hsic_dci = kzalloc(MAX_HSIC_DCI_CH * sizeof(struct diag_hsic_dci_dev), GFP_KERNEL); if (!diag_hsic_dci) { pr_warn("diag: could not allocate memory for hsic dci ch\n"); goto fail; } #endif if (driver) { Loading Loading @@ -2177,8 +2191,14 @@ static int __init diagchar_init(void) diag_masks_init(); diagfwd_init(); #ifdef CONFIG_DIAGFWD_BRIDGE_CODE diagfwd_bridge_init(HSIC); diagfwd_bridge_init(HSIC_2); diagfwd_bridge_init(HSIC_DATA_CH); diagfwd_bridge_init(HSIC_DATA_CH_2); ret = diagfwd_bridge_dci_init(HSIC_DCI_CH); if (ret) goto fail; ret = diagfwd_bridge_dci_init(HSIC_DCI_CH_2); if (ret) goto fail; /* register HSIC device */ ret = platform_driver_register(&msm_hsic_ch_driver); if (ret) Loading
drivers/char/diag/diagfwd_bridge.c +70 −16 Original line number Diff line number Diff line /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2014, 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 @@ -31,6 +31,7 @@ #include "diagfwd_bridge.h" struct diag_bridge_dev *diag_bridge; struct diag_bridge_dci_dev *diag_bridge_dci; /* diagfwd_connect_bridge is called when the USB mdm channel is connected */ int diagfwd_connect_bridge(int process_cable) Loading @@ -39,7 +40,7 @@ int diagfwd_connect_bridge(int process_cable) pr_debug("diag: in %s\n", __func__); for (i = 0; i < MAX_BRIDGES; i++) for (i = 0; i < MAX_BRIDGES_DATA; i++) if (diag_bridge[i].enabled) connect_bridge(process_cable, i); return 0; Loading Loading @@ -67,7 +68,7 @@ void connect_bridge(int process_cable, uint8_t index) diagfwd_connect_smux(); } } else { if (index >= MAX_HSIC_CH) { if (index >= MAX_HSIC_DATA_CH) { pr_err("diag: Invalid hsic channel index %d in %s\n", index, __func__); mutex_unlock(&diag_bridge[index].bridge_mutex); Loading @@ -83,7 +84,8 @@ void connect_bridge(int process_cable, uint8_t index) if (!diag_hsic[index].hsic_device_opened) { hsic_diag_bridge_ops[index].ctxt = (void *)(int)(index); err = diag_bridge_open(index, err = diag_bridge_open( hsic_data_bridge_map[index], &hsic_diag_bridge_ops[index]); if (err) { pr_err("diag: HSIC channel open error: %d\n", Loading Loading @@ -127,7 +129,7 @@ int diagfwd_disconnect_bridge(int process_cable) int i; pr_debug("diag: In %s, process_cable: %d\n", __func__, process_cable); for (i = 0; i < MAX_BRIDGES; i++) { for (i = 0; i < MAX_BRIDGES_DATA; i++) { if (diag_bridge[i].enabled) { mutex_lock(&diag_bridge[i].bridge_mutex); /* If the usb cable is being disconnected */ Loading Loading @@ -271,10 +273,8 @@ void diagfwd_bridge_init(int index) int ret; unsigned char name[20]; if (index == HSIC) { if (index == HSIC_DATA_CH) { strlcpy(name, "hsic", sizeof(name)); } else if (index == HSIC_2) { strlcpy(name, "hsic_2", sizeof(name)); } else if (index == SMUX) { strlcpy(name, "smux", sizeof(name)); } else { Loading Loading @@ -306,18 +306,15 @@ void diagfwd_bridge_init(int index) goto err; mutex_init(&diag_bridge[index].bridge_mutex); if (index == HSIC || index == HSIC_2) { if (index == HSIC_DATA_CH) { INIT_WORK(&(diag_bridge[index].usb_read_complete_work), diag_usb_read_complete_hsic_fn); #ifdef CONFIG_DIAG_OVER_USB INIT_WORK(&(diag_bridge[index].diag_read_work), diag_read_usb_hsic_work_fn); if (index == HSIC) if (index == HSIC_DATA_CH) diag_bridge[index].ch = usb_diag_open(DIAG_MDM, (void *)index, diagfwd_bridge_notifier); else if (index == HSIC_2) diag_bridge[index].ch = usb_diag_open(DIAG_MDM2, (void *)index, diagfwd_bridge_notifier); if (IS_ERR(diag_bridge[index].ch)) { pr_err("diag: Unable to open USB MDM ch = %d\n", index); goto err; Loading Loading @@ -360,7 +357,7 @@ void diagfwd_bridge_exit(void) int i; pr_debug("diag: in %s\n", __func__); for (i = 0; i < MAX_HSIC_CH; i++) { for (i = 0; i < MAX_HSIC_DATA_CH; i++) { if (diag_hsic[i].hsic_device_enabled) { diag_hsic_close(i); diag_hsic[i].hsic_device_enabled = 0; Loading @@ -379,7 +376,7 @@ void diagfwd_bridge_exit(void) platform_driver_unregister(&msm_hsic_ch_driver); platform_driver_unregister(&msm_diagfwd_smux_driver); /* destroy USB MDM specific variables */ for (i = 0; i < MAX_BRIDGES; i++) { for (i = 0; i < MAX_BRIDGES_DATA; i++) { if (diag_bridge[i].enabled) { #ifdef CONFIG_DIAG_OVER_USB usb_diag_close(diag_bridge[i].ch); Loading @@ -392,3 +389,60 @@ void diagfwd_bridge_exit(void) } kfree(driver->write_ptr_mdm); } int diagfwd_bridge_dci_init(int index) { unsigned char name[20]; if (!diag_bridge_dci) return -EIO; /* * Don't return an error code if the channel is not supported. The rest * of the driver initialization should proceed. * diag_bridge_dci[index].enabled is used to check if a particular * bridge instance is initialized. */ if (index == HSIC_DCI_CH) strlcpy(name, "hsic_dci", sizeof(name)); else return 0; strlcpy(diag_bridge_dci[index].name, name, sizeof(diag_bridge_dci[index].name)); strlcat(name, "_diag_wq", sizeof(diag_bridge_dci[index].name)); diag_bridge_dci[index].id = index; diag_bridge_dci[index].wq = create_singlethread_workqueue(name); if (!diag_bridge_dci[index].wq) return -ENOMEM; diag_bridge_dci[index].read_len = 0; diag_bridge_dci[index].write_len = 0; diag_bridge_dci[index].enabled = 1; mutex_init(&diag_bridge_dci[index].bridge_mutex); return 0; } void diagfwd_bridge_dci_exit(void) { int i; pr_debug("diag: in %s\n", __func__); for (i = 0; i < MAX_HSIC_DCI_CH; i++) { if (diag_hsic_dci[i].hsic_device_enabled) { diag_hsic_dci_close(i); diag_hsic_dci[i].hsic_device_enabled = 0; diag_bridge_dci[i].enabled = 0; } diag_hsic_dci[i].hsic_inited = 0; } diagmem_exit(driver, POOL_TYPE_ALL); for (i = 0; i < MAX_BRIDGES_DCI; i++) { if (diag_bridge_dci[i].enabled) { destroy_workqueue(diag_bridge_dci[i].wq); diag_bridge_dci[i].enabled = 0; } } }
drivers/char/diag/diagfwd_bridge.h +26 −5 Original line number Diff line number Diff line /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2014, 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 @@ -15,16 +15,26 @@ #include "diagfwd.h" #define MAX_BRIDGES 5 #define HSIC 0 #define HSIC_2 1 #define SMUX 4 #define MAX_BRIDGES_DATA 3 #define MAX_BRIDGES_DCI 2 #define HSIC_DATA_CH 0 #define HSIC_DATA_CH_2 1 #define HSIC_DCI_CH 0 #define HSIC_DCI_CH_2 1 #define SMUX 2 #define DIAG_DATA_BRIDGE_IDX 0 #define DIAG_DCI_BRIDGE_IDX 1 #define DIAG_DATA_BRIDGE_IDX_2 2 #define DIAG_DCI_BRIDGE_IDX_2 3 int diagfwd_connect_bridge(int); void connect_bridge(int, uint8_t); int diagfwd_disconnect_bridge(int); void diagfwd_bridge_init(int index); int diagfwd_bridge_dci_init(int index); void diagfwd_bridge_exit(void); void diagfwd_bridge_dci_exit(void); int diagfwd_read_complete_bridge(struct diag_request *diag_read_ptr); /* Diag-Bridge structure, n bridges can be used at same time Loading @@ -46,4 +56,15 @@ struct diag_bridge_dev { struct work_struct usb_read_complete_work; }; struct diag_bridge_dci_dev { int id; char name[20]; int enabled; struct mutex bridge_mutex; int read_len; int write_len; struct workqueue_struct *wq; struct work_struct read_complete_work; }; #endif