diag: Add UART support
DIAG traffic has been supported over USB and SD card. This
change adds capability to route DIAG traffic over UART.
Change-Id: I0d6732fcbb19950700218140d581b5759e676b74
Signed-off-by: Shalabh Jain <shalabhj@codeaurora.org>
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 5c685c3..292fbc3 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -46,6 +46,7 @@
#define MSG_MASK_SIZE 8000
#define LOG_MASK_SIZE 8000
#define EVENT_MASK_SIZE 1000
+#define USER_SPACE_DATA 8000
#define PKT_SIZE 4096
#define MAX_EQUIP_ID 12
@@ -157,6 +158,7 @@
unsigned char *buf_in_wcnss_cntl;
unsigned char *usb_buf_out;
unsigned char *apps_rsp_buf;
+ unsigned char *user_space_data;
smd_channel_t *ch;
smd_channel_t *ch_cntl;
smd_channel_t *chqdsp;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index c9a9d57..6fa043c 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -355,6 +355,8 @@
mutex_lock(&driver->diagchar_mutex);
temp = driver->logging_mode;
driver->logging_mode = (int)ioarg;
+ if (driver->logging_mode == UART_MODE)
+ driver->logging_mode = MEMORY_DEVICE_MODE;
driver->logging_process_id = current->tgid;
mutex_unlock(&driver->diagchar_mutex);
if (temp == MEMORY_DEVICE_MODE && driver->logging_mode
@@ -363,12 +365,14 @@
driver->in_busy_2 = 1;
driver->in_busy_qdsp_1 = 1;
driver->in_busy_qdsp_2 = 1;
+ driver->in_busy_wcnss = 1;
} else if (temp == NO_LOGGING_MODE && driver->logging_mode
== MEMORY_DEVICE_MODE) {
driver->in_busy_1 = 0;
driver->in_busy_2 = 0;
driver->in_busy_qdsp_1 = 0;
driver->in_busy_qdsp_2 = 0;
+ driver->in_busy_wcnss = 0;
/* Poll SMD channels to check for data*/
if (driver->ch)
queue_work(driver->diag_wq,
@@ -376,6 +380,9 @@
if (driver->chqdsp)
queue_work(driver->diag_wq,
&(driver->diag_read_smd_qdsp_work));
+ if (driver->ch_wcnss)
+ queue_work(driver->diag_wq,
+ &(driver->diag_read_smd_wcnss_work));
}
#ifdef CONFIG_DIAG_OVER_USB
else if (temp == USB_MODE && driver->logging_mode
@@ -391,6 +398,7 @@
driver->in_busy_2 = 0;
driver->in_busy_qdsp_2 = 0;
driver->in_busy_qdsp_2 = 0;
+ driver->in_busy_wcnss = 0;
/* Poll SMD channels to check for data*/
if (driver->ch)
queue_work(driver->diag_wq,
@@ -398,6 +406,9 @@
if (driver->chqdsp)
queue_work(driver->diag_wq,
&(driver->diag_read_smd_qdsp_work));
+ if (driver->ch_wcnss)
+ queue_work(driver->diag_wq,
+ &(driver->diag_read_smd_wcnss_work));
} else if (temp == MEMORY_DEVICE_MODE && driver->logging_mode
== USB_MODE)
diagfwd_connect();
@@ -426,10 +437,10 @@
driver->data_ready[index]);
mutex_lock(&driver->diagchar_mutex);
- if ((driver->data_ready[index] & MEMORY_DEVICE_LOG_TYPE) && (driver->
+ if ((driver->data_ready[index] & USER_SPACE_LOG_TYPE) && (driver->
logging_mode == MEMORY_DEVICE_MODE)) {
/*Copy the type of data being passed*/
- data_type = driver->data_ready[index] & MEMORY_DEVICE_LOG_TYPE;
+ data_type = driver->data_ready[index] & USER_SPACE_LOG_TYPE;
COPY_USER_SPACE_OR_EXIT(buf, data_type, 4);
/* place holder for number of data field */
ret += 4;
@@ -496,8 +507,7 @@
driver->write_ptr_2->length);
driver->in_busy_2 = 0;
}
-
- /* copy q6 data */
+ /* copy lpass data */
if (driver->in_busy_qdsp_1 == 1) {
num_data++;
/*Copy the length of data being passed*/
@@ -520,23 +530,37 @@
write_ptr_qdsp_2->length);
driver->in_busy_qdsp_2 = 0;
}
-
+ /* copy wncss data */
+ if (driver->in_busy_wcnss == 1) {
+ num_data++;
+ /*Copy the length of data being passed*/
+ COPY_USER_SPACE_OR_EXIT(buf+ret,
+ (driver->write_ptr_wcnss->length), 4);
+ /*Copy the actual data being passed*/
+ COPY_USER_SPACE_OR_EXIT(buf+ret, *(driver->
+ buf_in_wcnss),
+ driver->write_ptr_wcnss->length);
+ driver->in_busy_wcnss = 0;
+ }
/* copy number of data fields */
COPY_USER_SPACE_OR_EXIT(buf+4, num_data, 4);
ret -= 4;
- driver->data_ready[index] ^= MEMORY_DEVICE_LOG_TYPE;
+ driver->data_ready[index] ^= USER_SPACE_LOG_TYPE;
if (driver->ch)
queue_work(driver->diag_wq,
&(driver->diag_read_smd_work));
if (driver->chqdsp)
queue_work(driver->diag_wq,
&(driver->diag_read_smd_qdsp_work));
+ if (driver->ch_wcnss)
+ queue_work(driver->diag_wq,
+ &(driver->diag_read_smd_wcnss_work));
APPEND_DEBUG('n');
goto exit;
- } else if (driver->data_ready[index] & MEMORY_DEVICE_LOG_TYPE) {
+ } else if (driver->data_ready[index] & USER_SPACE_LOG_TYPE) {
/* In case, the thread wakes up and the logging mode is
not memory device any more, the condition needs to be cleared */
- driver->data_ready[index] ^= MEMORY_DEVICE_LOG_TYPE;
+ driver->data_ready[index] ^= USER_SPACE_LOG_TYPE;
}
if (driver->data_ready[index] & DEINIT_TYPE) {
@@ -612,21 +636,27 @@
#endif /* DIAG over USB */
/* Get the packet type F3/log/event/Pkt response */
err = copy_from_user((&pkt_type), buf, 4);
- /*First 4 bytes indicate the type of payload - ignore these */
+ /* First 4 bytes indicate the type of payload - ignore these */
payload_size = count - 4;
- if (pkt_type == MEMORY_DEVICE_LOG_TYPE) {
- if (!mask_request_validate((unsigned char *)buf)) {
- printk(KERN_ALERT "mask request Invalid ..cannot send to modem \n");
- return -EFAULT;
+ if (pkt_type == USER_SPACE_LOG_TYPE) {
+ err = copy_from_user(driver->user_space_data, buf + 4,
+ payload_size);
+ /* Check masks for On-Device logging */
+ if (pkt_type == USER_SPACE_LOG_TYPE) {
+ if (!mask_request_validate((unsigned char *)buf)) {
+ pr_alert("diag: mask request Invalid\n");
+ return -EFAULT;
+ }
}
buf = buf + 4;
#ifdef DIAG_DEBUG
- pr_debug("diag: masks: %d\n", payload_size);
+ pr_debug("diag: user space data %d\n", payload_size);
for (i = 0; i < payload_size; i++)
printk(KERN_DEBUG "\t %x", *(((unsigned char *)buf)+i));
#endif
- diag_process_hdlc((void *)buf, payload_size);
+ diag_process_hdlc((void *)(driver->user_space_data),
+ payload_size);
return 0;
}
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index f9664c4..e49d57c 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -61,7 +61,8 @@
driver->write_ptr_1->length = (int)(enc.dest - \
(void *)(driver->buf_in_1)); \
driver->in_busy_1 = 1; \
- usb_diag_write(driver->legacy_ch, driver->write_ptr_1); \
+ diag_device_write(driver->buf_in_1, MODEM_DATA, \
+ driver->write_ptr_1); \
memset(driver->apps_rsp_buf, '\0', 500); \
} \
} while (0)
@@ -153,7 +154,7 @@
driver->logging_process_id)
break;
if (i < driver->num_clients) {
- driver->data_ready[i] |= MEMORY_DEVICE_LOG_TYPE;
+ driver->data_ready[i] |= USER_SPACE_LOG_TYPE;
wake_up_interruptible(&driver->wait_q);
} else
return -EINVAL;
@@ -982,13 +983,15 @@
{
printk(KERN_DEBUG "diag: USB disconnected\n");
driver->usb_connected = 0;
- driver->in_busy_1 = 1;
- driver->in_busy_2 = 1;
- driver->in_busy_qdsp_1 = 1;
- driver->in_busy_qdsp_2 = 1;
- driver->in_busy_wcnss = 1;
driver->debug_flag = 1;
usb_diag_free_req(driver->legacy_ch);
+ if (driver->logging_mode == USB_MODE) {
+ driver->in_busy_1 = 1;
+ driver->in_busy_2 = 1;
+ driver->in_busy_qdsp_1 = 1;
+ driver->in_busy_qdsp_2 = 1;
+ driver->in_busy_wcnss = 1;
+ }
#ifdef CONFIG_DIAG_SDIO_PIPE
if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
if (driver->mdm_ch && !IS_ERR(driver->mdm_ch))
@@ -1235,6 +1238,10 @@
if (driver->hdlc_buf == NULL
&& (driver->hdlc_buf = kzalloc(HDLC_MAX, GFP_KERNEL)) == NULL)
goto err;
+ if (driver->user_space_data == NULL)
+ driver->user_space_data = kzalloc(USER_SPACE_DATA, GFP_KERNEL);
+ if (driver->user_space_data == NULL)
+ goto err;
if (driver->msg_masks == NULL
&& (driver->msg_masks = kzalloc(MSG_MASK_SIZE,
GFP_KERNEL)) == NULL)
@@ -1350,6 +1357,7 @@
kfree(driver->write_ptr_wcnss);
kfree(driver->usb_read_ptr);
kfree(driver->apps_rsp_buf);
+ kfree(driver->user_space_data);
if (driver->diag_wq)
destroy_workqueue(driver->diag_wq);
}
@@ -1391,5 +1399,6 @@
kfree(driver->write_ptr_wcnss);
kfree(driver->usb_read_ptr);
kfree(driver->apps_rsp_buf);
+ kfree(driver->user_space_data);
destroy_workqueue(driver->diag_wq);
}
diff --git a/drivers/char/diag/diagfwd_sdio.c b/drivers/char/diag/diagfwd_sdio.c
index 8be9f46..f3873aa 100644
--- a/drivers/char/diag/diagfwd_sdio.c
+++ b/drivers/char/diag/diagfwd_sdio.c
@@ -124,10 +124,11 @@
int diagfwd_disconnect_sdio(void)
{
- driver->in_busy_sdio = 1;
usb_diag_free_req(driver->mdm_ch);
- if (driver->sdio_ch && (driver->logging_mode == USB_MODE))
+ if (driver->sdio_ch && (driver->logging_mode == USB_MODE)) {
+ driver->in_busy_sdio = 1;
diag_sdio_close();
+ }
return 0;
}
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 22270de..91d67d5 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -18,10 +18,11 @@
#define EVENT_MASKS_TYPE 4
#define PKT_TYPE 8
#define DEINIT_TYPE 16
-#define MEMORY_DEVICE_LOG_TYPE 32
+#define USER_SPACE_LOG_TYPE 32
#define USB_MODE 1
#define MEMORY_DEVICE_MODE 2
#define NO_LOGGING_MODE 3
+#define UART_MODE 4
/* different values that go in for diag_data_type */
#define DATA_TYPE_EVENT 0