blob: 7ceae898f006d657279952655c1fa9ae5dd16674 [file] [log] [blame]
Dixon Peterson32e70bb2011-12-16 13:26:45 -08001/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070012#include <linux/slab.h>
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/device.h>
16#include <linux/err.h>
17#include <linux/platform_device.h>
18#include <linux/sched.h>
19#include <linux/workqueue.h>
20#include <linux/pm_runtime.h>
21#include <linux/diagchar.h>
22#include <linux/delay.h>
23#include <linux/reboot.h>
24#ifdef CONFIG_DIAG_OVER_USB
25#include <mach/usbdiag.h>
26#endif
27#include <mach/msm_smd.h>
28#include <mach/socinfo.h>
29#include <mach/restart.h>
30#include "diagmem.h"
31#include "diagchar.h"
32#include "diagfwd.h"
33#include "diagfwd_cntl.h"
34#include "diagchar_hdlc.h"
35#ifdef CONFIG_DIAG_SDIO_PIPE
36#include "diagfwd_sdio.h"
37#endif
38#define MODE_CMD 41
39#define RESET_ID 2
40
41int diag_debug_buf_idx;
42unsigned char diag_debug_buf[1024];
43static unsigned int buf_tbl_size = 8; /*Number of entries in table of buffers */
44struct diag_master_table entry;
Shalabh Jainc6c2b1d2011-12-20 04:32:34 -080045smd_channel_t *ch_temp, *chqdsp_temp, *ch_wcnss_temp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070046struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 };
47struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
48
49#define ENCODE_RSP_AND_SEND(buf_length) \
50do { \
51 send.state = DIAG_STATE_START; \
52 send.pkt = driver->apps_rsp_buf; \
53 send.last = (void *)(driver->apps_rsp_buf + buf_length); \
54 send.terminate = 1; \
55 if (!driver->in_busy_1) { \
56 enc.dest = driver->buf_in_1; \
57 enc.dest_last = (void *)(driver->buf_in_1 + 499); \
58 diag_hdlc_encode(&send, &enc); \
59 driver->write_ptr_1->buf = driver->buf_in_1; \
60 driver->write_ptr_1->length = (int)(enc.dest - \
61 (void *)(driver->buf_in_1)); \
Shalabh Jain3893bf92011-09-18 18:37:16 -070062 driver->in_busy_1 = 1; \
Shalabh Jain69890aa2011-10-10 12:59:16 -070063 diag_device_write(driver->buf_in_1, MODEM_DATA, \
64 driver->write_ptr_1); \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070065 memset(driver->apps_rsp_buf, '\0', 500); \
66 } \
67} while (0)
68
69#define CHK_OVERFLOW(bufStart, start, end, length) \
70((bufStart <= start) && (end - start >= length)) ? 1 : 0
71
Shalabh Jainfb8e3c12011-10-19 17:29:42 -070072int chk_config_get_id(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070073{
Shalabh Jain482bf122011-12-06 03:54:47 -080074 /* For all Fusion targets, Modem will always be present */
75 if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
76 return 0;
77
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070078 switch (socinfo_get_id()) {
79 case APQ8060_MACHINE_ID:
80 case MSM8660_MACHINE_ID:
81 return APQ8060_TOOLS_ID;
82 case AO8960_MACHINE_ID:
Shalabh Jain10f5f432012-01-11 11:45:44 +053083 case MSM8260A_MACHINE_ID:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070084 return AO8960_TOOLS_ID;
Shalabh Jainfb8e3c12011-10-19 17:29:42 -070085 case APQ8064_MACHINE_ID:
86 return APQ8064_TOOLS_ID;
Shalabh Jain2f4cea62011-12-19 21:50:03 -080087 case MSM8930_MACHINE_ID:
88 return MSM8930_TOOLS_ID;
Shalabh Jain10f5f432012-01-11 11:45:44 +053089 case MSM8974_MACHINE_ID:
90 return MSM8974_TOOLS_ID;
Shalabh Jainfb8e3c12011-10-19 17:29:42 -070091 default:
92 return 0;
93 }
94}
95
96/*
Shalabh Jain2c783cb2012-01-15 11:09:29 +053097 * This will return TRUE for targets which support apps only mode.
Shalabh Jainfb8e3c12011-10-19 17:29:42 -070098 * This applies to 8960 and newer targets.
99 */
100int chk_apps_only(void)
101{
102 switch (socinfo_get_id()) {
103 case AO8960_MACHINE_ID:
104 case APQ8064_MACHINE_ID:
Shalabh Jain2f4cea62011-12-19 21:50:03 -0800105 case MSM8930_MACHINE_ID:
106 case MSM8630_MACHINE_ID:
107 case MSM8230_MACHINE_ID:
108 case APQ8030_MACHINE_ID:
109 case MSM8627_MACHINE_ID:
110 case MSM8227_MACHINE_ID:
Shalabh Jain10f5f432012-01-11 11:45:44 +0530111 case MSM8974_MACHINE_ID:
112 case MDM9615_MACHINE_ID:
113 case MSM8260A_MACHINE_ID:
Shalabh Jainfb8e3c12011-10-19 17:29:42 -0700114 return 1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700115 default:
116 return 0;
117 }
118}
119
Shalabh Jain10f5f432012-01-11 11:45:44 +0530120/*
121 * This will return TRUE for targets which support apps as master.
122 * Thus, SW DLOAD and Mode Reset are supported on apps processor.
123 * This applies to 8960 and newer targets.
124 */
125int chk_apps_master(void)
126{
127 if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615())
128 return 1;
129 else
130 return 0;
131}
132
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700133void __diag_smd_send_req(void)
134{
135 void *buf = NULL;
136 int *in_busy_ptr = NULL;
137 struct diag_request *write_ptr_modem = NULL;
138
139 if (!driver->in_busy_1) {
140 buf = driver->buf_in_1;
141 write_ptr_modem = driver->write_ptr_1;
142 in_busy_ptr = &(driver->in_busy_1);
143 } else if (!driver->in_busy_2) {
144 buf = driver->buf_in_2;
145 write_ptr_modem = driver->write_ptr_2;
146 in_busy_ptr = &(driver->in_busy_2);
147 }
148
149 if (driver->ch && buf) {
150 int r = smd_read_avail(driver->ch);
151
152 if (r > IN_BUF_SIZE) {
153 if (r < MAX_IN_BUF_SIZE) {
154 pr_err("diag: SMD sending in "
155 "packets upto %d bytes", r);
156 buf = krealloc(buf, r, GFP_KERNEL);
157 } else {
158 pr_err("diag: SMD sending in "
159 "packets more than %d bytes", MAX_IN_BUF_SIZE);
160 return;
161 }
162 }
163 if (r > 0) {
164 if (!buf)
165 pr_info("Out of diagmem for Modem\n");
166 else {
167 APPEND_DEBUG('i');
168 smd_read(driver->ch, buf, r);
169 APPEND_DEBUG('j');
170 write_ptr_modem->length = r;
171 *in_busy_ptr = 1;
172 diag_device_write(buf, MODEM_DATA,
173 write_ptr_modem);
174 }
175 }
176 }
177}
178
179int diag_device_write(void *buf, int proc_num, struct diag_request *write_ptr)
180{
181 int i, err = 0;
182
183 if (driver->logging_mode == MEMORY_DEVICE_MODE) {
184 if (proc_num == APPS_DATA) {
185 for (i = 0; i < driver->poolsize_write_struct; i++)
186 if (driver->buf_tbl[i].length == 0) {
187 driver->buf_tbl[i].buf = buf;
188 driver->buf_tbl[i].length =
189 driver->used;
190#ifdef DIAG_DEBUG
191 pr_debug("diag: ENQUEUE buf ptr"
192 " and length is %x , %d\n",
193 (unsigned int)(driver->buf_
194 tbl[i].buf), driver->buf_tbl[i].length);
195#endif
196 break;
197 }
198 }
199 for (i = 0; i < driver->num_clients; i++)
200 if (driver->client_map[i].pid ==
201 driver->logging_process_id)
202 break;
203 if (i < driver->num_clients) {
Shalabh Jain69890aa2011-10-10 12:59:16 -0700204 driver->data_ready[i] |= USER_SPACE_LOG_TYPE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700205 wake_up_interruptible(&driver->wait_q);
206 } else
207 return -EINVAL;
208 } else if (driver->logging_mode == NO_LOGGING_MODE) {
209 if (proc_num == MODEM_DATA) {
210 driver->in_busy_1 = 0;
211 driver->in_busy_2 = 0;
212 queue_work(driver->diag_wq, &(driver->
213 diag_read_smd_work));
214 } else if (proc_num == QDSP_DATA) {
215 driver->in_busy_qdsp_1 = 0;
216 driver->in_busy_qdsp_2 = 0;
217 queue_work(driver->diag_wq, &(driver->
218 diag_read_smd_qdsp_work));
219 } else if (proc_num == WCNSS_DATA) {
220 driver->in_busy_wcnss = 0;
221 queue_work(driver->diag_wq, &(driver->
222 diag_read_smd_wcnss_work));
223 }
Shalabh Jain482bf122011-12-06 03:54:47 -0800224#ifdef CONFIG_DIAG_SDIO_PIPE
225 else if (proc_num == SDIO_DATA) {
226 driver->in_busy_sdio = 0;
227 queue_work(driver->diag_sdio_wq,
228 &(driver->diag_read_sdio_work));
229 }
230#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700231 err = -1;
232 }
233#ifdef CONFIG_DIAG_OVER_USB
234 else if (driver->logging_mode == USB_MODE) {
235 if (proc_num == APPS_DATA) {
236 driver->write_ptr_svc = (struct diag_request *)
237 (diagmem_alloc(driver, sizeof(struct diag_request),
238 POOL_TYPE_WRITE_STRUCT));
239 if (driver->write_ptr_svc) {
240 driver->write_ptr_svc->length = driver->used;
241 driver->write_ptr_svc->buf = buf;
242 err = usb_diag_write(driver->legacy_ch,
243 driver->write_ptr_svc);
244 } else
245 err = -1;
246 } else if (proc_num == MODEM_DATA) {
247 write_ptr->buf = buf;
248#ifdef DIAG_DEBUG
249 printk(KERN_INFO "writing data to USB,"
250 "pkt length %d\n", write_ptr->length);
251 print_hex_dump(KERN_DEBUG, "Written Packet Data to"
252 " USB: ", 16, 1, DUMP_PREFIX_ADDRESS,
253 buf, write_ptr->length, 1);
254#endif /* DIAG DEBUG */
255 err = usb_diag_write(driver->legacy_ch, write_ptr);
256 } else if (proc_num == QDSP_DATA) {
257 write_ptr->buf = buf;
258 err = usb_diag_write(driver->legacy_ch, write_ptr);
259 } else if (proc_num == WCNSS_DATA) {
260 write_ptr->buf = buf;
261 err = usb_diag_write(driver->legacy_ch, write_ptr);
262 }
263#ifdef CONFIG_DIAG_SDIO_PIPE
264 else if (proc_num == SDIO_DATA) {
265 if (machine_is_msm8x60_fusion() ||
Shalabh Jain482bf122011-12-06 03:54:47 -0800266 machine_is_msm8x60_fusn_ffa()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700267 write_ptr->buf = buf;
268 err = usb_diag_write(driver->mdm_ch, write_ptr);
269 } else
Dixon Peterson32e70bb2011-12-16 13:26:45 -0800270 pr_err("diag: Incorrect sdio data "
271 "while USB write\n");
272 }
273#endif
274#ifdef CONFIG_DIAG_HSIC_PIPE
275 else if (proc_num == HSIC_DATA) {
276 if (driver->hsic_device_enabled) {
277 write_ptr->buf = buf;
278 err = usb_diag_write(driver->mdm_ch, write_ptr);
279 } else
280 pr_err("diag: Incorrect hsic data "
281 "while USB write\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700282 }
283#endif
284 APPEND_DEBUG('d');
285 }
286#endif /* DIAG OVER USB */
287 return err;
288}
289
290void __diag_smd_wcnss_send_req(void)
291{
292 void *buf = driver->buf_in_wcnss;
293 int *in_busy_wcnss_ptr = &(driver->in_busy_wcnss);
294 struct diag_request *write_ptr_wcnss = driver->write_ptr_wcnss;
295
Shalabh Jain3893bf92011-09-18 18:37:16 -0700296 if ((!driver->in_busy_wcnss) && driver->ch_wcnss && buf) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700297 int r = smd_read_avail(driver->ch_wcnss);
298 if (r > IN_BUF_SIZE) {
299 if (r < MAX_IN_BUF_SIZE) {
300 pr_err("diag: wcnss packets > %d bytes", r);
301 buf = krealloc(buf, r, GFP_KERNEL);
302 } else {
303 pr_err("diag: wcnss pkt > %d", MAX_IN_BUF_SIZE);
304 return;
305 }
306 }
307 if (r > 0) {
308 if (!buf) {
309 pr_err("Out of diagmem for wcnss\n");
310 } else {
311 APPEND_DEBUG('i');
312 smd_read(driver->ch_wcnss, buf, r);
313 APPEND_DEBUG('j');
314 write_ptr_wcnss->length = r;
315 *in_busy_wcnss_ptr = 1;
316 diag_device_write(buf, WCNSS_DATA,
317 write_ptr_wcnss);
318 }
319 }
320 }
321}
322
323void __diag_smd_qdsp_send_req(void)
324{
325 void *buf = NULL;
326 int *in_busy_qdsp_ptr = NULL;
327 struct diag_request *write_ptr_qdsp = NULL;
328
329 if (!driver->in_busy_qdsp_1) {
330 buf = driver->buf_in_qdsp_1;
331 write_ptr_qdsp = driver->write_ptr_qdsp_1;
332 in_busy_qdsp_ptr = &(driver->in_busy_qdsp_1);
333 } else if (!driver->in_busy_qdsp_2) {
334 buf = driver->buf_in_qdsp_2;
335 write_ptr_qdsp = driver->write_ptr_qdsp_2;
336 in_busy_qdsp_ptr = &(driver->in_busy_qdsp_2);
337 }
338
339 if (driver->chqdsp && buf) {
340 int r = smd_read_avail(driver->chqdsp);
341
342 if (r > IN_BUF_SIZE) {
343 if (r < MAX_IN_BUF_SIZE) {
344 pr_err("diag: SMD sending in "
345 "packets upto %d bytes", r);
346 buf = krealloc(buf, r, GFP_KERNEL);
347 } else {
348 pr_err("diag: SMD sending in "
349 "packets more than %d bytes", MAX_IN_BUF_SIZE);
350 return;
351 }
352 }
353 if (r > 0) {
354 if (!buf)
355 printk(KERN_INFO "Out of diagmem for QDSP\n");
356 else {
357 APPEND_DEBUG('i');
358 smd_read(driver->chqdsp, buf, r);
359 APPEND_DEBUG('j');
360 write_ptr_qdsp->length = r;
361 *in_busy_qdsp_ptr = 1;
362 diag_device_write(buf, QDSP_DATA,
363 write_ptr_qdsp);
364 }
365 }
366 }
367}
368
369static void diag_print_mask_table(void)
370{
371/* Enable this to print mask table when updated */
372#ifdef MASK_DEBUG
373 int first;
374 int last;
375 uint8_t *ptr = driver->msg_masks;
376 int i = 0;
377
378 while (*(uint32_t *)(ptr + 4)) {
379 first = *(uint32_t *)ptr;
380 ptr += 4;
381 last = *(uint32_t *)ptr;
382 ptr += 4;
383 printk(KERN_INFO "SSID %d - %d\n", first, last);
384 for (i = 0 ; i <= last - first ; i++)
385 printk(KERN_INFO "MASK:%x\n", *((uint32_t *)ptr + i));
386 ptr += ((last - first) + 1)*4;
387
388 }
389#endif
390}
391
392static void diag_update_msg_mask(int start, int end , uint8_t *buf)
393{
394 int found = 0;
395 int first;
396 int last;
397 uint8_t *ptr = driver->msg_masks;
398 uint8_t *ptr_buffer_start = &(*(driver->msg_masks));
399 uint8_t *ptr_buffer_end = &(*(driver->msg_masks)) + MSG_MASK_SIZE;
400
401 mutex_lock(&driver->diagchar_mutex);
402 /* First SSID can be zero : So check that last is non-zero */
Shalabh Jain2c783cb2012-01-15 11:09:29 +0530403
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700404 while (*(uint32_t *)(ptr + 4)) {
405 first = *(uint32_t *)ptr;
406 ptr += 4;
407 last = *(uint32_t *)ptr;
408 ptr += 4;
409 if (start >= first && start <= last) {
410 ptr += (start - first)*4;
411 if (end <= last)
412 if (CHK_OVERFLOW(ptr_buffer_start, ptr,
413 ptr_buffer_end,
414 (((end - start)+1)*4)))
415 memcpy(ptr, buf , ((end - start)+1)*4);
416 else
417 printk(KERN_CRIT "Not enough"
418 " buffer space for"
419 " MSG_MASK\n");
420 else
421 printk(KERN_INFO "Unable to copy"
422 " mask change\n");
Shalabh Jain2c783cb2012-01-15 11:09:29 +0530423
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700424 found = 1;
425 break;
426 } else {
427 ptr += ((last - first) + 1)*4;
428 }
429 }
430 /* Entry was not found - add new table */
431 if (!found) {
432 if (CHK_OVERFLOW(ptr_buffer_start, ptr, ptr_buffer_end,
433 8 + ((end - start) + 1)*4)) {
434 memcpy(ptr, &(start) , 4);
435 ptr += 4;
436 memcpy(ptr, &(end), 4);
437 ptr += 4;
438 memcpy(ptr, buf , ((end - start) + 1)*4);
439 } else
440 printk(KERN_CRIT " Not enough buffer"
441 " space for MSG_MASK\n");
442 }
443 mutex_unlock(&driver->diagchar_mutex);
444 diag_print_mask_table();
Shalabh Jain2c783cb2012-01-15 11:09:29 +0530445
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700446}
447
Shalabh Jain2c783cb2012-01-15 11:09:29 +0530448static void diag_update_event_mask(uint8_t *buf, int toggle, int num_bits)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700449{
450 uint8_t *ptr = driver->event_masks;
451 uint8_t *temp = buf + 2;
452
453 mutex_lock(&driver->diagchar_mutex);
454 if (!toggle)
455 memset(ptr, 0 , EVENT_MASK_SIZE);
456 else
457 if (CHK_OVERFLOW(ptr, ptr,
458 ptr+EVENT_MASK_SIZE,
Shalabh Jain2c783cb2012-01-15 11:09:29 +0530459 num_bits/8 + 1))
460 memcpy(ptr, temp , num_bits/8 + 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700461 else
462 printk(KERN_CRIT "Not enough buffer space "
463 "for EVENT_MASK\n");
464 mutex_unlock(&driver->diagchar_mutex);
465}
466
467static void diag_update_log_mask(int equip_id, uint8_t *buf, int num_items)
468{
469 uint8_t *temp = buf;
Shalabh Jain2c783cb2012-01-15 11:09:29 +0530470 struct mask_info {
471 int equip_id;
472 int index;
473 };
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700474 int i = 0;
475 unsigned char *ptr_data;
476 int offset = 8*MAX_EQUIP_ID;
477 struct mask_info *ptr = (struct mask_info *)driver->log_masks;
478
479 mutex_lock(&driver->diagchar_mutex);
480 /* Check if we already know index of this equipment ID */
481 for (i = 0; i < MAX_EQUIP_ID; i++) {
482 if ((ptr->equip_id == equip_id) && (ptr->index != 0)) {
483 offset = ptr->index;
484 break;
485 }
486 if ((ptr->equip_id == 0) && (ptr->index == 0)) {
Shalabh Jain2c783cb2012-01-15 11:09:29 +0530487 /*Reached a null entry */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700488 ptr->equip_id = equip_id;
489 ptr->index = driver->log_masks_length;
490 offset = driver->log_masks_length;
491 driver->log_masks_length += ((num_items+7)/8);
492 break;
493 }
494 ptr++;
495 }
496 ptr_data = driver->log_masks + offset;
497 if (CHK_OVERFLOW(driver->log_masks, ptr_data, driver->log_masks
498 + LOG_MASK_SIZE, (num_items+7)/8))
499 memcpy(ptr_data, temp , (num_items+7)/8);
500 else
501 printk(KERN_CRIT " Not enough buffer space for LOG_MASK\n");
502 mutex_unlock(&driver->diagchar_mutex);
503}
504
505static void diag_update_pkt_buffer(unsigned char *buf)
506{
507 unsigned char *ptr = driver->pkt_buf;
508 unsigned char *temp = buf;
509
510 mutex_lock(&driver->diagchar_mutex);
511 if (CHK_OVERFLOW(ptr, ptr, ptr + PKT_SIZE, driver->pkt_length))
512 memcpy(ptr, temp , driver->pkt_length);
513 else
514 printk(KERN_CRIT " Not enough buffer space for PKT_RESP\n");
515 mutex_unlock(&driver->diagchar_mutex);
516}
517
518void diag_update_userspace_clients(unsigned int type)
519{
520 int i;
521
522 mutex_lock(&driver->diagchar_mutex);
523 for (i = 0; i < driver->num_clients; i++)
524 if (driver->client_map[i].pid != 0)
525 driver->data_ready[i] |= type;
526 wake_up_interruptible(&driver->wait_q);
527 mutex_unlock(&driver->diagchar_mutex);
528}
529
530void diag_update_sleeping_process(int process_id)
531{
532 int i;
533
534 mutex_lock(&driver->diagchar_mutex);
535 for (i = 0; i < driver->num_clients; i++)
536 if (driver->client_map[i].pid == process_id) {
537 driver->data_ready[i] |= PKT_TYPE;
538 break;
539 }
540 wake_up_interruptible(&driver->wait_q);
541 mutex_unlock(&driver->diagchar_mutex);
542}
543
544void diag_send_data(struct diag_master_table entry, unsigned char *buf,
545 int len, int type)
546{
547 driver->pkt_length = len;
548 if (entry.process_id != NON_APPS_PROC && type != MODEM_DATA) {
549 diag_update_pkt_buffer(buf);
550 diag_update_sleeping_process(entry.process_id);
551 } else {
552 if (len > 0) {
Shalabh Jainc9f35092011-07-28 18:36:17 -0700553 if (entry.client_id == MODEM_PROC && driver->ch) {
Shalabh Jain10f5f432012-01-11 11:45:44 +0530554 if (chk_apps_master() &&
Shalabh Jainc9f35092011-07-28 18:36:17 -0700555 (int)(*(char *)buf) == MODE_CMD)
Dixon Petersonff425d12011-12-06 18:12:35 -0800556 if ((int)(*(char *)(buf+1)) ==
557 RESET_ID)
Shalabh Jainc9f35092011-07-28 18:36:17 -0700558 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700559 smd_write(driver->ch, buf, len);
Shalabh Jainc9f35092011-07-28 18:36:17 -0700560 } else if (entry.client_id == QDSP_PROC &&
561 driver->chqdsp) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700562 smd_write(driver->chqdsp, buf, len);
Shalabh Jainc9f35092011-07-28 18:36:17 -0700563 } else if (entry.client_id == WCNSS_PROC &&
564 driver->ch_wcnss) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700565 smd_write(driver->ch_wcnss, buf, len);
Shalabh Jainc9f35092011-07-28 18:36:17 -0700566 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700567 pr_alert("diag: incorrect channel");
Shalabh Jainc9f35092011-07-28 18:36:17 -0700568 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700569 }
570 }
571}
572
573static int diag_process_apps_pkt(unsigned char *buf, int len)
574{
575 uint16_t subsys_cmd_code;
576 int subsys_id, ssid_first, ssid_last, ssid_range;
577 int packet_type = 1, i, cmd_code;
578 unsigned char *temp = buf;
579 int data_type;
580#if defined(CONFIG_DIAG_OVER_USB)
581 int payload_length;
582 unsigned char *ptr;
583#endif
584
585 /* Check for registered clients and forward packet to apropriate proc */
586 cmd_code = (int)(*(char *)buf);
587 temp++;
588 subsys_id = (int)(*(char *)temp);
589 temp++;
590 subsys_cmd_code = *(uint16_t *)temp;
591 temp += 2;
592 data_type = APPS_DATA;
593 /* Dont send any command other than mode reset */
Shalabh Jain10f5f432012-01-11 11:45:44 +0530594 if (chk_apps_master() && cmd_code == MODE_CMD) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700595 if (subsys_id != RESET_ID)
596 data_type = MODEM_DATA;
597 }
598
599 pr_debug("diag: %d %d %d", cmd_code, subsys_id, subsys_cmd_code);
600 for (i = 0; i < diag_max_registration; i++) {
601 entry = driver->table[i];
602 if (entry.process_id != NO_PROCESS) {
603 if (entry.cmd_code == cmd_code && entry.subsys_id ==
604 subsys_id && entry.cmd_code_lo <=
605 subsys_cmd_code &&
606 entry.cmd_code_hi >= subsys_cmd_code) {
607 diag_send_data(entry, buf, len, data_type);
608 packet_type = 0;
609 } else if (entry.cmd_code == 255
610 && cmd_code == 75) {
611 if (entry.subsys_id ==
612 subsys_id &&
613 entry.cmd_code_lo <=
614 subsys_cmd_code &&
615 entry.cmd_code_hi >=
616 subsys_cmd_code) {
617 diag_send_data(entry, buf, len,
618 data_type);
619 packet_type = 0;
620 }
621 } else if (entry.cmd_code == 255 &&
622 entry.subsys_id == 255) {
623 if (entry.cmd_code_lo <=
624 cmd_code &&
625 entry.
626 cmd_code_hi >= cmd_code) {
627 diag_send_data(entry, buf, len,
628 data_type);
629 packet_type = 0;
630 }
631 }
632 }
633 }
Shalabh Jain2c783cb2012-01-15 11:09:29 +0530634 /* set event mask */
635 if (*buf == 0x82) {
636 buf += 4;
637 diag_update_event_mask(buf, 1, *(uint16_t *)buf);
638 diag_update_userspace_clients(EVENT_MASKS_TYPE);
639 }
640 /* event mask change */
641 else if ((*buf == 0x60) && (*(buf+1) == 0x0)) {
642 diag_update_event_mask(buf+1, 0, 0);
643 diag_update_userspace_clients(EVENT_MASKS_TYPE);
644#if defined(CONFIG_DIAG_OVER_USB)
645 /* Check for Apps Only */
646 if (!(driver->ch) && chk_apps_only()) {
647 /* echo response back for apps only DIAG */
648 driver->apps_rsp_buf[0] = 0x60;
649 driver->apps_rsp_buf[1] = 0x0;
650 driver->apps_rsp_buf[2] = 0x0;
651 ENCODE_RSP_AND_SEND(2);
652 return 0;
653 }
654#endif
655 }
656 /* Set log masks */
657 else if (*buf == 0x73 && *(int *)(buf+4) == 3) {
658 buf += 8;
659 /* Read Equip ID and pass as first param below*/
660 diag_update_log_mask(*(int *)buf, buf+8, *(int *)(buf+4));
661 diag_update_userspace_clients(LOG_MASKS_TYPE);
662#if defined(CONFIG_DIAG_OVER_USB)
663 /* Check for Apps Only */
664 if (!(driver->ch) && chk_apps_only()) {
665 /* echo response back for Apps only DIAG */
666 driver->apps_rsp_buf[0] = 0x73;
667 *(int *)(driver->apps_rsp_buf + 4) = 0x3; /* op. ID */
668 *(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success */
669 payload_length = 8 + ((*(int *)(buf + 4)) + 7)/8;
670 for (i = 0; i < payload_length; i++)
671 *(int *)(driver->apps_rsp_buf+12+i) =
672 *(buf+8+i);
673 ENCODE_RSP_AND_SEND(12 + payload_length - 1);
674 return 0;
675 }
676#endif
677 }
678 /* Check for set message mask */
679 else if ((*buf == 0x7d) && (*(buf+1) == 0x4)) {
680 ssid_first = *(uint16_t *)(buf + 2);
681 ssid_last = *(uint16_t *)(buf + 4);
682 ssid_range = 4 * (ssid_last - ssid_first + 1);
683 diag_update_msg_mask(ssid_first, ssid_last , buf + 8);
684 diag_update_userspace_clients(MSG_MASKS_TYPE);
685#if defined(CONFIG_DIAG_OVER_USB)
686 if (!(driver->ch) && chk_apps_only()) {
687 /* echo response back for apps only DIAG */
688 for (i = 0; i < 8 + ssid_range; i++)
689 *(driver->apps_rsp_buf + i) = *(buf+i);
690 ENCODE_RSP_AND_SEND(8 + ssid_range - 1);
691 return 0;
692 }
693#endif
694 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700695#if defined(CONFIG_DIAG_OVER_USB)
Shalabh Jainfb8e3c12011-10-19 17:29:42 -0700696 /* Check for Apps Only & get event mask request */
Shalabh Jain2c783cb2012-01-15 11:09:29 +0530697 else if (!(driver->ch) && chk_apps_only() && *buf == 0x81) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700698 driver->apps_rsp_buf[0] = 0x81;
699 driver->apps_rsp_buf[1] = 0x0;
700 *(uint16_t *)(driver->apps_rsp_buf + 2) = 0x0;
701 *(uint16_t *)(driver->apps_rsp_buf + 4) = EVENT_LAST_ID + 1;
702 for (i = 0; i < EVENT_LAST_ID/8 + 1; i++)
703 *(unsigned char *)(driver->apps_rsp_buf + 6 + i) = 0x0;
704 ENCODE_RSP_AND_SEND(6 + EVENT_LAST_ID/8);
705 return 0;
706 }
Shalabh Jainfb8e3c12011-10-19 17:29:42 -0700707 /* Get log ID range & Check for Apps Only */
708 else if (!(driver->ch) && chk_apps_only()
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700709 && (*buf == 0x73) && *(int *)(buf+4) == 1) {
710 driver->apps_rsp_buf[0] = 0x73;
711 *(int *)(driver->apps_rsp_buf + 4) = 0x1; /* operation ID */
712 *(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success code */
713 *(int *)(driver->apps_rsp_buf + 12) = LOG_GET_ITEM_NUM(LOG_0);
714 *(int *)(driver->apps_rsp_buf + 16) = LOG_GET_ITEM_NUM(LOG_1);
715 *(int *)(driver->apps_rsp_buf + 20) = LOG_GET_ITEM_NUM(LOG_2);
716 *(int *)(driver->apps_rsp_buf + 24) = LOG_GET_ITEM_NUM(LOG_3);
717 *(int *)(driver->apps_rsp_buf + 28) = LOG_GET_ITEM_NUM(LOG_4);
718 *(int *)(driver->apps_rsp_buf + 32) = LOG_GET_ITEM_NUM(LOG_5);
719 *(int *)(driver->apps_rsp_buf + 36) = LOG_GET_ITEM_NUM(LOG_6);
720 *(int *)(driver->apps_rsp_buf + 40) = LOG_GET_ITEM_NUM(LOG_7);
721 *(int *)(driver->apps_rsp_buf + 44) = LOG_GET_ITEM_NUM(LOG_8);
722 *(int *)(driver->apps_rsp_buf + 48) = LOG_GET_ITEM_NUM(LOG_9);
723 *(int *)(driver->apps_rsp_buf + 52) = LOG_GET_ITEM_NUM(LOG_10);
724 *(int *)(driver->apps_rsp_buf + 56) = LOG_GET_ITEM_NUM(LOG_11);
725 *(int *)(driver->apps_rsp_buf + 60) = LOG_GET_ITEM_NUM(LOG_12);
726 *(int *)(driver->apps_rsp_buf + 64) = LOG_GET_ITEM_NUM(LOG_13);
727 *(int *)(driver->apps_rsp_buf + 68) = LOG_GET_ITEM_NUM(LOG_14);
728 *(int *)(driver->apps_rsp_buf + 72) = LOG_GET_ITEM_NUM(LOG_15);
729 ENCODE_RSP_AND_SEND(75);
730 return 0;
731 }
732 /* Respond to Get SSID Range request message */
Shalabh Jainfb8e3c12011-10-19 17:29:42 -0700733 else if (!(driver->ch) && chk_apps_only()
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700734 && (*buf == 0x7d) && (*(buf+1) == 0x1)) {
735 driver->apps_rsp_buf[0] = 0x7d;
736 driver->apps_rsp_buf[1] = 0x1;
737 driver->apps_rsp_buf[2] = 0x1;
738 driver->apps_rsp_buf[3] = 0x0;
739 *(int *)(driver->apps_rsp_buf + 4) = MSG_MASK_TBL_CNT;
740 *(uint16_t *)(driver->apps_rsp_buf + 8) = MSG_SSID_0;
741 *(uint16_t *)(driver->apps_rsp_buf + 10) = MSG_SSID_0_LAST;
742 *(uint16_t *)(driver->apps_rsp_buf + 12) = MSG_SSID_1;
743 *(uint16_t *)(driver->apps_rsp_buf + 14) = MSG_SSID_1_LAST;
744 *(uint16_t *)(driver->apps_rsp_buf + 16) = MSG_SSID_2;
745 *(uint16_t *)(driver->apps_rsp_buf + 18) = MSG_SSID_2_LAST;
746 *(uint16_t *)(driver->apps_rsp_buf + 20) = MSG_SSID_3;
747 *(uint16_t *)(driver->apps_rsp_buf + 22) = MSG_SSID_3_LAST;
748 *(uint16_t *)(driver->apps_rsp_buf + 24) = MSG_SSID_4;
749 *(uint16_t *)(driver->apps_rsp_buf + 26) = MSG_SSID_4_LAST;
750 *(uint16_t *)(driver->apps_rsp_buf + 28) = MSG_SSID_5;
751 *(uint16_t *)(driver->apps_rsp_buf + 30) = MSG_SSID_5_LAST;
752 *(uint16_t *)(driver->apps_rsp_buf + 32) = MSG_SSID_6;
753 *(uint16_t *)(driver->apps_rsp_buf + 34) = MSG_SSID_6_LAST;
754 *(uint16_t *)(driver->apps_rsp_buf + 36) = MSG_SSID_7;
755 *(uint16_t *)(driver->apps_rsp_buf + 38) = MSG_SSID_7_LAST;
756 *(uint16_t *)(driver->apps_rsp_buf + 40) = MSG_SSID_8;
757 *(uint16_t *)(driver->apps_rsp_buf + 42) = MSG_SSID_8_LAST;
758 *(uint16_t *)(driver->apps_rsp_buf + 44) = MSG_SSID_9;
759 *(uint16_t *)(driver->apps_rsp_buf + 46) = MSG_SSID_9_LAST;
760 *(uint16_t *)(driver->apps_rsp_buf + 48) = MSG_SSID_10;
761 *(uint16_t *)(driver->apps_rsp_buf + 50) = MSG_SSID_10_LAST;
762 *(uint16_t *)(driver->apps_rsp_buf + 52) = MSG_SSID_11;
763 *(uint16_t *)(driver->apps_rsp_buf + 54) = MSG_SSID_11_LAST;
764 *(uint16_t *)(driver->apps_rsp_buf + 56) = MSG_SSID_12;
765 *(uint16_t *)(driver->apps_rsp_buf + 58) = MSG_SSID_12_LAST;
766 *(uint16_t *)(driver->apps_rsp_buf + 60) = MSG_SSID_13;
767 *(uint16_t *)(driver->apps_rsp_buf + 62) = MSG_SSID_13_LAST;
768 *(uint16_t *)(driver->apps_rsp_buf + 64) = MSG_SSID_14;
769 *(uint16_t *)(driver->apps_rsp_buf + 66) = MSG_SSID_14_LAST;
770 *(uint16_t *)(driver->apps_rsp_buf + 68) = MSG_SSID_15;
771 *(uint16_t *)(driver->apps_rsp_buf + 70) = MSG_SSID_15_LAST;
772 *(uint16_t *)(driver->apps_rsp_buf + 72) = MSG_SSID_16;
773 *(uint16_t *)(driver->apps_rsp_buf + 74) = MSG_SSID_16_LAST;
774 *(uint16_t *)(driver->apps_rsp_buf + 76) = MSG_SSID_17;
775 *(uint16_t *)(driver->apps_rsp_buf + 78) = MSG_SSID_17_LAST;
776 *(uint16_t *)(driver->apps_rsp_buf + 80) = MSG_SSID_18;
777 *(uint16_t *)(driver->apps_rsp_buf + 82) = MSG_SSID_18_LAST;
778 ENCODE_RSP_AND_SEND(83);
779 return 0;
780 }
Shalabh Jainfb8e3c12011-10-19 17:29:42 -0700781 /* Check for Apps Only Respond to Get Subsys Build mask */
782 else if (!(driver->ch) && chk_apps_only()
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700783 && (*buf == 0x7d) && (*(buf+1) == 0x2)) {
784 ssid_first = *(uint16_t *)(buf + 2);
785 ssid_last = *(uint16_t *)(buf + 4);
786 ssid_range = 4 * (ssid_last - ssid_first + 1);
787 /* frame response */
788 driver->apps_rsp_buf[0] = 0x7d;
789 driver->apps_rsp_buf[1] = 0x2;
790 *(uint16_t *)(driver->apps_rsp_buf + 2) = ssid_first;
791 *(uint16_t *)(driver->apps_rsp_buf + 4) = ssid_last;
792 driver->apps_rsp_buf[6] = 0x1;
793 driver->apps_rsp_buf[7] = 0x0;
794 ptr = driver->apps_rsp_buf + 8;
795 /* bld time masks */
796 switch (ssid_first) {
797 case MSG_SSID_0:
798 for (i = 0; i < ssid_range; i += 4)
799 *(int *)(ptr + i) = msg_bld_masks_0[i/4];
800 break;
801 case MSG_SSID_1:
802 for (i = 0; i < ssid_range; i += 4)
803 *(int *)(ptr + i) = msg_bld_masks_1[i/4];
804 break;
805 case MSG_SSID_2:
806 for (i = 0; i < ssid_range; i += 4)
807 *(int *)(ptr + i) = msg_bld_masks_2[i/4];
808 break;
809 case MSG_SSID_3:
810 for (i = 0; i < ssid_range; i += 4)
811 *(int *)(ptr + i) = msg_bld_masks_3[i/4];
812 break;
813 case MSG_SSID_4:
814 for (i = 0; i < ssid_range; i += 4)
815 *(int *)(ptr + i) = msg_bld_masks_4[i/4];
816 break;
817 case MSG_SSID_5:
818 for (i = 0; i < ssid_range; i += 4)
819 *(int *)(ptr + i) = msg_bld_masks_5[i/4];
820 break;
821 case MSG_SSID_6:
822 for (i = 0; i < ssid_range; i += 4)
823 *(int *)(ptr + i) = msg_bld_masks_6[i/4];
824 break;
825 case MSG_SSID_7:
826 for (i = 0; i < ssid_range; i += 4)
827 *(int *)(ptr + i) = msg_bld_masks_7[i/4];
828 break;
829 case MSG_SSID_8:
830 for (i = 0; i < ssid_range; i += 4)
831 *(int *)(ptr + i) = msg_bld_masks_8[i/4];
832 break;
833 case MSG_SSID_9:
834 for (i = 0; i < ssid_range; i += 4)
835 *(int *)(ptr + i) = msg_bld_masks_9[i/4];
836 break;
837 case MSG_SSID_10:
838 for (i = 0; i < ssid_range; i += 4)
839 *(int *)(ptr + i) = msg_bld_masks_10[i/4];
840 break;
841 case MSG_SSID_11:
842 for (i = 0; i < ssid_range; i += 4)
843 *(int *)(ptr + i) = msg_bld_masks_11[i/4];
844 break;
845 case MSG_SSID_12:
846 for (i = 0; i < ssid_range; i += 4)
847 *(int *)(ptr + i) = msg_bld_masks_12[i/4];
848 break;
849 case MSG_SSID_13:
850 for (i = 0; i < ssid_range; i += 4)
851 *(int *)(ptr + i) = msg_bld_masks_13[i/4];
852 break;
853 case MSG_SSID_14:
854 for (i = 0; i < ssid_range; i += 4)
855 *(int *)(ptr + i) = msg_bld_masks_14[i/4];
856 break;
857 case MSG_SSID_15:
858 for (i = 0; i < ssid_range; i += 4)
859 *(int *)(ptr + i) = msg_bld_masks_15[i/4];
860 break;
861 case MSG_SSID_16:
862 for (i = 0; i < ssid_range; i += 4)
863 *(int *)(ptr + i) = msg_bld_masks_16[i/4];
864 break;
865 case MSG_SSID_17:
866 for (i = 0; i < ssid_range; i += 4)
867 *(int *)(ptr + i) = msg_bld_masks_17[i/4];
868 break;
869 case MSG_SSID_18:
870 for (i = 0; i < ssid_range; i += 4)
871 *(int *)(ptr + i) = msg_bld_masks_18[i/4];
872 break;
873 }
874 ENCODE_RSP_AND_SEND(8 + ssid_range - 1);
875 return 0;
876 }
877 /* Check for download command */
Shalabh Jain10f5f432012-01-11 11:45:44 +0530878 else if ((cpu_is_msm8x60() || chk_apps_master()) && (*buf == 0x3A)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700879 /* send response back */
880 driver->apps_rsp_buf[0] = *buf;
881 ENCODE_RSP_AND_SEND(0);
882 msleep(5000);
883 /* call download API */
884 msm_set_restart_mode(RESTART_DLOAD);
885 printk(KERN_CRIT "diag: download mode set, Rebooting SoC..\n");
886 kernel_restart(NULL);
887 /* Not required, represents that command isnt sent to modem */
888 return 0;
889 }
Dixon Petersonb46bb992012-01-12 19:16:56 -0800890 /* Check for polling for Apps only DIAG */
891 else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
892 (*(buf+2) == 0x03)) {
893 /* If there is NO MODEM present */
894 if (!(driver->ch)) {
895 /* Respond to polling for Apps only DIAG */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700896 for (i = 0; i < 3; i++)
897 driver->apps_rsp_buf[i] = *(buf+i);
898 for (i = 0; i < 13; i++)
899 driver->apps_rsp_buf[i+3] = 0;
900
901 ENCODE_RSP_AND_SEND(15);
902 return 0;
Dixon Petersonb46bb992012-01-12 19:16:56 -0800903 } else {
904 /* Since Modem is present, send error response */
905 return 1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700906 }
Dixon Petersonb46bb992012-01-12 19:16:56 -0800907 }
908 /* Check for ID for NO MODEM present */
909 else if (!(driver->ch)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700910 /* respond to 0x0 command */
Dixon Petersonb46bb992012-01-12 19:16:56 -0800911 if (*buf == 0x00) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700912 for (i = 0; i < 55; i++)
913 driver->apps_rsp_buf[i] = 0;
914
915 ENCODE_RSP_AND_SEND(54);
916 return 0;
917 }
918 /* respond to 0x7c command */
919 else if (*buf == 0x7c) {
920 driver->apps_rsp_buf[0] = 0x7c;
921 for (i = 1; i < 8; i++)
922 driver->apps_rsp_buf[i] = 0;
923 /* Tools ID for APQ 8060 */
924 *(int *)(driver->apps_rsp_buf + 8) =
925 chk_config_get_id();
926 *(unsigned char *)(driver->apps_rsp_buf + 12) = '\0';
927 *(unsigned char *)(driver->apps_rsp_buf + 13) = '\0';
928 ENCODE_RSP_AND_SEND(13);
929 return 0;
930 }
931 }
932#endif
933 return packet_type;
934}
935
936#ifdef CONFIG_DIAG_OVER_USB
937void diag_send_error_rsp(int index)
938{
939 int i;
Shalabh Jain1fedab92011-12-22 13:15:22 +0530940
941 if (index > 490) {
942 pr_err("diag: error response too huge, aborting\n");
943 return;
944 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700945 driver->apps_rsp_buf[0] = 0x13; /* error code 13 */
946 for (i = 0; i < index; i++)
947 driver->apps_rsp_buf[i+1] = *(driver->hdlc_buf+i);
948 ENCODE_RSP_AND_SEND(index - 3);
949}
950#else
951static inline void diag_send_error_rsp(int index) {}
952#endif
953
954void diag_process_hdlc(void *data, unsigned len)
955{
956 struct diag_hdlc_decode_type hdlc;
957 int ret, type = 0;
958 pr_debug("diag: HDLC decode fn, len of data %d\n", len);
959 hdlc.dest_ptr = driver->hdlc_buf;
960 hdlc.dest_size = USB_MAX_OUT_BUF;
961 hdlc.src_ptr = data;
962 hdlc.src_size = len;
963 hdlc.src_idx = 0;
964 hdlc.dest_idx = 0;
965 hdlc.escaping = 0;
966
967 ret = diag_hdlc_decode(&hdlc);
968
969 if (ret)
970 type = diag_process_apps_pkt(driver->hdlc_buf,
971 hdlc.dest_idx - 3);
972 else if (driver->debug_flag) {
973 printk(KERN_ERR "Packet dropped due to bad HDLC coding/CRC"
974 " errors or partial packet received, packet"
975 " length = %d\n", len);
976 print_hex_dump(KERN_DEBUG, "Dropped Packet Data: ", 16, 1,
977 DUMP_PREFIX_ADDRESS, data, len, 1);
978 driver->debug_flag = 0;
979 }
980 /* send error responses from APPS for Central Routing */
Shalabh Jainfb8e3c12011-10-19 17:29:42 -0700981 if (type == 1 && chk_apps_only()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700982 diag_send_error_rsp(hdlc.dest_idx);
983 type = 0;
984 }
985 /* implies this packet is NOT meant for apps */
986 if (!(driver->ch) && type == 1) {
Shalabh Jainfb8e3c12011-10-19 17:29:42 -0700987 if (chk_apps_only()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700988 diag_send_error_rsp(hdlc.dest_idx);
989 } else { /* APQ 8060, Let Q6 respond */
990 if (driver->chqdsp)
991 smd_write(driver->chqdsp, driver->hdlc_buf,
992 hdlc.dest_idx - 3);
993 }
994 type = 0;
995 }
996
997#ifdef DIAG_DEBUG
998 pr_debug("diag: hdlc.dest_idx = %d", hdlc.dest_idx);
999 for (i = 0; i < hdlc.dest_idx; i++)
1000 printk(KERN_DEBUG "\t%x", *(((unsigned char *)
1001 driver->hdlc_buf)+i));
1002#endif /* DIAG DEBUG */
1003 /* ignore 2 bytes for CRC, one for 7E and send */
1004 if ((driver->ch) && (ret) && (type) && (hdlc.dest_idx > 3)) {
1005 APPEND_DEBUG('g');
1006 smd_write(driver->ch, driver->hdlc_buf, hdlc.dest_idx - 3);
1007 APPEND_DEBUG('h');
1008#ifdef DIAG_DEBUG
1009 printk(KERN_INFO "writing data to SMD, pkt length %d\n", len);
1010 print_hex_dump(KERN_DEBUG, "Written Packet Data to SMD: ", 16,
1011 1, DUMP_PREFIX_ADDRESS, data, len, 1);
1012#endif /* DIAG DEBUG */
1013 }
1014}
1015
1016#ifdef CONFIG_DIAG_OVER_USB
Shalabh Jain8e9750a2011-09-09 13:06:29 -07001017/* 2+1 for modem ; 2 for LPASS ; 1 for WCNSS */
1018#define N_LEGACY_WRITE (driver->poolsize + 6)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001019#define N_LEGACY_READ 1
1020
1021int diagfwd_connect(void)
1022{
1023 int err;
1024
1025 printk(KERN_DEBUG "diag: USB connected\n");
1026 err = usb_diag_alloc_req(driver->legacy_ch, N_LEGACY_WRITE,
1027 N_LEGACY_READ);
1028 if (err)
1029 printk(KERN_ERR "diag: unable to alloc USB req on legacy ch");
1030
1031 driver->usb_connected = 1;
1032 driver->in_busy_1 = 0;
1033 driver->in_busy_2 = 0;
1034 driver->in_busy_qdsp_1 = 0;
1035 driver->in_busy_qdsp_2 = 0;
1036 driver->in_busy_wcnss = 0;
1037
1038 /* Poll SMD channels to check for data*/
1039 queue_work(driver->diag_wq, &(driver->diag_read_smd_work));
1040 queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work));
1041 queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work));
Shalabh Jaincf5f20e2011-08-22 12:29:52 -07001042 /* Poll SMD CNTL channels to check for data */
1043 queue_work(driver->diag_wq, &(driver->diag_read_smd_cntl_work));
1044 queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_cntl_work));
1045 queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_cntl_work));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001046 /* Poll USB channel to check for data*/
1047 queue_work(driver->diag_wq, &(driver->diag_read_work));
1048#ifdef CONFIG_DIAG_SDIO_PIPE
1049 if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa()) {
1050 if (driver->mdm_ch && !IS_ERR(driver->mdm_ch))
1051 diagfwd_connect_sdio();
1052 else
1053 printk(KERN_INFO "diag: No USB MDM ch");
1054 }
1055#endif
1056 return 0;
1057}
1058
1059int diagfwd_disconnect(void)
1060{
1061 printk(KERN_DEBUG "diag: USB disconnected\n");
1062 driver->usb_connected = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001063 driver->debug_flag = 1;
1064 usb_diag_free_req(driver->legacy_ch);
Shalabh Jain69890aa2011-10-10 12:59:16 -07001065 if (driver->logging_mode == USB_MODE) {
1066 driver->in_busy_1 = 1;
1067 driver->in_busy_2 = 1;
1068 driver->in_busy_qdsp_1 = 1;
1069 driver->in_busy_qdsp_2 = 1;
1070 driver->in_busy_wcnss = 1;
1071 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001072#ifdef CONFIG_DIAG_SDIO_PIPE
1073 if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
1074 if (driver->mdm_ch && !IS_ERR(driver->mdm_ch))
1075 diagfwd_disconnect_sdio();
1076#endif
1077 /* TBD - notify and flow control SMD */
1078 return 0;
1079}
1080
1081int diagfwd_write_complete(struct diag_request *diag_write_ptr)
1082{
1083 unsigned char *buf = diag_write_ptr->buf;
1084 /*Determine if the write complete is for data from modem/apps/q6 */
1085 /* Need a context variable here instead */
1086 if (buf == (void *)driver->buf_in_1) {
1087 driver->in_busy_1 = 0;
1088 APPEND_DEBUG('o');
1089 queue_work(driver->diag_wq, &(driver->diag_read_smd_work));
1090 } else if (buf == (void *)driver->buf_in_2) {
1091 driver->in_busy_2 = 0;
1092 APPEND_DEBUG('O');
1093 queue_work(driver->diag_wq, &(driver->diag_read_smd_work));
1094 } else if (buf == (void *)driver->buf_in_qdsp_1) {
1095 driver->in_busy_qdsp_1 = 0;
1096 APPEND_DEBUG('p');
1097 queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work));
1098 } else if (buf == (void *)driver->buf_in_qdsp_2) {
1099 driver->in_busy_qdsp_2 = 0;
1100 APPEND_DEBUG('P');
1101 queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work));
1102 } else if (buf == (void *)driver->buf_in_wcnss) {
1103 driver->in_busy_wcnss = 0;
1104 APPEND_DEBUG('R');
1105 queue_work(driver->diag_wq,
1106 &(driver->diag_read_smd_wcnss_work));
1107 }
1108#ifdef CONFIG_DIAG_SDIO_PIPE
1109 else if (buf == (void *)driver->buf_in_sdio)
1110 if (machine_is_msm8x60_fusion() ||
Shalabh Jain482bf122011-12-06 03:54:47 -08001111 machine_is_msm8x60_fusn_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001112 diagfwd_write_complete_sdio();
1113 else
1114 pr_err("diag: Incorrect buffer pointer while WRITE");
1115#endif
1116 else {
1117 diagmem_free(driver, (unsigned char *)buf, POOL_TYPE_HDLC);
1118 diagmem_free(driver, (unsigned char *)diag_write_ptr,
1119 POOL_TYPE_WRITE_STRUCT);
1120 APPEND_DEBUG('q');
1121 }
1122 return 0;
1123}
1124
1125int diagfwd_read_complete(struct diag_request *diag_read_ptr)
1126{
1127 int status = diag_read_ptr->status;
1128 unsigned char *buf = diag_read_ptr->buf;
1129
1130 /* Determine if the read complete is for data on legacy/mdm ch */
1131 if (buf == (void *)driver->usb_buf_out) {
1132 driver->read_len_legacy = diag_read_ptr->actual;
1133 APPEND_DEBUG('s');
1134#ifdef DIAG_DEBUG
1135 printk(KERN_INFO "read data from USB, pkt length %d",
1136 diag_read_ptr->actual);
1137 print_hex_dump(KERN_DEBUG, "Read Packet Data from USB: ", 16, 1,
1138 DUMP_PREFIX_ADDRESS, diag_read_ptr->buf,
1139 diag_read_ptr->actual, 1);
1140#endif /* DIAG DEBUG */
1141 if (driver->logging_mode == USB_MODE) {
1142 if (status != -ECONNRESET && status != -ESHUTDOWN)
1143 queue_work(driver->diag_wq,
1144 &(driver->diag_proc_hdlc_work));
1145 else
1146 queue_work(driver->diag_wq,
1147 &(driver->diag_read_work));
1148 }
1149 }
1150#ifdef CONFIG_DIAG_SDIO_PIPE
1151 else if (buf == (void *)driver->usb_buf_mdm_out) {
1152 if (machine_is_msm8x60_fusion() ||
Shalabh Jain482bf122011-12-06 03:54:47 -08001153 machine_is_msm8x60_fusn_ffa()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001154 driver->read_len_mdm = diag_read_ptr->actual;
1155 diagfwd_read_complete_sdio();
1156 } else
1157 pr_err("diag: Incorrect buffer pointer while READ");
1158 }
1159#endif
1160 else
1161 printk(KERN_ERR "diag: Unknown buffer ptr from USB");
1162
1163 return 0;
1164}
1165
1166void diag_read_work_fn(struct work_struct *work)
1167{
1168 APPEND_DEBUG('d');
1169 driver->usb_read_ptr->buf = driver->usb_buf_out;
1170 driver->usb_read_ptr->length = USB_MAX_OUT_BUF;
1171 usb_diag_read(driver->legacy_ch, driver->usb_read_ptr);
1172 APPEND_DEBUG('e');
1173}
1174
1175void diag_process_hdlc_fn(struct work_struct *work)
1176{
1177 APPEND_DEBUG('D');
1178 diag_process_hdlc(driver->usb_buf_out, driver->read_len_legacy);
1179 diag_read_work_fn(work);
1180 APPEND_DEBUG('E');
1181}
1182
1183void diag_usb_legacy_notifier(void *priv, unsigned event,
1184 struct diag_request *d_req)
1185{
1186 switch (event) {
1187 case USB_DIAG_CONNECT:
1188 diagfwd_connect();
1189 break;
1190 case USB_DIAG_DISCONNECT:
1191 diagfwd_disconnect();
1192 break;
1193 case USB_DIAG_READ_DONE:
1194 diagfwd_read_complete(d_req);
1195 break;
1196 case USB_DIAG_WRITE_DONE:
1197 diagfwd_write_complete(d_req);
1198 break;
1199 default:
1200 printk(KERN_ERR "Unknown event from USB diag\n");
1201 break;
1202 }
1203}
1204
1205#endif /* DIAG OVER USB */
1206
1207static void diag_smd_notify(void *ctxt, unsigned event)
1208{
Shalabh Jainc2ec8292011-10-14 12:34:55 -07001209 if (event == SMD_EVENT_CLOSE) {
1210 pr_info("diag: clean modem registration\n");
1211 diag_clear_reg(MODEM_PROC);
Shalabh Jaineefee052011-11-08 23:46:03 -08001212 driver->ch = 0;
1213 return;
1214 } else if (event == SMD_EVENT_OPEN) {
1215 driver->ch = ch_temp;
1216 }
1217 queue_work(driver->diag_wq, &(driver->diag_read_smd_work));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001218}
1219
1220#if defined(CONFIG_MSM_N_WAY_SMD)
1221static void diag_smd_qdsp_notify(void *ctxt, unsigned event)
1222{
Shalabh Jainc6c2b1d2011-12-20 04:32:34 -08001223 if (event == SMD_EVENT_CLOSE) {
1224 pr_info("diag: clean lpass registration\n");
1225 diag_clear_reg(QDSP_PROC);
1226 driver->chqdsp = 0;
1227 return;
1228 } else if (event == SMD_EVENT_OPEN) {
1229 driver->chqdsp = chqdsp_temp;
1230 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001231 queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work));
1232}
1233#endif
1234
1235static void diag_smd_wcnss_notify(void *ctxt, unsigned event)
1236{
Shalabh Jainc6c2b1d2011-12-20 04:32:34 -08001237 if (event == SMD_EVENT_CLOSE) {
1238 pr_info("diag: clean wcnss registration\n");
1239 diag_clear_reg(WCNSS_PROC);
1240 driver->ch_wcnss = 0;
1241 return;
1242 } else if (event == SMD_EVENT_OPEN) {
1243 driver->ch_wcnss = ch_wcnss_temp;
1244 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001245 queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work));
1246}
1247
1248static int diag_smd_probe(struct platform_device *pdev)
1249{
1250 int r = 0;
1251
Shalabh Jaineefee052011-11-08 23:46:03 -08001252 if (pdev->id == SMD_APPS_MODEM) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001253 r = smd_open("DIAG", &driver->ch, driver, diag_smd_notify);
Shalabh Jaineefee052011-11-08 23:46:03 -08001254 ch_temp = driver->ch;
1255 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001256#if defined(CONFIG_MSM_N_WAY_SMD)
Shalabh Jainc6c2b1d2011-12-20 04:32:34 -08001257 if (pdev->id == SMD_APPS_QDSP) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001258 r = smd_named_open_on_edge("DIAG", SMD_APPS_QDSP
1259 , &driver->chqdsp, driver, diag_smd_qdsp_notify);
Shalabh Jainc6c2b1d2011-12-20 04:32:34 -08001260 chqdsp_temp = driver->chqdsp;
1261 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001262#endif
Shalabh Jainc6c2b1d2011-12-20 04:32:34 -08001263 if (pdev->id == SMD_APPS_WCNSS) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001264 r = smd_named_open_on_edge("APPS_RIVA_DATA", SMD_APPS_WCNSS
1265 , &driver->ch_wcnss, driver, diag_smd_wcnss_notify);
Shalabh Jainc6c2b1d2011-12-20 04:32:34 -08001266 ch_wcnss_temp = driver->ch_wcnss;
1267 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001268 pm_runtime_set_active(&pdev->dev);
1269 pm_runtime_enable(&pdev->dev);
1270 pr_debug("diag: open SMD port, Id = %d, r = %d\n", pdev->id, r);
1271
1272 return 0;
1273}
1274
1275static int diagfwd_runtime_suspend(struct device *dev)
1276{
1277 dev_dbg(dev, "pm_runtime: suspending...\n");
1278 return 0;
1279}
1280
1281static int diagfwd_runtime_resume(struct device *dev)
1282{
1283 dev_dbg(dev, "pm_runtime: resuming...\n");
1284 return 0;
1285}
1286
1287static const struct dev_pm_ops diagfwd_dev_pm_ops = {
1288 .runtime_suspend = diagfwd_runtime_suspend,
1289 .runtime_resume = diagfwd_runtime_resume,
1290};
1291
1292static struct platform_driver msm_smd_ch1_driver = {
1293
1294 .probe = diag_smd_probe,
1295 .driver = {
1296 .name = "DIAG",
1297 .owner = THIS_MODULE,
1298 .pm = &diagfwd_dev_pm_ops,
1299 },
1300};
1301
1302static struct platform_driver diag_smd_lite_driver = {
1303
1304 .probe = diag_smd_probe,
1305 .driver = {
1306 .name = "APPS_RIVA_DATA",
1307 .owner = THIS_MODULE,
1308 .pm = &diagfwd_dev_pm_ops,
1309 },
1310};
1311
1312void diagfwd_init(void)
1313{
1314 diag_debug_buf_idx = 0;
1315 driver->read_len_legacy = 0;
1316 if (driver->buf_in_1 == NULL) {
1317 driver->buf_in_1 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
1318 if (driver->buf_in_1 == NULL)
1319 goto err;
1320 }
1321 if (driver->buf_in_2 == NULL) {
1322 driver->buf_in_2 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
1323 if (driver->buf_in_2 == NULL)
1324 goto err;
1325 }
1326 if (driver->buf_in_qdsp_1 == NULL) {
1327 driver->buf_in_qdsp_1 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
1328 if (driver->buf_in_qdsp_1 == NULL)
1329 goto err;
1330 }
1331 if (driver->buf_in_qdsp_2 == NULL) {
1332 driver->buf_in_qdsp_2 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
1333 if (driver->buf_in_qdsp_2 == NULL)
1334 goto err;
1335 }
1336 if (driver->buf_in_wcnss == NULL) {
1337 driver->buf_in_wcnss = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
1338 if (driver->buf_in_wcnss == NULL)
1339 goto err;
1340 }
1341 if (driver->usb_buf_out == NULL &&
1342 (driver->usb_buf_out = kzalloc(USB_MAX_OUT_BUF,
1343 GFP_KERNEL)) == NULL)
1344 goto err;
1345 if (driver->hdlc_buf == NULL
1346 && (driver->hdlc_buf = kzalloc(HDLC_MAX, GFP_KERNEL)) == NULL)
1347 goto err;
Shalabh Jain69890aa2011-10-10 12:59:16 -07001348 if (driver->user_space_data == NULL)
1349 driver->user_space_data = kzalloc(USER_SPACE_DATA, GFP_KERNEL);
1350 if (driver->user_space_data == NULL)
1351 goto err;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001352 if (driver->msg_masks == NULL
1353 && (driver->msg_masks = kzalloc(MSG_MASK_SIZE,
1354 GFP_KERNEL)) == NULL)
1355 goto err;
1356 if (driver->log_masks == NULL &&
1357 (driver->log_masks = kzalloc(LOG_MASK_SIZE, GFP_KERNEL)) == NULL)
1358 goto err;
1359 driver->log_masks_length = 8*MAX_EQUIP_ID;
1360 if (driver->event_masks == NULL &&
1361 (driver->event_masks = kzalloc(EVENT_MASK_SIZE,
1362 GFP_KERNEL)) == NULL)
1363 goto err;
1364 if (driver->client_map == NULL &&
1365 (driver->client_map = kzalloc
1366 ((driver->num_clients) * sizeof(struct diag_client_map),
1367 GFP_KERNEL)) == NULL)
1368 goto err;
1369 if (driver->buf_tbl == NULL)
1370 driver->buf_tbl = kzalloc(buf_tbl_size *
1371 sizeof(struct diag_write_device), GFP_KERNEL);
1372 if (driver->buf_tbl == NULL)
1373 goto err;
1374 if (driver->data_ready == NULL &&
1375 (driver->data_ready = kzalloc(driver->num_clients * sizeof(int)
1376 , GFP_KERNEL)) == NULL)
1377 goto err;
1378 if (driver->table == NULL &&
1379 (driver->table = kzalloc(diag_max_registration*
1380 sizeof(struct diag_master_table),
1381 GFP_KERNEL)) == NULL)
1382 goto err;
1383 if (driver->write_ptr_1 == NULL) {
1384 driver->write_ptr_1 = kzalloc(
1385 sizeof(struct diag_request), GFP_KERNEL);
1386 if (driver->write_ptr_1 == NULL)
1387 goto err;
1388 }
1389 if (driver->write_ptr_2 == NULL) {
1390 driver->write_ptr_2 = kzalloc(
1391 sizeof(struct diag_request), GFP_KERNEL);
1392 if (driver->write_ptr_2 == NULL)
1393 goto err;
1394 }
1395 if (driver->write_ptr_qdsp_1 == NULL) {
1396 driver->write_ptr_qdsp_1 = kzalloc(
1397 sizeof(struct diag_request), GFP_KERNEL);
1398 if (driver->write_ptr_qdsp_1 == NULL)
1399 goto err;
1400 }
1401 if (driver->write_ptr_qdsp_2 == NULL) {
1402 driver->write_ptr_qdsp_2 = kzalloc(
1403 sizeof(struct diag_request), GFP_KERNEL);
1404 if (driver->write_ptr_qdsp_2 == NULL)
1405 goto err;
1406 }
1407 if (driver->write_ptr_wcnss == NULL) {
1408 driver->write_ptr_wcnss = kzalloc(
1409 sizeof(struct diag_request), GFP_KERNEL);
1410 if (driver->write_ptr_wcnss == NULL)
1411 goto err;
1412 }
1413 if (driver->usb_read_ptr == NULL) {
1414 driver->usb_read_ptr = kzalloc(
1415 sizeof(struct diag_request), GFP_KERNEL);
1416 if (driver->usb_read_ptr == NULL)
1417 goto err;
1418 }
1419 if (driver->pkt_buf == NULL &&
1420 (driver->pkt_buf = kzalloc(PKT_SIZE,
1421 GFP_KERNEL)) == NULL)
1422 goto err;
1423 if (driver->apps_rsp_buf == NULL) {
1424 driver->apps_rsp_buf = kzalloc(500, GFP_KERNEL);
1425 if (driver->apps_rsp_buf == NULL)
1426 goto err;
1427 }
1428 driver->diag_wq = create_singlethread_workqueue("diag_wq");
1429#ifdef CONFIG_DIAG_OVER_USB
1430 INIT_WORK(&(driver->diag_proc_hdlc_work), diag_process_hdlc_fn);
1431 INIT_WORK(&(driver->diag_read_work), diag_read_work_fn);
1432 driver->legacy_ch = usb_diag_open(DIAG_LEGACY, driver,
1433 diag_usb_legacy_notifier);
1434 if (IS_ERR(driver->legacy_ch)) {
1435 printk(KERN_ERR "Unable to open USB diag legacy channel\n");
1436 goto err;
1437 }
1438#endif
1439 platform_driver_register(&msm_smd_ch1_driver);
1440 platform_driver_register(&diag_smd_lite_driver);
1441
1442 return;
1443err:
1444 pr_err("diag: Could not initialize diag buffers");
1445 kfree(driver->buf_in_1);
1446 kfree(driver->buf_in_2);
1447 kfree(driver->buf_in_qdsp_1);
1448 kfree(driver->buf_in_qdsp_2);
1449 kfree(driver->buf_in_wcnss);
1450 kfree(driver->usb_buf_out);
1451 kfree(driver->hdlc_buf);
1452 kfree(driver->msg_masks);
1453 kfree(driver->log_masks);
1454 kfree(driver->event_masks);
1455 kfree(driver->client_map);
1456 kfree(driver->buf_tbl);
1457 kfree(driver->data_ready);
1458 kfree(driver->table);
1459 kfree(driver->pkt_buf);
1460 kfree(driver->write_ptr_1);
1461 kfree(driver->write_ptr_2);
1462 kfree(driver->write_ptr_qdsp_1);
1463 kfree(driver->write_ptr_qdsp_2);
1464 kfree(driver->write_ptr_wcnss);
1465 kfree(driver->usb_read_ptr);
1466 kfree(driver->apps_rsp_buf);
Shalabh Jain69890aa2011-10-10 12:59:16 -07001467 kfree(driver->user_space_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001468 if (driver->diag_wq)
1469 destroy_workqueue(driver->diag_wq);
1470}
1471
1472void diagfwd_exit(void)
1473{
1474 smd_close(driver->ch);
1475 smd_close(driver->chqdsp);
1476 smd_close(driver->ch_wcnss);
1477 driver->ch = 0; /* SMD can make this NULL */
1478 driver->chqdsp = 0;
1479 driver->ch_wcnss = 0;
1480#ifdef CONFIG_DIAG_OVER_USB
1481 if (driver->usb_connected)
1482 usb_diag_free_req(driver->legacy_ch);
1483 usb_diag_close(driver->legacy_ch);
1484#endif
1485 platform_driver_unregister(&msm_smd_ch1_driver);
1486 platform_driver_unregister(&diag_smd_lite_driver);
1487 kfree(driver->buf_in_1);
1488 kfree(driver->buf_in_2);
1489 kfree(driver->buf_in_qdsp_1);
1490 kfree(driver->buf_in_qdsp_2);
1491 kfree(driver->buf_in_wcnss);
1492 kfree(driver->usb_buf_out);
1493 kfree(driver->hdlc_buf);
1494 kfree(driver->msg_masks);
1495 kfree(driver->log_masks);
1496 kfree(driver->event_masks);
1497 kfree(driver->client_map);
1498 kfree(driver->buf_tbl);
1499 kfree(driver->data_ready);
1500 kfree(driver->table);
1501 kfree(driver->pkt_buf);
1502 kfree(driver->write_ptr_1);
1503 kfree(driver->write_ptr_2);
1504 kfree(driver->write_ptr_qdsp_1);
1505 kfree(driver->write_ptr_qdsp_2);
1506 kfree(driver->write_ptr_wcnss);
1507 kfree(driver->usb_read_ptr);
1508 kfree(driver->apps_rsp_buf);
Shalabh Jain69890aa2011-10-10 12:59:16 -07001509 kfree(driver->user_space_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001510 destroy_workqueue(driver->diag_wq);
1511}