/drivers/char/diag/diagfwd.c

https://bitbucket.org/cresqo/cm7-p500-kernel · C · 1030 lines · 912 code · 73 blank · 45 comment · 273 complexity · 533b87e5570b9861cd39246cea6157c9 MD5 · raw file

  1. /* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
  2. *
  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. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program; if not, write to the Free Software
  14. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. * 02110-1301, USA.
  16. *
  17. */
  18. #include <linux/slab.h>
  19. #include <linux/init.h>
  20. #include <linux/module.h>
  21. #include <linux/device.h>
  22. #include <linux/err.h>
  23. #include <linux/platform_device.h>
  24. #include <linux/sched.h>
  25. #include <linux/workqueue.h>
  26. #include <linux/pm_runtime.h>
  27. #include <linux/diagchar.h>
  28. #ifdef CONFIG_DIAG_OVER_USB
  29. #include <mach/usbdiag.h>
  30. #endif
  31. #include <mach/msm_smd.h>
  32. #include <mach/socinfo.h>
  33. #include "diagmem.h"
  34. #include "diagchar.h"
  35. #include "diagfwd.h"
  36. #include "diagchar_hdlc.h"
  37. #ifdef CONFIG_DIAG_SDIO_PIPE
  38. #include "diagfwd_sdio.h"
  39. #endif
  40. MODULE_DESCRIPTION("Diag Char Driver");
  41. MODULE_LICENSE("GPL v2");
  42. MODULE_VERSION("1.0");
  43. int diag_debug_buf_idx;
  44. unsigned char diag_debug_buf[1024];
  45. static unsigned int buf_tbl_size = 8; /*Number of entries in table of buffers */
  46. struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 };
  47. struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
  48. #define ENCODE_RSP_AND_SEND(buf_length) \
  49. do { \
  50. send.state = DIAG_STATE_START; \
  51. send.pkt = driver->apps_rsp_buf; \
  52. send.last = (void *)(driver->apps_rsp_buf + buf_length); \
  53. send.terminate = 1; \
  54. if (!driver->in_busy_1) { \
  55. enc.dest = driver->buf_in_1; \
  56. enc.dest_last = (void *)(driver->buf_in_1 + 499); \
  57. diag_hdlc_encode(&send, &enc); \
  58. driver->write_ptr_1->buf = driver->buf_in_1; \
  59. driver->write_ptr_1->length = buf_length + 4; \
  60. usb_diag_write(driver->legacy_ch, driver->write_ptr_1); \
  61. } \
  62. } while (0)
  63. #define CHK_OVERFLOW(bufStart, start, end, length) \
  64. ((bufStart <= start) && (end - start >= length)) ? 1 : 0
  65. #define CHK_APQ_GET_ID() \
  66. (socinfo_get_id() == 86) ? 4062 : 0
  67. void __diag_smd_send_req(void)
  68. {
  69. void *buf = NULL;
  70. int *in_busy_ptr = NULL;
  71. struct diag_request *write_ptr_modem = NULL;
  72. if (!driver->in_busy_1) {
  73. buf = driver->buf_in_1;
  74. write_ptr_modem = driver->write_ptr_1;
  75. in_busy_ptr = &(driver->in_busy_1);
  76. } else if (!driver->in_busy_2) {
  77. buf = driver->buf_in_2;
  78. write_ptr_modem = driver->write_ptr_2;
  79. in_busy_ptr = &(driver->in_busy_2);
  80. }
  81. if (driver->ch && buf) {
  82. int r = smd_read_avail(driver->ch);
  83. if (r > IN_BUF_SIZE) {
  84. if (r < MAX_IN_BUF_SIZE) {
  85. printk(KERN_ALERT "\n diag: SMD sending in "
  86. "packets upto %d bytes", r);
  87. buf = krealloc(buf, r, GFP_KERNEL);
  88. } else {
  89. printk(KERN_ALERT "\n diag: SMD sending in "
  90. "packets more than %d bytes", MAX_IN_BUF_SIZE);
  91. return;
  92. }
  93. }
  94. if (r > 0) {
  95. if (!buf)
  96. pr_info("Out of diagmem for Modem\n");
  97. else {
  98. APPEND_DEBUG('i');
  99. smd_read(driver->ch, buf, r);
  100. APPEND_DEBUG('j');
  101. write_ptr_modem->length = r;
  102. *in_busy_ptr = 1;
  103. diag_device_write(buf, MODEM_DATA,
  104. write_ptr_modem);
  105. }
  106. }
  107. }
  108. }
  109. int diag_device_write(void *buf, int proc_num, struct diag_request *write_ptr)
  110. {
  111. int i, err = 0;
  112. if (driver->logging_mode == MEMORY_DEVICE_MODE) {
  113. if (proc_num == APPS_DATA) {
  114. for (i = 0; i < driver->poolsize_write_struct; i++)
  115. if (driver->buf_tbl[i].length == 0) {
  116. driver->buf_tbl[i].buf = buf;
  117. driver->buf_tbl[i].length =
  118. driver->used;
  119. #ifdef DIAG_DEBUG
  120. printk(KERN_INFO "\n ENQUEUE buf ptr"
  121. " and length is %x , %d\n",
  122. (unsigned int)(driver->buf_
  123. tbl[i].buf), driver->buf_tbl[i].length);
  124. #endif
  125. break;
  126. }
  127. }
  128. for (i = 0; i < driver->num_clients; i++)
  129. if (driver->client_map[i].pid ==
  130. driver->logging_process_id)
  131. break;
  132. if (i < driver->num_clients) {
  133. driver->data_ready[i] |= MEMORY_DEVICE_LOG_TYPE;
  134. wake_up_interruptible(&driver->wait_q);
  135. } else
  136. return -EINVAL;
  137. } else if (driver->logging_mode == NO_LOGGING_MODE) {
  138. if (proc_num == MODEM_DATA) {
  139. driver->in_busy_1 = 0;
  140. driver->in_busy_2 = 0;
  141. queue_work(driver->diag_wq, &(driver->
  142. diag_read_smd_work));
  143. } else if (proc_num == QDSP_DATA) {
  144. driver->in_busy_qdsp_1 = 0;
  145. driver->in_busy_qdsp_2 = 0;
  146. queue_work(driver->diag_wq, &(driver->
  147. diag_read_smd_qdsp_work));
  148. }
  149. err = -1;
  150. }
  151. #ifdef CONFIG_DIAG_OVER_USB
  152. else if (driver->logging_mode == USB_MODE) {
  153. if (proc_num == APPS_DATA) {
  154. driver->write_ptr_svc = (struct diag_request *)
  155. (diagmem_alloc(driver, sizeof(struct diag_request),
  156. POOL_TYPE_WRITE_STRUCT));
  157. if (driver->write_ptr_svc) {
  158. driver->write_ptr_svc->length = driver->used;
  159. driver->write_ptr_svc->buf = buf;
  160. err = usb_diag_write(driver->legacy_ch,
  161. driver->write_ptr_svc);
  162. } else
  163. err = -1;
  164. } else if (proc_num == MODEM_DATA) {
  165. write_ptr->buf = buf;
  166. #ifdef DIAG_DEBUG
  167. printk(KERN_INFO "writing data to USB,"
  168. "pkt length %d\n", write_ptr->length);
  169. print_hex_dump(KERN_DEBUG, "Written Packet Data to"
  170. " USB: ", 16, 1, DUMP_PREFIX_ADDRESS,
  171. buf, write_ptr->length, 1);
  172. #endif /* DIAG DEBUG */
  173. err = usb_diag_write(driver->legacy_ch, write_ptr);
  174. } else if (proc_num == QDSP_DATA) {
  175. write_ptr->buf = buf;
  176. err = usb_diag_write(driver->legacy_ch, write_ptr);
  177. }
  178. #ifdef CONFIG_DIAG_SDIO_PIPE
  179. else if (proc_num == SDIO_DATA) {
  180. if (machine_is_msm8x60_charm_surf() ||
  181. machine_is_msm8x60_charm_ffa()) {
  182. write_ptr->buf = buf;
  183. err = usb_diag_write(driver->mdm_ch, write_ptr);
  184. } else
  185. pr_err("diag: Incorrect data while USB write");
  186. }
  187. #endif
  188. APPEND_DEBUG('d');
  189. }
  190. #endif /* DIAG OVER USB */
  191. return err;
  192. }
  193. void __diag_smd_qdsp_send_req(void)
  194. {
  195. void *buf = NULL;
  196. int *in_busy_qdsp_ptr = NULL;
  197. struct diag_request *write_ptr_qdsp = NULL;
  198. if (!driver->in_busy_qdsp_1) {
  199. buf = driver->buf_in_qdsp_1;
  200. write_ptr_qdsp = driver->write_ptr_qdsp_1;
  201. in_busy_qdsp_ptr = &(driver->in_busy_qdsp_1);
  202. } else if (!driver->in_busy_qdsp_2) {
  203. buf = driver->buf_in_qdsp_2;
  204. write_ptr_qdsp = driver->write_ptr_qdsp_2;
  205. in_busy_qdsp_ptr = &(driver->in_busy_qdsp_2);
  206. }
  207. if (driver->chqdsp && buf) {
  208. int r = smd_read_avail(driver->chqdsp);
  209. if (r > IN_BUF_SIZE) {
  210. if (r < MAX_IN_BUF_SIZE) {
  211. printk(KERN_ALERT "\n diag: SMD sending in "
  212. "packets upto %d bytes", r);
  213. buf = krealloc(buf, r, GFP_KERNEL);
  214. } else {
  215. printk(KERN_ALERT "\n diag: SMD sending in "
  216. "packets more than %d bytes", MAX_IN_BUF_SIZE);
  217. return;
  218. }
  219. }
  220. if (r > 0) {
  221. if (!buf)
  222. printk(KERN_INFO "Out of diagmem for QDSP\n");
  223. else {
  224. APPEND_DEBUG('i');
  225. smd_read(driver->chqdsp, buf, r);
  226. APPEND_DEBUG('j');
  227. write_ptr_qdsp->length = r;
  228. *in_busy_qdsp_ptr = 1;
  229. diag_device_write(buf, QDSP_DATA,
  230. write_ptr_qdsp);
  231. }
  232. }
  233. }
  234. }
  235. static void diag_print_mask_table(void)
  236. {
  237. /* Enable this to print mask table when updated */
  238. #ifdef MASK_DEBUG
  239. int first;
  240. int last;
  241. uint8_t *ptr = driver->msg_masks;
  242. int i = 0;
  243. while (*(uint32_t *)(ptr + 4)) {
  244. first = *(uint32_t *)ptr;
  245. ptr += 4;
  246. last = *(uint32_t *)ptr;
  247. ptr += 4;
  248. printk(KERN_INFO "SSID %d - %d\n", first, last);
  249. for (i = 0 ; i <= last - first ; i++)
  250. printk(KERN_INFO "MASK:%x\n", *((uint32_t *)ptr + i));
  251. ptr += ((last - first) + 1)*4;
  252. }
  253. #endif
  254. }
  255. static void diag_update_msg_mask(int start, int end , uint8_t *buf)
  256. {
  257. int found = 0;
  258. int first;
  259. int last;
  260. uint8_t *ptr = driver->msg_masks;
  261. uint8_t *ptr_buffer_start = &(*(driver->msg_masks));
  262. uint8_t *ptr_buffer_end = &(*(driver->msg_masks)) + MSG_MASK_SIZE;
  263. mutex_lock(&driver->diagchar_mutex);
  264. /* First SSID can be zero : So check that last is non-zero */
  265. while (*(uint32_t *)(ptr + 4)) {
  266. first = *(uint32_t *)ptr;
  267. ptr += 4;
  268. last = *(uint32_t *)ptr;
  269. ptr += 4;
  270. if (start >= first && start <= last) {
  271. ptr += (start - first)*4;
  272. if (end <= last)
  273. if (CHK_OVERFLOW(ptr_buffer_start, ptr,
  274. ptr_buffer_end,
  275. (((end - start)+1)*4)))
  276. memcpy(ptr, buf , ((end - start)+1)*4);
  277. else
  278. printk(KERN_CRIT "Not enough"
  279. " buffer space for"
  280. " MSG_MASK\n");
  281. else
  282. printk(KERN_INFO "Unable to copy"
  283. " mask change\n");
  284. found = 1;
  285. break;
  286. } else {
  287. ptr += ((last - first) + 1)*4;
  288. }
  289. }
  290. /* Entry was not found - add new table */
  291. if (!found) {
  292. if (CHK_OVERFLOW(ptr_buffer_start, ptr, ptr_buffer_end,
  293. 8 + ((end - start) + 1)*4)) {
  294. memcpy(ptr, &(start) , 4);
  295. ptr += 4;
  296. memcpy(ptr, &(end), 4);
  297. ptr += 4;
  298. memcpy(ptr, buf , ((end - start) + 1)*4);
  299. } else
  300. printk(KERN_CRIT " Not enough buffer"
  301. " space for MSG_MASK\n");
  302. }
  303. mutex_unlock(&driver->diagchar_mutex);
  304. diag_print_mask_table();
  305. }
  306. static void diag_update_event_mask(uint8_t *buf, int toggle, int num_bits)
  307. {
  308. uint8_t *ptr = driver->event_masks;
  309. uint8_t *temp = buf + 2;
  310. mutex_lock(&driver->diagchar_mutex);
  311. if (!toggle)
  312. memset(ptr, 0 , EVENT_MASK_SIZE);
  313. else
  314. if (CHK_OVERFLOW(ptr, ptr,
  315. ptr+EVENT_MASK_SIZE,
  316. num_bits/8 + 1))
  317. memcpy(ptr, temp , num_bits/8 + 1);
  318. else
  319. printk(KERN_CRIT "Not enough buffer space "
  320. "for EVENT_MASK\n");
  321. mutex_unlock(&driver->diagchar_mutex);
  322. }
  323. static void diag_update_log_mask(int equip_id, uint8_t *buf, int num_items)
  324. {
  325. uint8_t *temp = buf;
  326. struct mask_info {
  327. int equip_id;
  328. int index;
  329. };
  330. int i = 0;
  331. unsigned char *ptr_data;
  332. int offset = 8*MAX_EQUIP_ID;
  333. struct mask_info *ptr = (struct mask_info *)driver->log_masks;
  334. mutex_lock(&driver->diagchar_mutex);
  335. /* Check if we already know index of this equipment ID */
  336. for (i = 0; i < MAX_EQUIP_ID; i++) {
  337. if ((ptr->equip_id == equip_id) && (ptr->index != 0)) {
  338. offset = ptr->index;
  339. break;
  340. }
  341. if ((ptr->equip_id == 0) && (ptr->index == 0)) {
  342. /*Reached a null entry */
  343. ptr->equip_id = equip_id;
  344. ptr->index = driver->log_masks_length;
  345. offset = driver->log_masks_length;
  346. driver->log_masks_length += ((num_items+7)/8);
  347. break;
  348. }
  349. ptr++;
  350. }
  351. ptr_data = driver->log_masks + offset;
  352. if (CHK_OVERFLOW(driver->log_masks, ptr_data, driver->log_masks
  353. + LOG_MASK_SIZE, (num_items+7)/8))
  354. memcpy(ptr_data, temp , (num_items+7)/8);
  355. else
  356. printk(KERN_CRIT " Not enough buffer space for LOG_MASK\n");
  357. mutex_unlock(&driver->diagchar_mutex);
  358. }
  359. static void diag_update_pkt_buffer(unsigned char *buf)
  360. {
  361. unsigned char *ptr = driver->pkt_buf;
  362. unsigned char *temp = buf;
  363. mutex_lock(&driver->diagchar_mutex);
  364. if (CHK_OVERFLOW(ptr, ptr, ptr + PKT_SIZE, driver->pkt_length))
  365. memcpy(ptr, temp , driver->pkt_length);
  366. else
  367. printk(KERN_CRIT " Not enough buffer space for PKT_RESP\n");
  368. mutex_unlock(&driver->diagchar_mutex);
  369. }
  370. void diag_update_userspace_clients(unsigned int type)
  371. {
  372. int i;
  373. mutex_lock(&driver->diagchar_mutex);
  374. for (i = 0; i < driver->num_clients; i++)
  375. if (driver->client_map[i].pid != 0)
  376. driver->data_ready[i] |= type;
  377. wake_up_interruptible(&driver->wait_q);
  378. mutex_unlock(&driver->diagchar_mutex);
  379. }
  380. void diag_update_sleeping_process(int process_id)
  381. {
  382. int i;
  383. mutex_lock(&driver->diagchar_mutex);
  384. for (i = 0; i < driver->num_clients; i++)
  385. if (driver->client_map[i].pid == process_id) {
  386. driver->data_ready[i] |= PKT_TYPE;
  387. break;
  388. }
  389. wake_up_interruptible(&driver->wait_q);
  390. mutex_unlock(&driver->diagchar_mutex);
  391. }
  392. static int diag_process_apps_pkt(unsigned char *buf, int len)
  393. {
  394. uint16_t start;
  395. uint16_t end, subsys_cmd_code;
  396. int i, cmd_code, subsys_id;
  397. int packet_type = 1;
  398. unsigned char *temp = buf;
  399. /* event mask */
  400. if ((*buf == 0x60) && (*(++buf) == 0x0)) {
  401. diag_update_event_mask(buf, 0, 0);
  402. diag_update_userspace_clients(EVENT_MASKS_TYPE);
  403. }
  404. /* check for set event mask */
  405. else if (*buf == 0x82) {
  406. buf += 4;
  407. diag_update_event_mask(buf, 1, *(uint16_t *)buf);
  408. diag_update_userspace_clients(
  409. EVENT_MASKS_TYPE);
  410. }
  411. /* log mask */
  412. else if (*buf == 0x73) {
  413. buf += 4;
  414. if (*(int *)buf == 3) {
  415. buf += 4;
  416. /* Read Equip ID and pass as first param below*/
  417. diag_update_log_mask(*(int *)buf, buf+8,
  418. *(int *)(buf+4));
  419. diag_update_userspace_clients(LOG_MASKS_TYPE);
  420. }
  421. }
  422. /* Check for set message mask */
  423. else if ((*buf == 0x7d) && (*(++buf) == 0x4)) {
  424. buf++;
  425. start = *(uint16_t *)buf;
  426. buf += 2;
  427. end = *(uint16_t *)buf;
  428. buf += 4;
  429. diag_update_msg_mask((uint32_t)start, (uint32_t)end , buf);
  430. diag_update_userspace_clients(MSG_MASKS_TYPE);
  431. }
  432. /* Set all run-time masks
  433. if ((*buf == 0x7d) && (*(++buf) == 0x5)) {
  434. TO DO
  435. } */
  436. #if defined(CONFIG_DIAG_OVER_USB)
  437. /* Check for ID for APQ8060 AND NO MODEM present */
  438. else if (!(driver->ch) && CHK_APQ_GET_ID()) {
  439. /* Respond to polling for Apps only DIAG */
  440. if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
  441. (*(buf+2) == 0x03)) {
  442. for (i = 0; i < 3; i++)
  443. driver->apps_rsp_buf[i] = *(buf+i);
  444. for (i = 0; i < 13; i++)
  445. driver->apps_rsp_buf[i+3] = 0;
  446. ENCODE_RSP_AND_SEND(15);
  447. return 0;
  448. }
  449. /* respond to 0x0 command */
  450. else if (*buf == 0x00) {
  451. for (i = 0; i < 55; i++)
  452. driver->apps_rsp_buf[i] = 0;
  453. ENCODE_RSP_AND_SEND(54);
  454. return 0;
  455. }
  456. /* respond to 0x7c command */
  457. else if (*buf == 0x7c) {
  458. driver->apps_rsp_buf[0] = 0x7c;
  459. for (i = 1; i < 8; i++)
  460. driver->apps_rsp_buf[i] = 0;
  461. /* Tools ID for APQ 8060 */
  462. *(int *)(driver->apps_rsp_buf + 8) = CHK_APQ_GET_ID();
  463. *(unsigned char *)(driver->apps_rsp_buf + 12) = '\0';
  464. *(unsigned char *)(driver->apps_rsp_buf + 13) = '\0';
  465. ENCODE_RSP_AND_SEND(13);
  466. return 0;
  467. }
  468. }
  469. #endif
  470. /* Check for registered clients and forward packet to user-space */
  471. else{
  472. cmd_code = (int)(*(char *)buf);
  473. temp++;
  474. subsys_id = (int)(*(char *)temp);
  475. temp++;
  476. subsys_cmd_code = *(uint16_t *)temp;
  477. temp += 2;
  478. for (i = 0; i < diag_max_registration; i++) {
  479. if (driver->table[i].process_id != 0) {
  480. if (driver->table[i].cmd_code ==
  481. cmd_code && driver->table[i].subsys_id ==
  482. subsys_id &&
  483. driver->table[i].cmd_code_lo <=
  484. subsys_cmd_code &&
  485. driver->table[i].cmd_code_hi >=
  486. subsys_cmd_code){
  487. driver->pkt_length = len;
  488. diag_update_pkt_buffer(buf);
  489. diag_update_sleeping_process(
  490. driver->table[i].process_id);
  491. return 0;
  492. } /* end of if */
  493. else if (driver->table[i].cmd_code == 255
  494. && cmd_code == 75) {
  495. if (driver->table[i].subsys_id ==
  496. subsys_id &&
  497. driver->table[i].cmd_code_lo <=
  498. subsys_cmd_code &&
  499. driver->table[i].cmd_code_hi >=
  500. subsys_cmd_code){
  501. driver->pkt_length = len;
  502. diag_update_pkt_buffer(buf);
  503. diag_update_sleeping_process(
  504. driver->table[i].
  505. process_id);
  506. return 0;
  507. }
  508. } /* end of else-if */
  509. else if (driver->table[i].cmd_code == 255 &&
  510. driver->table[i].subsys_id == 255) {
  511. if (driver->table[i].cmd_code_lo <=
  512. cmd_code &&
  513. driver->table[i].
  514. cmd_code_hi >= cmd_code){
  515. driver->pkt_length = len;
  516. diag_update_pkt_buffer(buf);
  517. diag_update_sleeping_process
  518. (driver->table[i].
  519. process_id);
  520. return 0;
  521. }
  522. } /* end of else-if */
  523. } /* if(driver->table[i].process_id != 0) */
  524. } /* for (i = 0; i < diag_max_registration; i++) */
  525. } /* else */
  526. return packet_type;
  527. }
  528. void diag_process_hdlc(void *data, unsigned len)
  529. {
  530. struct diag_hdlc_decode_type hdlc;
  531. int ret, type = 0;
  532. #ifdef DIAG_DEBUG
  533. int i;
  534. printk(KERN_INFO "\n HDLC decode function, len of data %d\n", len);
  535. #endif
  536. hdlc.dest_ptr = driver->hdlc_buf;
  537. hdlc.dest_size = USB_MAX_OUT_BUF;
  538. hdlc.src_ptr = data;
  539. hdlc.src_size = len;
  540. hdlc.src_idx = 0;
  541. hdlc.dest_idx = 0;
  542. hdlc.escaping = 0;
  543. ret = diag_hdlc_decode(&hdlc);
  544. if (ret)
  545. type = diag_process_apps_pkt(driver->hdlc_buf,
  546. hdlc.dest_idx - 3);
  547. else if (driver->debug_flag) {
  548. printk(KERN_ERR "Packet dropped due to bad HDLC coding/CRC"
  549. " errors or partial packet received, packet"
  550. " length = %d\n", len);
  551. print_hex_dump(KERN_DEBUG, "Dropped Packet Data: ", 16, 1,
  552. DUMP_PREFIX_ADDRESS, data, len, 1);
  553. driver->debug_flag = 0;
  554. }
  555. /* implies this packet is NOT meant for apps */
  556. if (!(driver->ch) && type == 1 && CHK_APQ_GET_ID()) {
  557. if (driver->chqdsp)
  558. smd_write(driver->chqdsp, driver->hdlc_buf,
  559. hdlc.dest_idx - 3);
  560. type = 0;
  561. }
  562. #ifdef DIAG_DEBUG
  563. printk(KERN_INFO "\n hdlc.dest_idx = %d", hdlc.dest_idx);
  564. for (i = 0; i < hdlc.dest_idx; i++)
  565. printk(KERN_DEBUG "\t%x", *(((unsigned char *)
  566. driver->hdlc_buf)+i));
  567. #endif /* DIAG DEBUG */
  568. /* ignore 2 bytes for CRC, one for 7E and send */
  569. if ((driver->ch) && (ret) && (type) && (hdlc.dest_idx > 3)) {
  570. APPEND_DEBUG('g');
  571. smd_write(driver->ch, driver->hdlc_buf, hdlc.dest_idx - 3);
  572. APPEND_DEBUG('h');
  573. #ifdef DIAG_DEBUG
  574. printk(KERN_INFO "writing data to SMD, pkt length %d\n", len);
  575. print_hex_dump(KERN_DEBUG, "Written Packet Data to SMD: ", 16,
  576. 1, DUMP_PREFIX_ADDRESS, data, len, 1);
  577. #endif /* DIAG DEBUG */
  578. }
  579. }
  580. #ifdef CONFIG_DIAG_OVER_USB
  581. #define N_LEGACY_WRITE (driver->poolsize + 5) /* 2+1 for modem ; 2 for q6 */
  582. #define N_LEGACY_READ 1
  583. int diagfwd_connect(void)
  584. {
  585. int err;
  586. printk(KERN_DEBUG "diag: USB connected\n");
  587. err = usb_diag_alloc_req(driver->legacy_ch, N_LEGACY_WRITE,
  588. N_LEGACY_READ);
  589. if (err)
  590. printk(KERN_ERR "diag: unable to alloc USB req on legacy ch");
  591. driver->usb_connected = 1;
  592. driver->in_busy_1 = 0;
  593. driver->in_busy_2 = 0;
  594. driver->in_busy_qdsp_1 = 0;
  595. driver->in_busy_qdsp_2 = 0;
  596. /* Poll SMD channels to check for data*/
  597. queue_work(driver->diag_wq, &(driver->diag_read_smd_work));
  598. queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work));
  599. /* Poll USB channel to check for data*/
  600. queue_work(driver->diag_wq, &(driver->diag_read_work));
  601. #ifdef CONFIG_DIAG_SDIO_PIPE
  602. if (machine_is_msm8x60_charm_surf() || machine_is_msm8x60_charm_ffa()) {
  603. if (driver->mdm_ch && !IS_ERR(driver->mdm_ch))
  604. diagfwd_connect_sdio();
  605. else
  606. printk(KERN_INFO "diag: No USB MDM ch");
  607. }
  608. #endif
  609. return 0;
  610. }
  611. int diagfwd_disconnect(void)
  612. {
  613. printk(KERN_DEBUG "diag: USB disconnected\n");
  614. driver->usb_connected = 0;
  615. driver->in_busy_1 = 1;
  616. driver->in_busy_2 = 1;
  617. driver->in_busy_qdsp_1 = 1;
  618. driver->in_busy_qdsp_2 = 1;
  619. driver->debug_flag = 1;
  620. usb_diag_free_req(driver->legacy_ch);
  621. #ifdef CONFIG_DIAG_SDIO_PIPE
  622. if (machine_is_msm8x60_charm_surf() || machine_is_msm8x60_charm_ffa())
  623. if (driver->mdm_ch && !IS_ERR(driver->mdm_ch))
  624. diagfwd_disconnect_sdio();
  625. #endif
  626. /* TBD - notify and flow control SMD */
  627. return 0;
  628. }
  629. int diagfwd_write_complete(struct diag_request *diag_write_ptr)
  630. {
  631. unsigned char *buf = diag_write_ptr->buf;
  632. /*Determine if the write complete is for data from modem/apps/q6 */
  633. /* Need a context variable here instead */
  634. if (buf == (void *)driver->buf_in_1) {
  635. driver->in_busy_1 = 0;
  636. APPEND_DEBUG('o');
  637. queue_work(driver->diag_wq, &(driver->diag_read_smd_work));
  638. } else if (buf == (void *)driver->buf_in_2) {
  639. driver->in_busy_2 = 0;
  640. APPEND_DEBUG('O');
  641. queue_work(driver->diag_wq, &(driver->diag_read_smd_work));
  642. } else if (buf == (void *)driver->buf_in_qdsp_1) {
  643. driver->in_busy_qdsp_1 = 0;
  644. APPEND_DEBUG('p');
  645. queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work));
  646. } else if (buf == (void *)driver->buf_in_qdsp_2) {
  647. driver->in_busy_qdsp_2 = 0;
  648. APPEND_DEBUG('P');
  649. queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work));
  650. }
  651. #ifdef CONFIG_DIAG_SDIO_PIPE
  652. else if (buf == (void *)driver->buf_in_sdio)
  653. if (machine_is_msm8x60_charm_surf() ||
  654. machine_is_msm8x60_charm_ffa())
  655. diagfwd_write_complete_sdio();
  656. else
  657. pr_err("diag: Incorrect buffer pointer while WRITE");
  658. #endif
  659. else {
  660. diagmem_free(driver, (unsigned char *)buf, POOL_TYPE_HDLC);
  661. diagmem_free(driver, (unsigned char *)diag_write_ptr,
  662. POOL_TYPE_WRITE_STRUCT);
  663. APPEND_DEBUG('q');
  664. }
  665. return 0;
  666. }
  667. int diagfwd_read_complete(struct diag_request *diag_read_ptr)
  668. {
  669. int status = diag_read_ptr->status;
  670. unsigned char *buf = diag_read_ptr->buf;
  671. /* Determine if the read complete is for data on legacy/mdm ch */
  672. if (buf == (void *)driver->usb_buf_out) {
  673. driver->read_len_legacy = diag_read_ptr->actual;
  674. APPEND_DEBUG('s');
  675. #ifdef DIAG_DEBUG
  676. printk(KERN_INFO "read data from USB, pkt length %d",
  677. diag_read_ptr->actual);
  678. print_hex_dump(KERN_DEBUG, "Read Packet Data from USB: ", 16, 1,
  679. DUMP_PREFIX_ADDRESS, diag_read_ptr->buf,
  680. diag_read_ptr->actual, 1);
  681. #endif /* DIAG DEBUG */
  682. if (driver->logging_mode == USB_MODE) {
  683. if (status != -ECONNRESET && status != -ESHUTDOWN)
  684. queue_work(driver->diag_wq,
  685. &(driver->diag_proc_hdlc_work));
  686. else
  687. queue_work(driver->diag_wq,
  688. &(driver->diag_read_work));
  689. }
  690. }
  691. #ifdef CONFIG_DIAG_SDIO_PIPE
  692. else if (buf == (void *)driver->usb_buf_mdm_out) {
  693. if (machine_is_msm8x60_charm_surf() ||
  694. machine_is_msm8x60_charm_ffa()) {
  695. driver->read_len_mdm = diag_read_ptr->actual;
  696. diagfwd_read_complete_sdio();
  697. } else
  698. pr_err("diag: Incorrect buffer pointer while READ");
  699. }
  700. #endif
  701. else
  702. printk(KERN_ERR "diag: Unknown buffer ptr from USB");
  703. return 0;
  704. }
  705. void diag_read_work_fn(struct work_struct *work)
  706. {
  707. APPEND_DEBUG('d');
  708. driver->usb_read_ptr->buf = driver->usb_buf_out;
  709. driver->usb_read_ptr->length = USB_MAX_OUT_BUF;
  710. usb_diag_read(driver->legacy_ch, driver->usb_read_ptr);
  711. APPEND_DEBUG('e');
  712. }
  713. void diag_process_hdlc_fn(struct work_struct *work)
  714. {
  715. APPEND_DEBUG('D');
  716. diag_process_hdlc(driver->usb_buf_out, driver->read_len_legacy);
  717. diag_read_work_fn(work);
  718. APPEND_DEBUG('E');
  719. }
  720. void diag_usb_legacy_notifier(void *priv, unsigned event,
  721. struct diag_request *d_req)
  722. {
  723. switch (event) {
  724. case USB_DIAG_CONNECT:
  725. diagfwd_connect();
  726. break;
  727. case USB_DIAG_DISCONNECT:
  728. diagfwd_disconnect();
  729. break;
  730. case USB_DIAG_READ_DONE:
  731. diagfwd_read_complete(d_req);
  732. break;
  733. case USB_DIAG_WRITE_DONE:
  734. diagfwd_write_complete(d_req);
  735. break;
  736. default:
  737. printk(KERN_ERR "Unknown event from USB diag\n");
  738. break;
  739. }
  740. }
  741. #endif /* DIAG OVER USB */
  742. static void diag_smd_notify(void *ctxt, unsigned event)
  743. {
  744. queue_work(driver->diag_wq, &(driver->diag_read_smd_work));
  745. }
  746. #if defined(CONFIG_MSM_N_WAY_SMD)
  747. static void diag_smd_qdsp_notify(void *ctxt, unsigned event)
  748. {
  749. queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work));
  750. }
  751. #endif
  752. static int diag_smd_probe(struct platform_device *pdev)
  753. {
  754. int r = 0;
  755. if (pdev->id == 0)
  756. r = smd_open("DIAG", &driver->ch, driver, diag_smd_notify);
  757. #if defined(CONFIG_MSM_N_WAY_SMD)
  758. if (pdev->id == 1)
  759. r = smd_named_open_on_edge("DIAG", SMD_APPS_QDSP
  760. , &driver->chqdsp, driver, diag_smd_qdsp_notify);
  761. #endif
  762. pm_runtime_set_active(&pdev->dev);
  763. pm_runtime_enable(&pdev->dev);
  764. printk(KERN_INFO "diag opened SMD port ; r = %d\n", r);
  765. return 0;
  766. }
  767. static int diagfwd_runtime_suspend(struct device *dev)
  768. {
  769. dev_dbg(dev, "pm_runtime: suspending...\n");
  770. return 0;
  771. }
  772. static int diagfwd_runtime_resume(struct device *dev)
  773. {
  774. dev_dbg(dev, "pm_runtime: resuming...\n");
  775. return 0;
  776. }
  777. static const struct dev_pm_ops diagfwd_dev_pm_ops = {
  778. .runtime_suspend = diagfwd_runtime_suspend,
  779. .runtime_resume = diagfwd_runtime_resume,
  780. };
  781. static struct platform_driver msm_smd_ch1_driver = {
  782. .probe = diag_smd_probe,
  783. .driver = {
  784. .name = "DIAG",
  785. .owner = THIS_MODULE,
  786. .pm = &diagfwd_dev_pm_ops,
  787. },
  788. };
  789. void diagfwd_init(void)
  790. {
  791. diag_debug_buf_idx = 0;
  792. driver->read_len_legacy = 0;
  793. if (driver->buf_in_1 == NULL)
  794. driver->buf_in_1 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
  795. if (driver->buf_in_1 == NULL)
  796. goto err;
  797. if (driver->buf_in_2 == NULL)
  798. driver->buf_in_2 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
  799. if (driver->buf_in_2 == NULL)
  800. goto err;
  801. if (driver->buf_in_qdsp_1 == NULL)
  802. driver->buf_in_qdsp_1 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
  803. if (driver->buf_in_qdsp_1 == NULL)
  804. goto err;
  805. if (driver->buf_in_qdsp_2 == NULL)
  806. driver->buf_in_qdsp_2 = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
  807. if (driver->buf_in_qdsp_2 == NULL)
  808. goto err;
  809. if (driver->usb_buf_out == NULL &&
  810. (driver->usb_buf_out = kzalloc(USB_MAX_OUT_BUF,
  811. GFP_KERNEL)) == NULL)
  812. goto err;
  813. if (driver->hdlc_buf == NULL
  814. && (driver->hdlc_buf = kzalloc(HDLC_MAX, GFP_KERNEL)) == NULL)
  815. goto err;
  816. if (driver->msg_masks == NULL
  817. && (driver->msg_masks = kzalloc(MSG_MASK_SIZE,
  818. GFP_KERNEL)) == NULL)
  819. goto err;
  820. if (driver->log_masks == NULL &&
  821. (driver->log_masks = kzalloc(LOG_MASK_SIZE, GFP_KERNEL)) == NULL)
  822. goto err;
  823. driver->log_masks_length = 8*MAX_EQUIP_ID;
  824. if (driver->event_masks == NULL &&
  825. (driver->event_masks = kzalloc(EVENT_MASK_SIZE,
  826. GFP_KERNEL)) == NULL)
  827. goto err;
  828. if (driver->client_map == NULL &&
  829. (driver->client_map = kzalloc
  830. ((driver->num_clients) * sizeof(struct diag_client_map),
  831. GFP_KERNEL)) == NULL)
  832. goto err;
  833. if (driver->buf_tbl == NULL)
  834. driver->buf_tbl = kzalloc(buf_tbl_size *
  835. sizeof(struct diag_write_device), GFP_KERNEL);
  836. if (driver->buf_tbl == NULL)
  837. goto err;
  838. if (driver->data_ready == NULL &&
  839. (driver->data_ready = kzalloc(driver->num_clients * sizeof(struct
  840. diag_client_map), GFP_KERNEL)) == NULL)
  841. goto err;
  842. if (driver->table == NULL &&
  843. (driver->table = kzalloc(diag_max_registration*
  844. sizeof(struct diag_master_table),
  845. GFP_KERNEL)) == NULL)
  846. goto err;
  847. if (driver->write_ptr_1 == NULL)
  848. driver->write_ptr_1 = kzalloc(
  849. sizeof(struct diag_request), GFP_KERNEL);
  850. if (driver->write_ptr_1 == NULL)
  851. goto err;
  852. if (driver->write_ptr_2 == NULL)
  853. driver->write_ptr_2 = kzalloc(
  854. sizeof(struct diag_request), GFP_KERNEL);
  855. if (driver->write_ptr_2 == NULL)
  856. goto err;
  857. if (driver->write_ptr_qdsp_1 == NULL)
  858. driver->write_ptr_qdsp_1 = kzalloc(
  859. sizeof(struct diag_request), GFP_KERNEL);
  860. if (driver->write_ptr_qdsp_1 == NULL)
  861. goto err;
  862. if (driver->write_ptr_qdsp_2 == NULL)
  863. driver->write_ptr_qdsp_2 = kzalloc(
  864. sizeof(struct diag_request), GFP_KERNEL);
  865. if (driver->write_ptr_qdsp_2 == NULL)
  866. goto err;
  867. if (driver->usb_read_ptr == NULL)
  868. driver->usb_read_ptr = kzalloc(
  869. sizeof(struct diag_request), GFP_KERNEL);
  870. if (driver->usb_read_ptr == NULL)
  871. goto err;
  872. if (driver->pkt_buf == NULL &&
  873. (driver->pkt_buf = kzalloc(PKT_SIZE,
  874. GFP_KERNEL)) == NULL)
  875. goto err;
  876. if (driver->apps_rsp_buf == NULL)
  877. driver->apps_rsp_buf = kzalloc(150, GFP_KERNEL);
  878. if (driver->apps_rsp_buf == NULL)
  879. goto err;
  880. driver->diag_wq = create_singlethread_workqueue("diag_wq");
  881. #ifdef CONFIG_DIAG_OVER_USB
  882. INIT_WORK(&(driver->diag_proc_hdlc_work), diag_process_hdlc_fn);
  883. INIT_WORK(&(driver->diag_read_work), diag_read_work_fn);
  884. driver->legacy_ch = usb_diag_open(DIAG_LEGACY, driver,
  885. diag_usb_legacy_notifier);
  886. if (IS_ERR(driver->legacy_ch)) {
  887. printk(KERN_ERR "Unable to open USB diag legacy channel\n");
  888. goto err;
  889. }
  890. #ifdef CONFIG_DIAG_SDIO_PIPE
  891. if (machine_is_msm8x60_charm_surf() || machine_is_msm8x60_charm_ffa())
  892. diagfwd_sdio_init();
  893. #endif
  894. #endif
  895. platform_driver_register(&msm_smd_ch1_driver);
  896. return;
  897. err:
  898. printk(KERN_INFO "\n Could not initialize diag buffers\n");
  899. kfree(driver->buf_in_1);
  900. kfree(driver->buf_in_2);
  901. kfree(driver->buf_in_qdsp_1);
  902. kfree(driver->buf_in_qdsp_2);
  903. kfree(driver->usb_buf_out);
  904. kfree(driver->hdlc_buf);
  905. kfree(driver->msg_masks);
  906. kfree(driver->log_masks);
  907. kfree(driver->event_masks);
  908. kfree(driver->client_map);
  909. kfree(driver->buf_tbl);
  910. kfree(driver->data_ready);
  911. kfree(driver->table);
  912. kfree(driver->pkt_buf);
  913. kfree(driver->write_ptr_1);
  914. kfree(driver->write_ptr_2);
  915. kfree(driver->write_ptr_qdsp_1);
  916. kfree(driver->write_ptr_qdsp_2);
  917. kfree(driver->usb_read_ptr);
  918. kfree(driver->apps_rsp_buf);
  919. if (driver->diag_wq)
  920. destroy_workqueue(driver->diag_wq);
  921. }
  922. void diagfwd_exit(void)
  923. {
  924. smd_close(driver->ch);
  925. smd_close(driver->chqdsp);
  926. driver->ch = 0; /*SMD can make this NULL */
  927. driver->chqdsp = 0;
  928. #ifdef CONFIG_DIAG_OVER_USB
  929. if (driver->usb_connected)
  930. usb_diag_free_req(driver->legacy_ch);
  931. #endif
  932. platform_driver_unregister(&msm_smd_ch1_driver);
  933. #ifdef CONFIG_DIAG_OVER_USB
  934. usb_diag_close(driver->legacy_ch);
  935. #endif
  936. kfree(driver->buf_in_1);
  937. kfree(driver->buf_in_2);
  938. kfree(driver->buf_in_qdsp_1);
  939. kfree(driver->buf_in_qdsp_2);
  940. kfree(driver->usb_buf_out);
  941. kfree(driver->hdlc_buf);
  942. kfree(driver->msg_masks);
  943. kfree(driver->log_masks);
  944. kfree(driver->event_masks);
  945. kfree(driver->client_map);
  946. kfree(driver->buf_tbl);
  947. kfree(driver->data_ready);
  948. kfree(driver->table);
  949. kfree(driver->pkt_buf);
  950. kfree(driver->write_ptr_1);
  951. kfree(driver->write_ptr_2);
  952. kfree(driver->write_ptr_qdsp_1);
  953. kfree(driver->write_ptr_qdsp_2);
  954. kfree(driver->usb_read_ptr);
  955. kfree(driver->apps_rsp_buf);
  956. destroy_workqueue(driver->diag_wq);
  957. }