mirror from https://www.codeaurora.org/git/projects/hisense-ts7008/repository/
[huawei.git] / AMSS / diagdiag.c
1 /*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*\r
2 \r
3                 Diagnostics Packet Processing Common Routines\r
4 \r
5 General Description\r
6   Core diagnostic packet processing routines that are common to all targets.\r
7 \r
8 Copyright (c) 2000-2010 by QUALCOMM, Incorporated.  All Rights Reserved.\r
9 *====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/\r
10 \r
11 /*===========================================================================\r
12 \r
13                            Edit History\r
14 \r
15 $Header: //source/qcom/qct/core/pkg/2H09/halcyon_modem/rel/LA2.0/AMSS/products/7x30/core/services/diag/DCM/rtos/src/diagdiag.c#1 $\r
16 \r
17 when       who     what, where, why\r
18 --------   ---     ----------------------------------------------------------\r
19 07/15/10   sg      Moving  diagdiag_memop_tbl_mutex to diagdiag_common.c \r
20 07/10/10   vs      Added support for diagpeek/poke registration API.\r
21 06/22/10   is      Changed external flag FEATURE_VOC_TASK into internal flag\r
22                    DIAG_VOC_TASK.\r
23 06/07/10   is      Mainlined T_MSM3.\r
24 06/03/10   sg      Added FEATURE_VOC_TASK back \r
25 05/10/10   JV      Fix for compile error when FEATURE_DIAG_DISALLOW_MEM_OPS\r
26                    is defined.\r
27 04/29/10   is      Removed functionality for ERR_HAS_NV_LOG_PACKET not defined\r
28 04/20/10   is      Remove support for DIAG_GET_PROPERTY_F, DIAG_PUT_PROPERTY_F,\r
29                    DIAG_GET_PERM_PROPERTY_F, and DIAG_PUT_PERM_PROPERTY_F.\r
30 03/11/10   sg      Cleaning up FEATURE_VOC_TASK feature\r
31 12/28/09   ps      Fixed Klocwork errors & compiler warnings.\r
32 10/29/09   sg      Split file into diagdiag_common and diagdiag.c and moved common\r
33                    functionality to diagdiag_common.c\r
34 \r
35 ===========================================================================*/\r
36 \r
37 #if defined __cplusplus\r
38   extern "C" {\r
39 #endif\r
40 \r
41 #include "comdef.h"\r
42 \r
43 #include "customer.h"\r
44 #include "feature.h"\r
45 \r
46 #include "diagcmd.h"\r
47 #include "diag_v.h"\r
48 #include "diagi_v.h"\r
49 #include "diagdiag_v.h"\r
50 #include "diagbuf.h" /* For diagbuf_flush */\r
51 #include "diagtarget.h"\r
52 \r
53 #include "ts.h"\r
54 #include "hw.h"\r
55 #include "assert.h"\r
56 \r
57 #include "msg.h"\r
58 \r
59 \r
60 \r
61 #include "qw.h"\r
62 \r
63 #include "osal.h"\r
64 #include "diagpkt.h"\r
65 \r
66 \r
67 \r
68 #define DIAGDIAG_MAX_MEM_OP_TBL_SIZE 5\r
69 \r
70 typedef struct\r
71 {\r
72                 uint32 start;\r
73                 uint32 end;\r
74                 const diagpkt_user_table_entry_type * tbl;\r
75                 int count;\r
76 \r
77 }diagdiag_memop_tbl_type;\r
78 \r
79 static diagdiag_memop_tbl_type diagdiag_memop_tbl[DIAGDIAG_MAX_MEM_OP_TBL_SIZE];\r
80 \r
81 \r
82 \r
83 /*==============================================================================\r
84 \r
85 FUNCTION diag_register_memory_address_cb\r
86 \r
87 DESCRIPTION\r
88 \r
89   This function registers a callback function to be invoked for a certain\r
90   range of addresses specified in the parameters in the callback                \r
91 \r
92    \r
93 \r
94 ===============================================================================*/\r
95 \r
96 \r
97 boolean\r
98 diag_register_memory_address_cb (uint32 start, uint32 end,  \r
99                                         const diagpkt_user_table_entry_type * tbl, int count)\r
100 \r
101 {\r
102                 int i = 0;\r
103                 boolean ret = FALSE;\r
104 \r
105         osal_lock_mutex(&diagdiag_memop_tbl_mutex); \r
106 \r
107                 for (i=0; i < DIAGDIAG_MAX_MEM_OP_TBL_SIZE; i++ )  \r
108                 {\r
109                                 if (diagdiag_memop_tbl[i].end == 0) {\r
110                                                 diagdiag_memop_tbl[i].start = start;\r
111                                                 diagdiag_memop_tbl[i].end = end;\r
112                                                 diagdiag_memop_tbl[i].tbl = tbl;   \r
113                                                 diagdiag_memop_tbl[i].count = count;\r
114                                                 ret =  TRUE;\r
115                                                 break;\r
116                                 }\r
117                 }\r
118                 osal_unlock_mutex(&diagdiag_memop_tbl_mutex);\r
119 \r
120                 return ret;\r
121 \r
122 }\r
123 \r
124 \r
125 /*==============================================================================\r
126 \r
127 FUNCTION diag_register_memory_address_cb\r
128 \r
129 DESCRIPTION\r
130 \r
131   This function registers a callback function to be invoked for a certain\r
132   range of addresses specified in the parameters in the callback                \r
133 \r
134    \r
135 \r
136 ===============================================================================*/\r
137 \r
138 \r
139 boolean\r
140 diag_unregister_memory_address_cb (uint32 start, uint32 end,  \r
141                                        const diagpkt_user_table_entry_type * tbl)\r
142 \r
143 {\r
144                 int i = 0;\r
145                 boolean ret = FALSE;\r
146 \r
147                 osal_lock_mutex(&diagdiag_memop_tbl_mutex);\r
148 \r
149                 for (i=0; i < DIAGDIAG_MAX_MEM_OP_TBL_SIZE; i++ )  \r
150                 {\r
151                                 if ((diagdiag_memop_tbl[i].start == start)  && \r
152                                         (diagdiag_memop_tbl[i].end == end) &&\r
153                                         (diagdiag_memop_tbl[i].tbl == tbl))  \r
154                                         {\r
155                                                 diagdiag_memop_tbl[i].start = 0;\r
156                                                 diagdiag_memop_tbl[i].end = 0;   \r
157                                                 diagdiag_memop_tbl[i].tbl = NULL;\r
158                                                 diagdiag_memop_tbl[i].count = 0;\r
159                                                 ret = TRUE;\r
160                                                 break;\r
161                                 }\r
162                 }\r
163 \r
164                 osal_unlock_mutex(&diagdiag_memop_tbl_mutex);\r
165                 \r
166 \r
167                 return ret;\r
168 \r
169 }\r
170 \r
171 \r
172 /*===========================================================================\r
173 \r
174 FUNCTION DIAGDIAG_PEEKB\r
175 \r
176 DESCRIPTION\r
177   This procedure processes a received peek byte request. It performs the peek\r
178   operation and formats a peek response message.\r
179 \r
180 ===========================================================================*/\r
181 PACK(void *) diagdiag_peekb (\r
182   PACK(void *) req_pkt,\r
183   uint16 pkt_len\r
184 )\r
185 {\r
186   DIAG_PEEKB_F_req_type *req = (DIAG_PEEKB_F_req_type *) req_pkt;\r
187   DIAG_PEEKB_F_rsp_type *rsp;\r
188   const int rsp_len = sizeof(DIAG_PEEKB_F_rsp_type);\r
189   int i,j;\r
190   uint16 count;\r
191   PACK(byte *) src = NULL;\r
192   PACK(byte *) dest = NULL;\r
193 \r
194   count = req->length;\r
195   src = (byte *) req->ptr;\r
196 \r
197   /*-------------------------------------------------------------------------\r
198     Check security, since this is a secure funciton\r
199   --------------------------------------------------------------------------*/\r
200   if (diag_get_security_state() != DIAG_SEC_UNLOCKED) {\r
201     return( diagpkt_err_rsp(DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len) );\r
202   }\r
203 \r
204   /*-------------------------------------------------------------------------\r
205     Check memory peek length against max allowable length.\r
206   --------------------------------------------------------------------------*/\r
207   if (count > DIAG_MAX_PEEK_B) {\r
208     return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );\r
209   }\r
210 \r
211 \r
212   /*-------------------------------------------------------------------------\r
213     Check to see if block requested is within a valid range\r
214   --------------------------------------------------------------------------*/\r
215   if (!hw_valid_addr ((void *) src, count) ) {\r
216     return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );\r
217   }\r
218 \r
219 \r
220   for (i=0;i<DIAGDIAG_MAX_MEM_OP_TBL_SIZE;i++) {\r
221                         if ( (diagdiag_memop_tbl[i].start <= (uint32)src) && \r
222                                         (diagdiag_memop_tbl[i].end >= (uint32)src + count * sizeof(byte))) {\r
223                                         for (j = 0; j < diagdiag_memop_tbl[i].count ; j++) {\r
224                                                         if ((diagdiag_memop_tbl[i].tbl[j].cmd_code_lo == DIAG_PEEKB_F) &&\r
225                                                                 (diagdiag_memop_tbl[i].tbl[j].cmd_code_hi == DIAG_PEEKB_F)) {\r
226                                                         rsp = (DIAG_PEEKB_F_rsp_type *) \r
227                                                         diagdiag_memop_tbl[i].tbl[j].func_ptr(req_pkt, pkt_len);\r
228  \r
229                                                         return rsp;\r
230                                         }    \r
231 \r
232                            }\r
233                   \r
234                         }\r
235   }\r
236 \r
237   /* Allocate space for response packet */\r
238   rsp = (DIAG_PEEKB_F_rsp_type *)diagpkt_alloc(DIAG_PEEKB_F, rsp_len);\r
239 \r
240   if (rsp) {\r
241     dest = &rsp->data[0];\r
242 \r
243     /*--------------------------------------------------------------------------\r
244       Fill in the boilerplate for the response.\r
245     --------------------------------------------------------------------------*/\r
246     rsp->ptr      = (byte *) src;\r
247     rsp->length   = count;\r
248 \r
249 \r
250      \r
251     /*----------------------------------------------------------------------\r
252     Lock out interrupts to preserve consistency of the memory block.     */\r
253 \r
254     osal_disable_interrupts();\r
255 \r
256     for (i = 0; i < count; i++) {\r
257       *dest = *src;\r
258        src++;\r
259        dest++;\r
260     }\r
261 \r
262     osal_enable_interrupts();\r
263     \r
264   }\r
265 \r
266   return (rsp);\r
267 \r
268 } /* diagdiag_peekb */\r
269 \r
270 \r
271 \f\r
272 /*===========================================================================\r
273 \r
274 FUNCTION DIAGDIAG_PEEKW\r
275 \r
276 DESCRIPTION\r
277   This procedure processes a received peek word request. It performs the peek\r
278   operation and formats a peek response message.\r
279 \r
280 ===========================================================================*/\r
281 PACK(void *) diagdiag_peekw (\r
282   PACK(void *) req_pkt,\r
283   uint16 pkt_len\r
284 )\r
285 {\r
286   DIAG_PEEKW_F_req_type *req =(DIAG_PEEKW_F_req_type *)req_pkt;\r
287   DIAG_PEEKW_F_rsp_type *rsp;\r
288   const int rsp_len = sizeof(DIAG_PEEKW_F_rsp_type);\r
289   int i,j;\r
290   uint16 count;\r
291   PACK(word *) src = NULL;\r
292   PACK(word *) dest = NULL;\r
293 \r
294   word * src_w;  /* Unpacked word pointer */\r
295   word   val_w;  /* Result of peek */\r
296 \r
297   count = req->length;\r
298   src = (word *) req->ptr;\r
299 \r
300   /*-------------------------------------------------------------------------\r
301     Check security, since this is a secure funciton\r
302   --------------------------------------------------------------------------*/\r
303   if (diag_get_security_state() != DIAG_SEC_UNLOCKED) {\r
304     return( diagpkt_err_rsp(DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len) );\r
305   }\r
306 \r
307   /*-------------------------------------------------------------------------\r
308     Check block length against max allowed length.\r
309   -------------------------------------------------------------------------*/\r
310   if (count > DIAG_MAX_PEEK_W) {\r
311     return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );\r
312   }\r
313 \r
314 \r
315  /*-------------------------------------------------------------------------\r
316     Check to see that the block requested is within a valid range.\r
317   --------------------------------------------------------------------------*/\r
318   if (!hw_valid_addr ((void *) src, (word)(count * sizeof (word)))) {\r
319     return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );\r
320   }\r
321 \r
322   for (i=0;i<DIAGDIAG_MAX_MEM_OP_TBL_SIZE;i++) {\r
323                         if ( (diagdiag_memop_tbl[i].start <= (uint32)src) && \r
324                                         (diagdiag_memop_tbl[i].end >= (uint32)src + count * sizeof(byte))) {\r
325                                         for (j = 0; j < diagdiag_memop_tbl[i].count ; j++) {\r
326                                                         if ((diagdiag_memop_tbl[i].tbl[j].cmd_code_lo == DIAG_PEEKW_F) &&\r
327                                                                 (diagdiag_memop_tbl[i].tbl[j].cmd_code_hi == DIAG_PEEKW_F)) {\r
328                                                         rsp = (DIAG_PEEKW_F_rsp_type *) \r
329                                                                 diagdiag_memop_tbl[i].tbl[j].func_ptr(req_pkt, pkt_len);\r
330 \r
331                                                         return rsp;\r
332                                         }    \r
333 \r
334                                         }\r
335 \r
336 \r
337                         }\r
338   }\r
339 \r
340   /* Allocate space for response packet */\r
341   rsp = (DIAG_PEEKW_F_rsp_type *)diagpkt_alloc(DIAG_PEEKW_F, rsp_len);\r
342 \r
343   if (rsp) {\r
344     dest = &rsp->data[0];\r
345 \r
346     /*--------------------------------------------------------------------------\r
347       Fill in the boilerplate for the response.\r
348     --------------------------------------------------------------------------*/\r
349     rsp->ptr = (word *) src;\r
350     rsp->length = count;\r
351 \r
352     /* Test for alignment. If source address is word aligned, use\r
353        non-packed word transfers. */\r
354     if (((dword)src & 0x1) == 0x00)\r
355     {\r
356       /* Copy packed pointer to non-packed pointer */\r
357       src_w = (word*)src; \r
358 \r
359       /*----------------------------------------------------------------------\r
360        Lock out interrupts to preserve consistency of the memory block.\r
361        ----------------------------------------------------------------------*/\r
362         \r
363       osal_disable_interrupts();\r
364         \r
365       for (i = 0; i < count; i++) {\r
366         val_w = *src_w;\r
367         *dest = val_w;\r
368         src_w++;\r
369         dest++;\r
370       }\r
371         \r
372       osal_enable_interrupts();\r
373         \r
374     }\r
375     else  /* Copy with packed variables */\r
376     {\r
377       /*----------------------------------------------------------------------\r
378        Lock out interrupts to preserve consistency of the memory block.\r
379        ----------------------------------------------------------------------*/\r
380         \r
381       osal_disable_interrupts();\r
382         \r
383       for (i = 0; i < count; i++) {\r
384         *dest = *src;\r
385         src++;\r
386         dest++;\r
387       }\r
388         \r
389       osal_enable_interrupts();\r
390             \r
391     }\r
392   }\r
393 \r
394   return (rsp);\r
395 \r
396 } /* diagdiag_peekw */\r
397 \r
398 \r
399 \f\r
400 /*===========================================================================\r
401 \r
402 FUNCTION DIAGDIAG_PEEKD\r
403 \r
404 DESCRIPTION\r
405   This procedure processes a received peek dword request. It performs the peek\r
406   operation and formats a peek response message.\r
407 \r
408 ===========================================================================*/\r
409 PACK(void *) diagdiag_peekd (\r
410   PACK(void *) req_pkt,\r
411   uint16 pkt_len\r
412 )\r
413 {\r
414   DIAG_PEEKD_F_req_type *req = (DIAG_PEEKD_F_req_type *)req_pkt;\r
415   DIAG_PEEKD_F_rsp_type *rsp;\r
416   const int rsp_len = sizeof(DIAG_PEEKD_F_rsp_type);\r
417   int i,j;\r
418   uint16 count;\r
419   PACK(dword *) src = NULL;\r
420   PACK(dword *) dest = NULL;\r
421 \r
422   dword * src_dw;  /* Unpacked word pointer */\r
423   dword   val_dw;  /* Result of peek */\r
424 \r
425   count = req->length;\r
426   src = (dword *) req->ptr;\r
427 \r
428   /*--------------------------------------------------------------------------\r
429     Check security, since this is a secure funciton\r
430   --------------------------------------------------------------------------*/\r
431   if (diag_get_security_state() != DIAG_SEC_UNLOCKED) {\r
432     return( diagpkt_err_rsp(DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len) );\r
433   }\r
434 \r
435   /*--------------------------------------------------------------------------\r
436     Check requested length against max allowable length.\r
437   --------------------------------------------------------------------------*/\r
438   if (count > DIAG_MAX_PEEK_D) {\r
439     return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );\r
440   }\r
441 \r
442 \r
443   /*-------------------------------------------------------------------------\r
444     Check to see that the block requested is within a valid range.\r
445   --------------------------------------------------------------------------*/\r
446   if (!hw_valid_addr ((void *) src, (word)(count * sizeof(dword)))) {\r
447     return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );\r
448   }\r
449 \r
450   for (i=0;i<DIAGDIAG_MAX_MEM_OP_TBL_SIZE;i++) {\r
451                         if ( (diagdiag_memop_tbl[i].start <= (uint32)src) && \r
452                                         (diagdiag_memop_tbl[i].end >= (uint32)src + count * sizeof(byte))) {\r
453                                         for (j = 0; j < diagdiag_memop_tbl[i].count ; j++) {\r
454                                                         if ((diagdiag_memop_tbl[i].tbl[j].cmd_code_lo == DIAG_PEEKD_F) &&\r
455                                                                 (diagdiag_memop_tbl[i].tbl[j].cmd_code_hi == DIAG_PEEKD_F)) {\r
456                                                         rsp = (DIAG_PEEKD_F_rsp_type *) \r
457                                                                 diagdiag_memop_tbl[i].tbl[j].func_ptr(req_pkt, pkt_len);\r
458 \r
459                                                         return rsp;\r
460                                         }    \r
461 \r
462                                         }\r
463 \r
464 \r
465                         }\r
466   }\r
467 \r
468   /* Allocate space for response packet */\r
469   rsp = (DIAG_PEEKD_F_rsp_type *)diagpkt_alloc(DIAG_PEEKD_F, rsp_len);\r
470 \r
471   if (rsp) {\r
472     dest = &rsp->data[0];\r
473 \r
474     /*--------------------------------------------------------------------------\r
475       Fill in the boilerplate for the response.\r
476     --------------------------------------------------------------------------*/\r
477     rsp->ptr      = (dword *) src;\r
478     rsp->length   = count;\r
479 \r
480 \r
481     /* Test for alignment. If source address is dword aligned, use\r
482        non-packed dword transfers. */\r
483     if (((dword)src & 0x3) == 0x00)\r
484     {\r
485       /* Copy packed pointer to non-packed pointer */\r
486       src_dw = (dword*)src; \r
487 \r
488       /*----------------------------------------------------------------------\r
489         Lock out interrupts to preserve consistency of the memory block.\r
490         ----------------------------------------------------------------------*/\r
491         \r
492       osal_disable_interrupts();\r
493        \r
494       for (i = 0; i < count; i++) {\r
495         val_dw = *src_dw;\r
496         *dest = val_dw;\r
497         src_dw++;\r
498         dest++;\r
499       }\r
500         \r
501       osal_enable_interrupts();\r
502         \r
503       }\r
504       else  /* Copy with packed variables */\r
505       {\r
506         /*----------------------------------------------------------------------\r
507           Lock out interrupts to preserve consistency of the memory block.\r
508         ----------------------------------------------------------------------*/\r
509         \r
510         osal_disable_interrupts();\r
511         \r
512         for (i = 0; i < count; i++) {\r
513           *dest = *src;\r
514           dest++;\r
515           src++;\r
516         }\r
517         \r
518         osal_enable_interrupts();\r
519         \r
520       }\r
521   }\r
522 \r
523   return (rsp);\r
524 \r
525 } /* diagdiag_peekd */\r
526 \r
527 \r
528 \f\r
529 /*===========================================================================\r
530 \r
531 FUNCTION DIAGDIAG_POKEB\r
532 \r
533 DESCRIPTION\r
534   This procedure pokes a byte into memory and formats a poke response\r
535   buffer.\r
536 \r
537 ===========================================================================*/\r
538 PACK(void *) diagdiag_pokeb (\r
539   PACK(void *) req_pkt,\r
540   uint16 pkt_len\r
541 )\r
542 {\r
543   DIAG_POKEB_F_req_type *req = (DIAG_POKEB_F_req_type *)req_pkt;\r
544   DIAG_POKEB_F_rsp_type *rsp;\r
545   const int rsp_len = sizeof(DIAG_POKEB_F_rsp_type);\r
546   int i,j;\r
547   uint16 count;\r
548   PACK(byte *) src = NULL;\r
549   PACK(byte *) dest = NULL;\r
550 \r
551   count = req->length;\r
552   src = &req->data[0];\r
553   dest = req->ptr;\r
554 \r
555   /*----------------------------------------------------------------------\r
556     Check length of request packet.\r
557   ----------------------------------------------------------------------*/\r
558   if (pkt_len != sizeof (DIAG_POKEB_F_req_type))\r
559   {\r
560     return (diagpkt_err_rsp (DIAG_BAD_LEN_F, req_pkt, pkt_len));\r
561   }\r
562 \r
563   /*----------------------------------------------------------------------\r
564     Check security, since this is a secure funciton\r
565   ----------------------------------------------------------------------*/\r
566   if (diag_get_security_state() != DIAG_SEC_UNLOCKED) {\r
567     return( diagpkt_err_rsp(DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len) );\r
568   }\r
569 \r
570   /*----------------------------------------------------------------------\r
571     Check block size against maximum allowable block size.\r
572   ----------------------------------------------------------------------*/\r
573   if (count > DIAG_MAX_POKE_B) {\r
574     return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );\r
575   }\r
576 \r
577 \r
578   /*---------------------------------------------------------------------\r
579     Check to see if address requested is within a valid range.\r
580   ----------------------------------------------------------------------*/\r
581   else if (!hw_valid_addr ((void *) dest, count * sizeof (byte))) {\r
582     return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );\r
583   }\r
584 \r
585   for (i=0;i<DIAGDIAG_MAX_MEM_OP_TBL_SIZE;i++) {\r
586                         if ( (diagdiag_memop_tbl[i].start <= (uint32)src) && \r
587                                         (diagdiag_memop_tbl[i].end >= (uint32)src + count * sizeof(byte))) {\r
588                                         for (j = 0; j <  diagdiag_memop_tbl[i].count ; j++) {\r
589                                                         if ((diagdiag_memop_tbl[i].tbl[j].cmd_code_lo == DIAG_POKEB_F) &&\r
590                                                                 (diagdiag_memop_tbl[i].tbl[j].cmd_code_hi == DIAG_POKEB_F)) {\r
591                                                         rsp = (DIAG_POKEB_F_rsp_type *) \r
592                                                                 diagdiag_memop_tbl[i].tbl[j].func_ptr(req_pkt, pkt_len);\r
593 \r
594                                                         return rsp;\r
595                                         }    \r
596 \r
597                                         }\r
598 \r
599 \r
600                         }\r
601   }\r
602     /*----------------------------------------------------------------------\r
603       Lock out interrupts to preserve consistency of the memory block.\r
604     ----------------------------------------------------------------------*/\r
605    \r
606     osal_disable_interrupts();\r
607     \r
608 \r
609     for (i = 0; i < count; i++) {\r
610       *dest = *src;\r
611         src++;\r
612       dest++;      \r
613     }\r
614     \r
615     osal_enable_interrupts();\r
616    \r
617 \r
618 \r
619   /*-------------------------------------------------------------------------\r
620    Prepare the response packet.\r
621   -------------------------------------------------------------------------*/\r
622   rsp = (DIAG_POKEB_F_rsp_type *)diagpkt_alloc(DIAG_POKEB_F, rsp_len);\r
623 \r
624   if (rsp)\r
625   {\r
626     *rsp = *req;\r
627   }\r
628 \r
629   return (rsp);\r
630 \r
631 } /* diagdiag_pokeb */\r
632 \r
633 \f\r
634 /*===========================================================================\r
635 \r
636 FUNCTION DIAGDIAG_POKEW\r
637 \r
638 DESCRIPTION\r
639   This procedure pokes a word into memory and formats a poke response\r
640   message.\r
641 \r
642 ===========================================================================*/\r
643 PACK(void *) diagdiag_pokew (\r
644   PACK(void *) req_pkt,\r
645   uint16 pkt_len\r
646 )\r
647 {\r
648   DIAG_POKEW_F_req_type *req = (DIAG_POKEW_F_req_type *)req_pkt;\r
649   DIAG_POKEW_F_rsp_type *rsp;\r
650   const int rsp_len = sizeof(DIAG_POKEW_F_rsp_type);\r
651   int i,j;\r
652   uint16 count;\r
653   PACK(word *) src = NULL;\r
654   PACK(word *) dest = NULL;\r
655 \r
656   word * dest_w; /* Unpacked word pointer */\r
657   word   val_w;  /* Value to poke */\r
658   \r
659   count = req->length;\r
660   src = &req->data[0];\r
661   dest = req->ptr;\r
662 \r
663   /*----------------------------------------------------------------------\r
664     Check length of request packet.  This is critical since the download\r
665     protocol used by QPST uses HDLC encoded packets with the equivalent\r
666     of command code 6.  Length check is the only thing that prevents\r
667     accidental pokes!\r
668   ----------------------------------------------------------------------*/\r
669   if (pkt_len != sizeof (DIAG_POKEW_F_req_type))\r
670   {\r
671     return (diagpkt_err_rsp (DIAG_BAD_LEN_F, req_pkt, pkt_len));\r
672   }\r
673 \r
674   /*----------------------------------------------------------------------\r
675     Check security, since this is a secure funciton\r
676   ----------------------------------------------------------------------*/\r
677   if (diag_get_security_state() != DIAG_SEC_UNLOCKED) {\r
678     return( diagpkt_err_rsp(DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len) );\r
679   }\r
680 \r
681   /*----------------------------------------------------------------------\r
682     Check block length against maximum allowable length.\r
683   ----------------------------------------------------------------------*/\r
684   if (count > DIAG_MAX_POKE_W) {\r
685     return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );\r
686   }\r
687 \r
688 \r
689   /*----------------------------------------------------------------------\r
690     Check to be sure the block is a valid block.\r
691   ----------------------------------------------------------------------*/\r
692   if (!hw_valid_addr ((void *) dest, (word)(count * sizeof (word)))) {\r
693     return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );\r
694   }\r
695 \r
696   for (i=0;i<DIAGDIAG_MAX_MEM_OP_TBL_SIZE;i++) {\r
697                         if ( (diagdiag_memop_tbl[i].start <= (uint32)src) && \r
698                                         (diagdiag_memop_tbl[i].end >= (uint32)src + count * sizeof(byte))) {\r
699                                         for (j = 0; j < diagdiag_memop_tbl[i].count; j++) {\r
700                                                         if ((diagdiag_memop_tbl[i].tbl[j].cmd_code_lo == DIAG_POKEW_F) &&\r
701                                                                  (diagdiag_memop_tbl[i].tbl[j].cmd_code_hi == DIAG_POKEW_F)) {\r
702                                                             rsp = (DIAG_POKEW_F_rsp_type *) \r
703                                                                   diagdiag_memop_tbl[i].tbl[j].func_ptr(req_pkt, pkt_len);\r
704 \r
705                                                         return rsp;\r
706                                         }    \r
707 \r
708                                         }\r
709 \r
710 \r
711                         }\r
712 \r
713 \r
714    }\r
715     /* Test for alignment. If destination address is word aligned, use\r
716        non-packed word transfers. */\r
717     if (((dword)dest & 0x01) == 0x00)\r
718     {\r
719       /* Copy packed pointer to non-packed pointer */\r
720       dest_w = (word*)dest; \r
721 \r
722       /*----------------------------------------------------------------------\r
723         Lock out interrupts to preserve consistency of the memory block.\r
724       ----------------------------------------------------------------------*/\r
725     \r
726       osal_disable_interrupts();\r
727       \r
728       for (i = 0; i < count; i++) {\r
729         val_w = *src;\r
730         *dest_w = val_w;\r
731         dest_w++;\r
732         src++;\r
733       }\r
734       \r
735       osal_enable_interrupts();\r
736      \r
737     }\r
738     else  /*  Copy with packed variables */\r
739     {\r
740       /*----------------------------------------------------------------------\r
741         Lock out interrupts to preserve consistency of the memory block.\r
742       ----------------------------------------------------------------------*/\r
743       \r
744       osal_disable_interrupts();\r
745       \r
746       for (i = 0; i < count; i++) {\r
747         *dest = *src;\r
748         src++;\r
749         dest++;        \r
750       }\r
751       \r
752       osal_enable_interrupts();\r
753       \r
754     }\r
755 \r
756 \r
757   /*----------------------------------------------------------------------\r
758     Prepare the response packet.\r
759   ----------------------------------------------------------------------*/\r
760   rsp = (DIAG_POKEW_F_rsp_type *)diagpkt_alloc(DIAG_POKEW_F, rsp_len);\r
761 \r
762   if (rsp)\r
763   {\r
764     *rsp = *req;\r
765   }\r
766 \r
767   return (rsp);\r
768 \r
769 } /* diagdiag_pokew */\r
770 \r
771 \r
772 \f\r
773 /*===========================================================================\r
774 \r
775 FUNCTION DIAGDIAG_POKED\r
776 \r
777 DESCRIPTION\r
778   This procedure pokes a dword into memory and formats a poke response\r
779   message.\r
780 \r
781 ===========================================================================*/\r
782 PACK(void *) diagdiag_poked (\r
783   PACK(void *) req_pkt,\r
784   uint16 pkt_len\r
785 )\r
786 {\r
787   DIAG_POKED_F_req_type *req = (DIAG_POKED_F_req_type *)req_pkt;\r
788   DIAG_POKED_F_rsp_type *rsp;\r
789   const int rsp_len = sizeof(DIAG_POKED_F_rsp_type);\r
790   int i,j;\r
791   uint16 count;\r
792   PACK(dword *) src = NULL;\r
793   PACK(dword *) dest = NULL;\r
794 \r
795   dword * dest_dw; /* Unpacked dword pointer */\r
796   dword   val_dw;  /* Value to poke */\r
797 \r
798 \r
799   count = req->length;\r
800   src = &req->data[0];\r
801   dest = req->ptr;\r
802 \r
803   /*----------------------------------------------------------------------\r
804     Check length of request packet.\r
805   ----------------------------------------------------------------------*/\r
806   if (pkt_len != sizeof (DIAG_POKED_F_req_type))\r
807   {\r
808     return (diagpkt_err_rsp (DIAG_BAD_LEN_F, req_pkt, pkt_len));\r
809   }\r
810 \r
811   /*----------------------------------------------------------------------\r
812     Check security, since this is a secure funciton\r
813   ----------------------------------------------------------------------*/\r
814   if (diag_get_security_state() != DIAG_SEC_UNLOCKED) {\r
815     return( diagpkt_err_rsp(DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len) );\r
816   }\r
817 \r
818   /*----------------------------------------------------------------------\r
819     Check block length against maximum allowed length.\r
820   ----------------------------------------------------------------------*/\r
821   if (count > DIAG_MAX_POKE_D) {\r
822     return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );\r
823   }\r
824 \r
825 \r
826   /*----------------------------------------------------------------------\r
827     Check to see that requested block is a valid block.\r
828   ----------------------------------------------------------------------*/\r
829   if (!hw_valid_addr ((void *) dest, (word)(count * sizeof (dword))) ) {\r
830     return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );\r
831   }\r
832 \r
833 \r
834   for (i=0;i<DIAGDIAG_MAX_MEM_OP_TBL_SIZE;i++) {\r
835                         if ( (diagdiag_memop_tbl[i].start <= (uint32)src) && \r
836                                         (diagdiag_memop_tbl[i].end >= (uint32)src + count * sizeof(byte))) {\r
837                                         for (j = 0; j < diagdiag_memop_tbl[i].count; j++) {\r
838                                                         if ((diagdiag_memop_tbl[i].tbl[j].cmd_code_lo == DIAG_POKED_F) &&\r
839                                                                 (diagdiag_memop_tbl[i].tbl[j].cmd_code_hi == DIAG_POKED_F)) {\r
840                                                         rsp = (DIAG_POKED_F_rsp_type *) \r
841                                                                 diagdiag_memop_tbl[i].tbl[j].func_ptr(req_pkt, pkt_len);\r
842 \r
843                                                         return rsp;\r
844                                         }    \r
845 \r
846                                         }\r
847 \r
848 \r
849                         }\r
850   }\r
851 \r
852     /* Test for alignment. If destination address is dword aligned, use\r
853        non-packed dword transfers. */\r
854     if (((dword)dest & 0x03) == 0x00)\r
855     {\r
856       /* Copy packed pointer to non-packed pointer */\r
857       dest_dw = (dword*)dest; \r
858 \r
859       /*----------------------------------------------------------------------\r
860         Lock out interrupts to preserve consistency of the memory block.\r
861       ----------------------------------------------------------------------*/\r
862       \r
863       osal_disable_interrupts();\r
864 \r
865       \r
866       for (i = 0; i < count; i++) {\r
867         val_dw = *src;\r
868         *dest_dw = val_dw;\r
869         dest_dw++;\r
870         src++;\r
871       }\r
872      \r
873       osal_enable_interrupts();\r
874       \r
875     }\r
876     else  /*  Copy with packed variables */\r
877     {\r
878  \r
879       /*----------------------------------------------------------------------\r
880         Lock out interrupts to preserve consistency of the memory block.  */\r
881      \r
882       osal_disable_interrupts();\r
883     \r
884       for (i = 0; i < count; i++) {\r
885         *dest = *src;\r
886         src++;\r
887         dest++;        \r
888       }\r
889      \r
890       osal_enable_interrupts();\r
891      \r
892         }\r
893 \r
894   /*-----------------------------------------------------------------------\r
895    Prepare the response packet.\r
896   -----------------------------------------------------------------------*/\r
897   rsp = (DIAG_POKED_F_rsp_type *)diagpkt_alloc(DIAG_POKED_F, rsp_len);\r
898 \r
899   if (rsp)\r
900   {\r
901     *rsp = *req;\r
902   }\r
903 \r
904   return (rsp);\r
905 \r
906 } /* diagdiag_poked */\r
907 \r
908 \r
909 \r
910 \f\r
911 /*===========================================================================\r
912 \r
913 FUNCTION DIAGDIAG_VER\r
914 \r
915 DESCRIPTION\r
916   Return the diag version\r
917 \r
918 ===========================================================================*/\r
919 PACK(void *) diagdiag_ver (\r
920   PACK(void *) req_pkt,\r
921   uint16 pkt_len\r
922 )\r
923 {\r
924   DIAG_DIAG_VER_F_rsp_type *rsp;\r
925   const int rsp_len = sizeof (DIAG_DIAG_VER_F_rsp_type);\r
926 \r
927   (void) req_pkt; /* suppress compiler warning */\r
928   (void) pkt_len; /* suppress compiler warning */\r
929 \r
930   rsp = (DIAG_DIAG_VER_F_rsp_type *)diagpkt_alloc(DIAG_DIAG_VER_F, rsp_len);\r
931 \r
932   /*-------------------------------------------------------------------------\r
933     Return diag source code version\r
934   -------------------------------------------------------------------------*/\r
935   if (rsp)\r
936   {\r
937     rsp->ver = DIAG_DIAGVER;\r
938   }\r
939   return (rsp);\r
940 \r
941 } /* diagdiag_diag_ver */\r
942 \r
943 \r
944 \f\r
945 /*===========================================================================\r
946 \r
947 FUNCTION DIAGDIAG_FEATURE_QUERY\r
948 \r
949 DESCRIPTION\r
950   This procedure processes a request to query for features in the current\r
951   build.  It returns a variable length bit mask where each bit corresponds to\r
952   a particular feature defined in diagpkt.h in feature_query_enum_type.\r
953 \r
954 ============================================================================*/\r
955 PACK(void *) diagdiag_feature_query (\r
956   PACK(void *) req_pkt,\r
957   uint16 pkt_len\r
958 )\r
959 {\r
960 \r
961   DIAG_FEATURE_QUERY_F_rsp_type *rsp;\r
962   const int rsp_len = sizeof(DIAG_FEATURE_QUERY_F_rsp_type);\r
963 \r
964   (void) req_pkt; /* suppress compiler warning */\r
965   (void) pkt_len; /* suppress compiler warning */\r
966 \r
967   rsp =(DIAG_FEATURE_QUERY_F_rsp_type *)diagpkt_alloc(DIAG_FEATURE_QUERY_F, rsp_len);\r
968   if (rsp)\r
969   {\r
970         rsp->feature_mask_size = FEATURE_MASK_LENGTH;\r
971 \r
972         /* Copy the current mask into the diag pkt */\r
973         memcpy( (void *) rsp->feature_mask,\r
974           diag_feature_mask,\r
975           FEATURE_MASK_LENGTH\r
976         );\r
977   }\r
978   /* return the size of the variable length packet.  command_code and\r
979   ** feature_mask_size is constant.  FEATURE_MASK_LENGTH changes\r
980   ** as more features are added\r
981   */\r
982   return (rsp);\r
983 \r
984 \r
985 } /* diagdiag_feature_query */\r
986 \r
987 \r
988 \f\r
989 /*===========================================================================\r
990 \r
991 FUNCTION DIAGDIAG_PASSWORD\r
992 \r
993 DESCRIPTION\r
994   Processes an entry of the Security Password.\r
995   This function compares the password in the phone to what was sent in\r
996   the packet.  If they are the same, the successful Security unlock is\r
997   noted (setting the diag_get_security_state() mask to UNLOCKED), and a value of TRUE\r
998   is returned to the external device.\r
999   If they are NOT the same, Security remains locked, a value of FALSE is\r
1000   returned to the external device, and the phone is powered off,\r
1001   to deter hackers.\r
1002 \r
1003 SIDE EFFECTS\r
1004   May cause the phone to power off!  (After returning from this routine).\r
1005 \r
1006 ===========================================================================*/\r
1007 PACK(void *) diagdiag_password (\r
1008   PACK(void *) req_pkt,\r
1009   uint16 pkt_len\r
1010 )\r
1011 {\r
1012   DIAG_PASSWORD_F_req_type *req = (DIAG_PASSWORD_F_req_type *) req_pkt;\r
1013   DIAG_PASSWORD_F_rsp_type *rsp;\r
1014   const int rsp_len = sizeof(DIAG_PASSWORD_F_rsp_type);\r
1015   (void) pkt_len; /* suppress compiler warning */\r
1016 \r
1017   rsp = (DIAG_PASSWORD_F_rsp_type *) diagpkt_alloc (DIAG_PASSWORD_F, rsp_len);\r
1018 \r
1019 /*------------------------------------------------------------------------*/\r
1020 \r
1021   MSG_LOW ("Security Password given", 0, 0, 0);\r
1022 \r
1023   /* If the security is already unlocked, then it doesn't matter what\r
1024   ** you give as the security code.  Otherwise we need to compare\r
1025   ** the given security code with the one in the phone.\r
1026   */\r
1027   if (rsp)\r
1028   {\r
1029           if ((diag_get_security_state() == DIAG_SEC_UNLOCKED) ||\r
1030               (diag_check_password((void *) req->password))) {\r
1031 \r
1032             rsp->password_ok = TRUE;\r
1033             (void) diag_set_security_state(DIAG_SEC_UNLOCKED);\r
1034           }\r
1035           /* Otherwise, the code was incorrect.  Diag will now powerdown the phone.\r
1036           */\r
1037           else {\r
1038             rsp->password_ok = FALSE;\r
1039             (void) diag_set_security_state(DIAG_SEC_LOCKED);\r
1040 \r
1041             diagpkt_commit(rsp);\r
1042             rsp = NULL;\r
1043 \r
1044             /* Flush DIAG's TX buffer */\r
1045             diagbuf_flush();\r
1046 \r
1047             /* Power down the phone.  This function does not return.\r
1048             */\r
1049             diag_powerdown();\r
1050           }\r
1051         }\r
1052   return (rsp);\r
1053 \r
1054 } /* diagdiag_password */\r
1055 \r
1056 \r
1057 \f\r
1058 /*===========================================================================\r
1059 FUNCTION DIAGDIAG_TS\r
1060 \r
1061 DESCRIPTION\r
1062   Return an IS-95/IS-2000 timestamp\r
1063 \r
1064 DEPENDENCIES\r
1065   None.\r
1066 \r
1067 RETURN VALUE\r
1068   Pointer to response packet.\r
1069 \r
1070 SIDE EFFECTS\r
1071   None.\r
1072 ===========================================================================*/\r
1073 PACK(void *) diagdiag_ts (\r
1074   PACK(void *) req_pkt,\r
1075   uint16 pkt_len\r
1076 )\r
1077 {\r
1078   qword ts_time;                 /* time stamp */\r
1079   DIAG_TS_F_rsp_type *rsp;\r
1080   const int rsp_len = sizeof( DIAG_TS_F_rsp_type );\r
1081 \r
1082   (void) req_pkt; /* suppress compiler warning */\r
1083   (void) pkt_len; /* suppress compiler warning */\r
1084 \r
1085 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/\r
1086   /*------------------------------------------------------------------------\r
1087     Get the time, stuff the packet.\r
1088   -------------------------------------------------------------------------*/\r
1089 \r
1090   ts_get (ts_time);\r
1091 \r
1092 \r
1093   rsp = (DIAG_TS_F_rsp_type *) diagpkt_alloc (DIAG_TS_F, rsp_len);\r
1094 \r
1095   qw_equ_misaligned (rsp->ts, ts_time);\r
1096 \r
1097   return (rsp);\r
1098 \r
1099 } /* diagdiag_ts */\r
1100 \r
1101 \r
1102 \f\r
1103 \r
1104 #define MSM_MEMMAP_IO_OFFSET 0x03000000\r
1105 \r
1106 /*===========================================================================\r
1107 \r
1108 FUNCTION DIAGDIAG_OUTP\r
1109 \r
1110 DESCRIPTION\r
1111   This procedure processes a received command to write a byte to a port.\r
1112   The byte is written to the input port and a response packet is built.\r
1113 \r
1114 DEPENDENCIES\r
1115   None.\r
1116 \r
1117 RETURN VALUE\r
1118   Pointer to response packet.\r
1119 \r
1120 SIDE EFFECTS\r
1121   None.\r
1122 \r
1123 ===========================================================================*/\r
1124 PACK(void *) diagdiag_outp (\r
1125   PACK(void *) req_pkt,\r
1126   uint16 pkt_len\r
1127 )\r
1128 {\r
1129   DIAG_OUTP_F_rsp_type *rsp;\r
1130   const int rsp_len = sizeof( DIAG_OUTP_F_rsp_type );\r
1131   DIAG_OUTP_F_req_type *req = (DIAG_OUTP_F_req_type *) req_pkt;\r
1132 \r
1133   /*----------------------------------------------------------------------\r
1134     Check security, since this is a secure function\r
1135   ----------------------------------------------------------------------*/\r
1136   if (diag_get_security_state() == DIAG_SEC_LOCKED) {\r
1137     rsp = (DIAG_OUTP_F_rsp_type *)diagpkt_err_rsp( DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len );\r
1138     return rsp;\r
1139   }\r
1140 \r
1141   /*----------------------------------------------------------------------\r
1142     Write byte to port\r
1143   ----------------------------------------------------------------------*/\r
1144   (void) outp( req->port + MSM_MEMMAP_IO_OFFSET, req->data );\r
1145 \r
1146   /*-----------------------------------------------------------------------\r
1147     Prepare the response packet.\r
1148   -----------------------------------------------------------------------*/\r
1149   /* Allocate space for rsponse packet */\r
1150   rsp = (DIAG_OUTP_F_rsp_type *)diagpkt_alloc( DIAG_OUTP_F, rsp_len );\r
1151 \r
1152   if (rsp)\r
1153   {\r
1154     rsp->port = req->port;\r
1155     rsp->data = req->data;\r
1156   }\r
1157 \r
1158   return (rsp);\r
1159 \r
1160 } /* diagdiag_outp */\r
1161 \r
1162 \r
1163 \f\r
1164 /*===========================================================================\r
1165 \r
1166 FUNCTION DIAGDIAG_OUTPW\r
1167 \r
1168 DESCRIPTION\r
1169   This procedure processes a received command to write a word to a port.\r
1170   The word is written to the input port and a response packet is built.\r
1171 \r
1172 DEPENDENCIES\r
1173   None.\r
1174 \r
1175 RETURN VALUE\r
1176   Pointer to response packet.\r
1177 \r
1178 SIDE EFFECTS\r
1179   None.\r
1180 \r
1181 ===========================================================================*/\r
1182 PACK(void *) diagdiag_outpw (\r
1183   PACK(void *) req_pkt,\r
1184   uint16 pkt_len\r
1185 )\r
1186 {\r
1187   DIAG_OUTPW_F_rsp_type *rsp;\r
1188   const int rsp_len = sizeof( DIAG_OUTPW_F_rsp_type );\r
1189   DIAG_OUTPW_F_req_type *req = (DIAG_OUTPW_F_req_type *) req_pkt;\r
1190 \r
1191   /*----------------------------------------------------------------------\r
1192     Check security, since this is a secure funciton\r
1193   ----------------------------------------------------------------------*/\r
1194   if (diag_get_security_state() == DIAG_SEC_LOCKED) {\r
1195     rsp = (DIAG_OUTPW_F_rsp_type *)diagpkt_err_rsp( DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len );\r
1196     return rsp;\r
1197   }\r
1198 \r
1199   /*----------------------------------------------------------------------\r
1200     Write word to port\r
1201   ----------------------------------------------------------------------*/\r
1202   (void) outpw( req->port+ MSM_MEMMAP_IO_OFFSET, req->data );\r
1203 \r
1204   /*-----------------------------------------------------------------------\r
1205     Prepare the response packet.\r
1206   -----------------------------------------------------------------------*/\r
1207   /* Allocate space for rsponse packet */\r
1208   rsp = (DIAG_OUTPW_F_rsp_type *)diagpkt_alloc( DIAG_OUTPW_F, rsp_len );\r
1209 \r
1210   if (rsp)\r
1211   {\r
1212     rsp->port = req->port;\r
1213     rsp->data = req->data;\r
1214   }\r
1215 \r
1216   return (rsp);\r
1217 \r
1218 } /* diagdiag_outpw */\r
1219 \r
1220 \r
1221 \f\r
1222 /*===========================================================================\r
1223 \r
1224 FUNCTION DIAGDIAG_INP\r
1225 \r
1226 DESCRIPTION\r
1227   This procedure processes a received command to read a byte from a port.\r
1228   The byte is read from the port and a response packet is built.\r
1229 \r
1230 DEPENDENCIES\r
1231   None.\r
1232 \r
1233 RETURN VALUE\r
1234   Pointer to response packet.\r
1235 \r
1236 SIDE EFFECTS\r
1237   None.\r
1238 \r
1239 ===========================================================================*/\r
1240 PACK(void *) diagdiag_inp (\r
1241   PACK(void *) req_pkt,\r
1242   uint16 pkt_len\r
1243 )\r
1244 {\r
1245   DIAG_INP_F_rsp_type *rsp;\r
1246   const int rsp_len = sizeof( DIAG_INP_F_rsp_type );\r
1247   DIAG_INP_F_req_type *req = (DIAG_INP_F_req_type *) req_pkt;\r
1248 \r
1249   /*----------------------------------------------------------------------\r
1250     Check security, since this is a secure funciton\r
1251   ----------------------------------------------------------------------*/\r
1252   if (diag_get_security_state() == DIAG_SEC_LOCKED) {\r
1253     rsp = ( DIAG_INP_F_rsp_type *)diagpkt_err_rsp( DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len );\r
1254     return rsp;\r
1255   }\r
1256 \r
1257   /* Allocate space for rsponse packet */\r
1258   rsp = (DIAG_INP_F_rsp_type *)diagpkt_alloc( DIAG_INP_F, rsp_len );\r
1259 \r
1260   /*------------------------------------------------------------------------\r
1261     Fill in the boilerplate for the response packet, then read the byte in\r
1262     from the port.\r
1263   ------------------------------------------------------------------------*/\r
1264   if (rsp)\r
1265   {\r
1266     rsp->port = req->port;\r
1267     rsp->data = (byte) inp( req->port + MSM_MEMMAP_IO_OFFSET );\r
1268   }\r
1269   return (rsp);\r
1270 \r
1271 } /* diagdiag_inp */\r
1272 \r
1273 \r
1274 \f\r
1275 /*===========================================================================\r
1276 \r
1277 FUNCTION DIAGDIAG_INPW\r
1278 \r
1279 DESCRIPTION\r
1280   This procedure processes a received command to read a word from a port.\r
1281   The word is read from the port and a response packet is built.\r
1282 \r
1283 DEPENDENCIES\r
1284   None.\r
1285 \r
1286 RETURN VALUE\r
1287   Pointer to response packet.\r
1288 \r
1289 SIDE EFFECTS\r
1290   None.\r
1291 \r
1292 ===========================================================================*/\r
1293 PACK(void *) diagdiag_inpw (\r
1294   PACK(void *) req_pkt,\r
1295   uint16 pkt_len\r
1296 )\r
1297 {\r
1298   DIAG_INPW_F_rsp_type *rsp;\r
1299   const int rsp_len = sizeof( DIAG_INPW_F_rsp_type );\r
1300   DIAG_INPW_F_req_type *req = (DIAG_INPW_F_req_type *) req_pkt;\r
1301 \r
1302   /*----------------------------------------------------------------------\r
1303     Check security, since this is a secure funciton\r
1304   ----------------------------------------------------------------------*/\r
1305   if (diag_get_security_state() == DIAG_SEC_LOCKED) {\r
1306     rsp = (DIAG_INPW_F_rsp_type *)diagpkt_err_rsp( DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len );\r
1307     return rsp;\r
1308   }\r
1309 \r
1310   /* Allocate space for rsponse packet */\r
1311   rsp = (DIAG_INPW_F_rsp_type *)diagpkt_alloc( DIAG_INPW_F, rsp_len );\r
1312 \r
1313   /*------------------------------------------------------------------------\r
1314     Fill in the boilerplate for the response, then input the word directly\r
1315     into the response packet.\r
1316   -------------------------------------------------------------------------*/\r
1317   if (rsp)\r
1318   {\r
1319         rsp->port = req->port;\r
1320         rsp->data = inpw( req->port + MSM_MEMMAP_IO_OFFSET );\r
1321   }\r
1322   return (rsp);\r
1323 \r
1324 } /* diagdiag_inpw */\r
1325 \r
1326 #if 1 //For now, use a fake GUID. -LD\r
1327 /* Default GUID (since it was unspecified) */\r
1328 static const diag_guid_type diag_guid =\r
1329 {\r
1330    0xDEADD00DU,\r
1331    0xDEADD00DU,\r
1332    0xDEADD00DU,\r
1333    0x06101975\r
1334 };\r
1335 #endif\r
1336 \r
1337 \r
1338 LOCAL diag_prop_struct_type diag_prop_table[DIAG_MAX_NUM_PROPS];\r
1339 \r
1340 /*===========================================================================\r
1341 \r
1342 FUNCTION DIAG_LOOKUP_PROP\r
1343 \r
1344 DESCRIPTION\r
1345   Looks up the address of a callback function given its name.\r
1346 \r
1347 DEPENDENCIES\r
1348   None.\r
1349 \r
1350 RETURN VALUE\r
1351   The address of the function or NULL if the function is not found in the\r
1352   function table.\r
1353 \r
1354 SIDE EFFECTS\r
1355   None.\r
1356 \r
1357 ===========================================================================*/\r
1358 void *diag_lookup_prop\r
1359 (\r
1360   char *prop_name\r
1361 )\r
1362 {\r
1363   int i = 0;\r
1364 \r
1365   if ( prop_name == NULL )\r
1366   {\r
1367     return (void *) NULL;\r
1368   }\r
1369 \r
1370   while ( diag_prop_table[ i ].name != NULL )\r
1371   {\r
1372     if ( strncmp(\r
1373                  diag_prop_table[ i ].name,\r
1374                  prop_name,\r
1375                  DIAG_MAX_PROPERTY_NAME_SIZE\r
1376          ) == 0 )\r
1377     {\r
1378       return diag_prop_table[ i ].address;\r
1379     }\r
1380     i++;\r
1381     if ( i >= DIAG_MAX_NUM_PROPS )\r
1382     {\r
1383       /*\r
1384       ** Will get here only if the properties table has been corrupted.\r
1385       */\r
1386       break;\r
1387     }\r
1388   }\r
1389   return (void *) NULL;\r
1390 } /* diag_lookup_prop */\r
1391 \r
1392 \r
1393 \f\r
1394 /*===========================================================================\r
1395 \r
1396 FUNCTION DIAG_GUID_IS_VALID\r
1397 \r
1398 DESCRIPTION\r
1399   This static function returns true or false depending on whether the\r
1400   input guid (globally unique identifier) matches that of the current build.\r
1401 \r
1402 DEPENDENCIES\r
1403   None.\r
1404 \r
1405 RETURN VALUE\r
1406   TRUE if the input guid is valid, FALSE otherwise.\r
1407 \r
1408 SIDE EFFECTS\r
1409   None.\r
1410 \r
1411 ===========================================================================*/\r
1412 LOCAL boolean diag_guid_is_valid\r
1413 (\r
1414   diag_guid_type guid\r
1415 )\r
1416 {\r
1417   if ( ( guid[ 0 ] == diag_guid[ 0 ] ) &&\r
1418        ( guid[ 1 ] == diag_guid[ 1 ] ) &&\r
1419        ( guid[ 2 ] == diag_guid[ 2 ] ) &&\r
1420        ( guid[ 3 ] == diag_guid[ 3 ] ) )\r
1421   {\r
1422     return TRUE;\r
1423   }\r
1424   else\r
1425   {\r
1426     return FALSE;\r
1427   }\r
1428 } /* diag_guid_is_valid */\r
1429 \r
1430 \f\r
1431 /*===========================================================================\r
1432 \r
1433 FUNCTION DIAGDIAG_GET_GUID\r
1434 \r
1435 DESCRIPTION\r
1436   This procedure processes a get_guid request. The GUID (globally unique\r
1437   identifier) for this build is retrieved and returned in the response\r
1438   packet. The GUID is stored during the build process.\r
1439 \r
1440 ===========================================================================*/\r
1441 PACK(void *) diagdiag_get_guid\r
1442 (\r
1443   PACK(void *) req_pkt, /* pointer to request packet  */\r
1444   uint16 pkt_len            /* length of request packet  */\r
1445 )\r
1446 {\r
1447   DIAG_GET_GUID_F_rsp_type *rsp;\r
1448   const unsigned int rsp_len = sizeof (DIAG_GET_GUID_F_rsp_type);\r
1449 \r
1450   (void) req_pkt; /* suppress compiler warning */\r
1451   (void) pkt_len; /* suppress compiler warning */\r
1452 \r
1453   /*--------------------------------------------\r
1454     Allocate buffer space for response packet.\r
1455   --------------------------------------------*/\r
1456   rsp = (DIAG_GET_GUID_F_rsp_type *) diagpkt_alloc (DIAG_GET_GUID_F, rsp_len);\r
1457 \r
1458   memcpy((void *) &rsp->guid[0],\r
1459          (const void *) &diag_guid[0],\r
1460          sizeof(diag_guid_type));\r
1461 \r
1462   return rsp;\r
1463 \r
1464 } /* diagdiag_get_guid */\r
1465 \r
1466 \f\r
1467 \r
1468 /*===========================================================================\r
1469 FUNCTION DIAGDIAG_EVENT_LISTENER\r
1470 \r
1471 DESCRIPTION The event has been removed from listening\r
1472 ============================================================================*/\r
1473 void\r
1474 diagdiag_event_listener (uint32 seq_num, const diag_event_type * event, void * param)\r
1475 {\r
1476   MSG_3 (MSG_SSID_DIAG, MSG_LEGACY_HIGH,\r
1477             "Event listener 0x%04X param:0x%08X seq:%d", \r
1478             event->event_id, (uint32) param, seq_num);\r
1479 }\r
1480 \r
1481 /*===========================================================================\r
1482 FUNCTION DIAGDIAG_LOG_LISTENER\r
1483 \r
1484 DESCRIPTION The log has been added to listen\r
1485 ============================================================================*/\r
1486 void\r
1487 diagdiag_log_listener (uint32 seq_num, const byte * log, unsigned int length,\r
1488                        void * param)\r
1489 {\r
1490   MSG_3 (MSG_SSID_DIAG, MSG_LEGACY_HIGH,\r
1491          "Log listener 0x%04X param:0x%08X seq:%d", \r
1492          log_get_code ((PACK(void *)) log), (uint32) param, seq_num);\r
1493 }\r
1494 \r
1495 \r
1496 /*===========================================================================\r
1497 FUNCTION DIAGDIAG_LISTENER_PKT\r
1498 \r
1499 DESCRIPTION   \r
1500   This procedure tests the following:\r
1501   1) Add log listener\r
1502   2) Remove log listener\r
1503   3) Add event listener\r
1504   4) Remove event listener\r
1505 \r
1506 RETURN VALUE\r
1507   Pointer to response packet.\r
1508 \r
1509 ============================================================================*/\r
1510 PACK(void *)\r
1511 diagdiag_listener_pkt (PACK(void *) req_pkt, uint16 pkt_len)\r
1512 {\r
1513   diag_log_event_listener_rsp_type *rsp;\r
1514   diag_log_event_listener_req_type *req = \r
1515     (diag_log_event_listener_req_type *) req_pkt;\r
1516 \r
1517   diagpkt_subsys_cmd_code_type cmd_code = diagpkt_subsys_get_cmd_code (req);\r
1518 \r
1519   const int rsp_len = pkt_len;\r
1520 \r
1521   /* Allocate the same length as the request */\r
1522   rsp = (diag_log_event_listener_rsp_type *) \r
1523     diagpkt_subsys_alloc (DIAG_SUBSYS_DIAG_SERV, cmd_code, rsp_len);\r
1524 \r
1525   /* Send the response acknowledging that the packet has been started */\r
1526   if (rsp != NULL)\r
1527   {\r
1528     memcpy ((void *) rsp, (void *) req, rsp_len);\r
1529 \r
1530     switch (cmd_code)\r
1531     {\r
1532       case DIAGDIAG_ADD_EVENT_LISTENER_F:\r
1533         (void) diag_add_event_listener (req->id, diagdiag_event_listener, (void *) req->param);\r
1534         break;\r
1535       case DIAGDIAG_REMOVE_EVENT_LISTENER_F:\r
1536         (void) diag_remove_event_listener (req->id, diagdiag_event_listener, (void *) req->param);\r
1537         break;\r
1538       case DIAGDIAG_ADD_LOG_LISTENER_F:\r
1539         (void) diag_add_log_listener (req->id, diagdiag_log_listener, (void *) req->param);\r
1540         break;\r
1541       case DIAGDIAG_REMOVE_LOG_LISTENER_F:\r
1542         (void) diag_remove_log_listener (req->id, diagdiag_log_listener, (void *) req->param);\r
1543         break;\r
1544       default:\r
1545         break;\r
1546     }\r
1547   }\r
1548   \r
1549   return rsp;\r
1550 \r
1551 } /* diagdiag_cmd_request_handler */\r
1552 \r
1553 #ifdef FEATURE_TECHNICS_DIAG\r
1554 #include "mobile.h"\r
1555 #include "uim.h"\r
1556 #include "flash_nand.h"\r
1557 #include "diagsec.h"\r
1558 #include "diagd3des.h"\r
1559 \r
1560 byte diagdiag_des_sec_rand[8] = {0, 0, 0, 0, 0, 0, 0, 0};\r
1561 extern const byte diag_cal_des_sec_code[] ;\r
1562 extern const byte diag_cal_des_sec_key[] ;\r
1563 extern const byte diag_tool_des_sec_code[] ;\r
1564 extern const byte diag_tool_des_sec_key[] ;\r
1565 \r
1566 static byte *diag_des_sec_code;\r
1567 static byte *diag_des_sec_key;\r
1568 dword diag_rand_init;\r
1569 boolean diag_des_ulock_stat = FALSE;\r
1570 \r
1571 /*===========================================================================\r
1572  \r
1573 FUNCTION DIAGDIAG_MANUFACTURE_TEST\r
1574  \r
1575 DESCRIPTION\r
1576   This procedure processes a request to poke into Non-Volatile memory.\r
1577  \r
1578 DEPENDENCIES\r
1579   None.\r
1580  \r
1581 RETURN VALUE\r
1582   Pointer to response packet.\r
1583  \r
1584 SIDE EFFECTS\r
1585   None.\r
1586  \r
1587 ===========================================================================*/\r
1588 PACK(void *) diagdiag_manufacture_test (PACK(void *) req_pkt, uint16 pkt_len)\r
1589 {\r
1590     int i;\r
1591     int data_count;\r
1592 \r
1593     static byte dir_number[] =\r
1594         { '0','1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0, 0, 0, 0,0};\r
1595     //uim_status_type uim_status;\r
1596     byte diagdiag_des_sec_para[16];\r
1597     byte diagdiag_des_sec_scrunch[8];\r
1598     boolean diagdiag_des_sec_ok;\r
1599     dword* sec_rand_ptr;\r
1600 #ifdef FEATURE_INFO_BAK\r
1601     unsigned char need_data[INFO_BAK_SIZE];\r
1602 #endif\r
1603 \r
1604     DIAG_MANUFACTURE_TEST_F_req_type *req = (DIAG_MANUFACTURE_TEST_F_req_type *) req_pkt;\r
1605     DIAG_MANUFACTURE_TEST_F_rsp_type *rsp;\r
1606     const int rsp_len = sizeof(DIAG_MANUFACTURE_TEST_F_rsp_type);\r
1607 \r
1608     //ran_seed(diag_rand_init);\r
1609 \r
1610     /* Allocate space for response packet */\r
1611     rsp = (DIAG_MANUFACTURE_TEST_F_rsp_type *)diagpkt_alloc(DIAG_MANUFACTURE_TEST_F, rsp_len);\r
1612 \r
1613     rsp->mask = 0x00;\r
1614     for (i=0 ; i < 16; i++)\r
1615     {\r
1616         rsp->data[i] = 0x00;\r
1617     }\r
1618 \r
1619     switch(req->mask)\r
1620     {\r
1621         case 0x00:\r
1622         {\r
1623             for ( i=0; i<14; i++ )\r
1624             {\r
1625                 rsp->data[i] = mob_sw_rev[i];\r
1626             }\r
1627             break;\r
1628         }\r
1629 #if 0\r
1630         case 0x01:\r
1631         {\r
1632             uim_status = uim_get_uim_status();\r
1633             if (uim_status == UIM_ERR_S)\r
1634             {\r
1635                 rsp->mask = 0x01;\r
1636                 for (i=0 ; i < 16; i++)\r
1637                 {\r
1638                     rsp->data[i] = 0x00;\r
1639                 }\r
1640             }\r
1641             /* Select the CDMA DF to check if the card is an R-UIM card */\r
1642             else\r
1643             {\r
1644                 rsp->mask = 0x01;\r
1645 \r
1646                 diag_nv_read(NV_DIR_NUMBER_PCS_I, &nitem);\r
1647 \r
1648                 rsp->data[0] = 0x01;\r
1649 \r
1650                 for (i=1 ; i < NV_DIR_NUMB_PCS_SIZ; i++)\r
1651                 {\r
1652                     rsp->data[i] = dir_number[ nitem.mob_dir_number.digitn[i-1]];\r
1653                 }\r
1654             }\r
1655             break;\r
1656         }\r
1657 #endif\r
1658         case 0x03:\r
1659         {//read the BT address\r
1660             nv_item_type  nv_item;\r
1661             uint16 bt_add,bt_temp;\r
1662             uint16 mac_add,mac_temp;\r
1663 \r
1664             if(diag_nv_read(NV_BD_ADDR_I,&nv_item) != NV_DONE_S)\r
1665             {\r
1666                 rsp->data[0] = 1;\r
1667             }\r
1668             else\r
1669             {\r
1670                 for(i = 0;i < NV_BD_ADDR_SIZE;i++)\r
1671                 {\r
1672                     bt_add = (uint16)nv_item.bd_addr.bd_addr[i];\r
1673                     bt_temp = bt_add & 0x000F;  \r
1674                     rsp->data[NV_BD_ADDR_SIZE*2 -1 - i*2] = (unsigned char) (( bt_temp <= 9 ) ? bt_temp + '0' : bt_temp - 10 + 'A');\r
1675                     bt_temp = (bt_add >> 4) & 0x000F;   \r
1676                     rsp->data[NV_BD_ADDR_SIZE*2 -2 - i*2] = (unsigned char) (( bt_temp <= 9 ) ? bt_temp + '0' : bt_temp - 10 + 'A');\r
1677                 }\r
1678             }\r
1679 \r
1680             rsp->mask=req->mask;\r
1681             break;\r
1682         }\r
1683         case 0x06:\r
1684         {//write the BT address \r
1685             nv_item_type  nv_item;\r
1686             uint16 bt_add,bt_temp;\r
1687             uint16 mac_add,mac_temp;\r
1688 \r
1689             for(i = 0;i < NV_BD_ADDR_SIZE;i++)\r
1690             {\r
1691                 bt_add = 0;\r
1692                 bt_temp = 0;\r
1693                 if(req->data[2*i] <= 0x39)\r
1694                 {\r
1695                     bt_add = req->data[2*i] - '0';\r
1696                 }\r
1697                 else\r
1698                 {\r
1699                     bt_add = req->data[2*i]  - 'A' + 10;\r
1700                 }\r
1701 \r
1702                 if(req->data[2*i + 1] <= 0x39)\r
1703                 {\r
1704                     bt_temp = req->data[2*i + 1] - '0';\r
1705                 }\r
1706                 else\r
1707                 {\r
1708                     bt_temp = req->data[2*i + 1] -  'A' + 10;\r
1709                 }\r
1710 \r
1711                 bt_temp |= (bt_add << 4);\r
1712                 nv_item.bd_addr.bd_addr[NV_BD_ADDR_SIZE -1 - i] = bt_temp;\r
1713             }\r
1714 \r
1715             if(diag_nv_write(NV_BD_ADDR_I,&nv_item) != NV_DONE_S)\r
1716             {\r
1717                 rsp->data[0] = 1;\r
1718             }\r
1719             else\r
1720             {\r
1721                 rsp->data[0] = 0;\r
1722             }\r
1723 \r
1724             rsp->mask=req->mask;\r
1725             break;\r
1726         }\r
1727 \r
1728         case 0x25:\r
1729         {\r
1730             diag_des_sec_key = (byte *)diag_tool_des_sec_key;\r
1731             diag_des_sec_code = (byte *)diag_tool_des_sec_code;\r
1732             rsp->mask = 0x25;\r
1733 \r
1734             sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[0];\r
1735 \r
1736             *sec_rand_ptr = ran_next ();\r
1737 \r
1738             sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[4];\r
1739 \r
1740             *sec_rand_ptr = ran_next ();\r
1741             diag_rand_init = *sec_rand_ptr;\r
1742 \r
1743             memcpy(diagdiag_des_sec_scrunch, diag_des_sec_key, sizeof(diagdiag_des_sec_scrunch));\r
1744 \r
1745             diag_deskey(diagdiag_des_sec_scrunch, EN0);\r
1746 \r
1747             diag_des( &diagdiag_des_sec_rand[0],&rsp->data[0]);\r
1748 \r
1749             break;\r
1750         }\r
1751         case 0x26:\r
1752         {\r
1753             diag_des_sec_key = (byte *)diag_tool_des_sec_key;\r
1754             diag_des_sec_code = (byte *)diag_tool_des_sec_code;\r
1755             rsp->mask = 0x26;\r
1756 \r
1757             memcpy(diagdiag_des_sec_scrunch, diag_des_sec_key, sizeof(diagdiag_des_sec_scrunch));\r
1758 \r
1759             diag_deskey(diagdiag_des_sec_scrunch, DE1);\r
1760 \r
1761             diag_des(&req->data[0], &diagdiag_des_sec_para[0]);\r
1762 \r
1763             diagdiag_des_sec_ok = TRUE;\r
1764 \r
1765             if((diagdiag_des_sec_rand[0] == 0) &&\r
1766                     (diagdiag_des_sec_rand[1] == 0) &&\r
1767                     (diagdiag_des_sec_rand[2] == 0) &&\r
1768                     (diagdiag_des_sec_rand[3] == 0) &&\r
1769                     (diagdiag_des_sec_rand[4] == 0) &&\r
1770                     (diagdiag_des_sec_rand[5] == 0) &&\r
1771                     (diagdiag_des_sec_rand[6] == 0) &&\r
1772                     (diagdiag_des_sec_rand[7] == 0) )\r
1773             {\r
1774                 diagdiag_des_sec_ok = FALSE;\r
1775 \r
1776                 diag_powerdown();\r
1777 \r
1778                 break;\r
1779             }\r
1780 \r
1781             for (i = 0; i < 8; i++)\r
1782             {\r
1783                 if(diag_des_sec_code[i] != (diagdiag_des_sec_para[i] ^ diagdiag_des_sec_rand[i]))\r
1784                 {\r
1785                     diagdiag_des_sec_ok = FALSE;\r
1786 \r
1787                     diag_powerdown();\r
1788 \r
1789                     break;\r
1790                 }\r
1791             }\r
1792 \r
1793             if(diagdiag_des_sec_ok == TRUE)\r
1794             {\r
1795                 rsp->data[0] = 0x01;\r
1796 \r
1797             }\r
1798 \r
1799             sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[0];\r
1800 \r
1801             *sec_rand_ptr = ran_next ();\r
1802 \r
1803             sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[4];\r
1804 \r
1805             *sec_rand_ptr = ran_next ();\r
1806             diag_rand_init = *sec_rand_ptr;\r
1807             diag_des_ulock_stat = TRUE;\r
1808             break;\r
1809         }\r
1810         \r
1811         case 0x32:\r
1812         {//read the wlan mac address\r
1813             nv_item_type  nv_item;\r
1814             uint16 mac_add,mac_temp;\r
1815 \r
1816             if(diag_nv_read(NV_WLAN_MAC_ADDRESS_I,&nv_item) != NV_DONE_S)\r
1817             {\r
1818                 rsp->data[0] = 1;\r
1819             }\r
1820             else\r
1821             {\r
1822                 for(i = 0;i < 6;i++)\r
1823                 {\r
1824                     mac_add = (uint16)nv_item.wlan_mac_address[i];\r
1825                     mac_temp = mac_add & 0x000F;  \r
1826                     rsp->data[6*2 -1 - i*2] = (unsigned char) (( mac_temp <= 9 ) ? mac_temp + '0' : mac_temp - 10 + 'A');\r
1827                     mac_temp = (mac_add >> 4) & 0x000F;   \r
1828                     rsp->data[6*2 -2 - i*2] = (unsigned char) (( mac_temp <= 9 ) ? mac_temp + '0' : mac_temp - 10 + 'A');\r
1829                 }\r
1830             }\r
1831 \r
1832             rsp->mask=req->mask;\r
1833             break;\r
1834         }\r
1835         case 0x33:\r
1836         {//write the wlan mac address\r
1837             nv_item_type  nv_item;\r
1838             uint16 mac_add,mac_temp;\r
1839 \r
1840             for(i = 0;i < 6;i++)\r
1841             {\r
1842                 mac_add = 0;\r
1843                 mac_temp = 0;\r
1844                 if(req->data[2*i] <= 0x39)\r
1845                 {\r
1846                     mac_add = req->data[2*i] - '0';\r
1847                 }\r
1848                 else\r
1849                 {\r
1850                     mac_add = req->data[2*i]  - 'A' + 10;\r
1851                 }\r
1852 \r
1853                 if(req->data[2*i + 1] <= 0x39)\r
1854                 {\r
1855                     mac_temp = req->data[2*i + 1] - '0';\r
1856                 }\r
1857                 else\r
1858                 {\r
1859                     mac_temp = req->data[2*i + 1] -  'A' + 10;\r
1860                 }\r
1861 \r
1862                 mac_temp |= (mac_add << 4);\r
1863                 nv_item.wlan_mac_address[6 -1 - i] = mac_temp;\r
1864             }\r
1865 \r
1866             if(diag_nv_write(NV_WLAN_MAC_ADDRESS_I,&nv_item) != NV_DONE_S)\r
1867             {\r
1868                 rsp->data[0] = 1;\r
1869             }\r
1870             else\r
1871             {\r
1872                 rsp->data[0] = 0;\r
1873             }\r
1874 \r
1875             rsp->mask=req->mask;\r
1876             break;\r
1877         }\r
1878            \r
1879 #ifdef FEATURE_NV_BAK\r
1880         case 0x53:\r
1881         {\r
1882 #ifdef FEATURE_INFO_BAK\r
1883             efs_device_write_info_bak_data();\r
1884 #endif\r
1885             if(efs_device_bak_nv_data(FALSE) == 0) \r
1886             {\r
1887                 rsp->data[0] = 0x01;\r
1888             }\r
1889             else\r
1890             {\r
1891                 rsp->data[0] = 0x00;\r
1892             }\r
1893             rsp->mask = 0x53;\r
1894             break;\r
1895         }\r
1896         \r
1897         case 0x54:\r
1898         {\r
1899             /* »Ö¸´NVÊý¾Ý*/\r
1900             if(efs_device_restore_nv_data() == FALSE)\r
1901             {\r
1902                 rsp->data[0] = 0x01;\r
1903             }\r
1904             else\r
1905             {\r
1906             #ifdef FEATURE_INFO_BAK\r
1907                 /* »Ö¸´DATÎļþ*/\r
1908                 if(efs_device_restore_info_bak_file() == TRUE)\r
1909                 {\r
1910                     if(efs_device_get_info_bak_data(&need_data[0]) == FALSE)//read BOARDNO, MSNO and PHONEID data, ssd add 2008-12-23\r
1911                     {\r
1912                         rsp->data[0] = 0x01;//¶Áȡʧ°Ü\r
1913                     }\r
1914                     else\r
1915                     {\r
1916                         rsp->data[0] = 0x00;//¶ÁÈ¡³É¹¦\r
1917                         \r
1918                         for(i=0; i<BOARDNO_MAX_SIZE; i++)\r
1919                         {\r
1920                             rsp->data[i+1] = need_data[i];\r
1921                         }\r
1922                         \r
1923                         rsp->data[BOARDNO_MAX_SIZE+1] = 0x00;//0x00·Ö¸ôBOARDNOºÍPHONEIDÊý¾Ý\r
1924                     \r
1925                         for(i=0; i<PHONEID_MAX_SIZE; i++)\r
1926                         {\r
1927                             rsp->data[BOARDNO_MAX_SIZE+2+i] = need_data[BOARDNO_MAX_SIZE+i];\r
1928                         }\r
1929                         \r
1930                         rsp->data[BOARDNO_MAX_SIZE+PHONEID_MAX_SIZE+2] = 0x00;//0x00·Ö¸ôPHONEIDºÍMSNOÊý¾Ý\r
1931                     \r
1932                         for(i=0; i<MSNO_MAX_SIZE; i++)\r
1933                         {\r
1934                             rsp->data[BOARDNO_MAX_SIZE+PHONEID_MAX_SIZE+3+i] = need_data[BOARDNO_MAX_SIZE+PHONEID_MAX_SIZE+i];\r
1935                         }\r
1936                     }\r
1937                 }\r
1938                 else\r
1939                 {\r
1940                     rsp->data[0] = 0x01;//»Ö¸´Ê§°Ü\r
1941                 }\r
1942             #else\r
1943                 rsp->data[0] = 0x00;//»Ö¸´³É¹¦\r
1944             #endif\r
1945             }\r
1946             \r
1947             rsp->mask = 0x54;\r
1948             break;\r
1949         }\r
1950 #endif\r
1951         default:\r
1952         {\r
1953             rsp->mask = 0xFF;\r
1954             for (i=0 ; i < NV_DIR_NUMB_PCS_SIZ; i++)\r
1955             {\r
1956                 rsp->data[i] = 0xFF;\r
1957             }\r
1958             break;\r
1959         }\r
1960     }\r
1961     return (rsp);\r
1962 }\r
1963 \r
1964 /*===========================================================================\r
1965 \r
1966 FUNCTION DIAGDIAG_FACTORY_TEST\r
1967 \r
1968 DESCRIPTION\r
1969   This procedure processes a request to poke into Non-Volatile memory.\r
1970 \r
1971 DEPENDENCIES\r
1972   None.\r
1973 \r
1974 RETURN VALUE\r
1975   Pointer to response packet.\r
1976 \r
1977 SIDE EFFECTS\r
1978   None.\r
1979  \r
1980 ===========================================================================*/\r
1981 PACK(void *) diagdiag_factory_test (PACK(void *) req_pkt, uint16 pkt_len)\r
1982 {\r
1983     int i;\r
1984 \r
1985     DIAG_FACTORY_TEST_F_req_type *req = (DIAG_FACTORY_TEST_F_req_type *) req_pkt;\r
1986     DIAG_FACTORY_TEST_F_rsp_type *rsp;\r
1987     const int rsp_len = sizeof(DIAG_FACTORY_TEST_F_rsp_type);\r
1988 \r
1989     /* Allocate space for response packet */\r
1990     rsp = (DIAG_FACTORY_TEST_F_rsp_type *)diagpkt_alloc(DIAG_FACTORY_TEST_F, rsp_len);\r
1991 \r
1992     rsp->mask = 0x00;\r
1993     for (i=0 ; i < 16; i++)\r
1994     {\r
1995         rsp->data[i] = 0x00;\r
1996     }   \r
1997 \r
1998     switch(req->mask)\r
1999     {\r
2000         case 0x00:\r
2001         {\r
2002             rsp->mask = 0x00;\r
2003             break;\r
2004         }\r
2005         default:\r
2006             rsp->mask = 0xFF;\r
2007             break;\r
2008     }\r
2009 \r
2010     return (rsp);\r
2011 }\r
2012 \r
2013 /*===========================================================================\r
2014  \r
2015 FUNCTION DIAGDIAG_ENCRYPT_TEST\r
2016  \r
2017 DESCRIPTION\r
2018  \r
2019 DEPENDENCIES\r
2020   None.\r
2021  \r
2022 RETURN VALUE\r
2023   Pointer to response packet.\r
2024  \r
2025 SIDE EFFECTS\r
2026   None.\r
2027  \r
2028 ===========================================================================*/\r
2029 PACK(void *) diagdiag_encrypt_test (PACK(void *) req_pkt, uint16 pkt_len)\r
2030 {\r
2031     byte diagdiag_des_sec_para[16];\r
2032     byte diagdiag_des_sec_scrunch[8];\r
2033     boolean diagdiag_des_sec_ok;\r
2034     dword* sec_rand_ptr;\r
2035     int i;\r
2036 \r
2037 #ifdef NV_BAK\r
2038 \r
2039     extern int efs_device_bak_nv_data(PACKED const byte *data_ptr,int data_size,boolean erase);\r
2040 #endif\r
2041 \r
2042     DIAG_ENCRYPT_TEST_F_req_type *req = (DIAG_ENCRYPT_TEST_F_req_type *) req_pkt;\r
2043     DIAG_ENCRYPT_TEST_F_rsp_type *rsp;\r
2044     const int rsp_len = sizeof(DIAG_ENCRYPT_TEST_F_rsp_type);\r
2045 \r
2046     /* Allocate space for response packet */\r
2047     rsp = (DIAG_ENCRYPT_TEST_F_rsp_type *)diagpkt_alloc(DIAG_ENCRYPT_TEST_F, rsp_len);\r
2048 \r
2049     rsp->mask = 0x00;\r
2050     for (i=0 ; i < 16; i++)\r
2051     {\r
2052         rsp->data[i] = 0x00;\r
2053     }\r
2054 \r
2055     switch(req->mask)\r
2056     {\r
2057     case 0x01:\r
2058         diag_des_sec_key = (byte *)diag_tool_des_sec_key;\r
2059         diag_des_sec_code = (byte *)diag_tool_des_sec_code;\r
2060         rsp->mask = 0x01;\r
2061 \r
2062         sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[0];\r
2063 \r
2064         *sec_rand_ptr = ran_next ();\r
2065 \r
2066         sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[4];\r
2067 \r
2068         *sec_rand_ptr = ran_next ();\r
2069 \r
2070         memcpy(diagdiag_des_sec_scrunch, diag_des_sec_key, sizeof(diagdiag_des_sec_scrunch));\r
2071 \r
2072         diag_deskey(diagdiag_des_sec_scrunch, EN0);\r
2073 \r
2074         diag_des( &diagdiag_des_sec_rand[0],&rsp->data[0]);\r
2075 \r
2076         break;\r
2077 \r
2078     case 0x02:\r
2079         diag_des_sec_key =(byte *) diag_tool_des_sec_key;\r
2080         diag_des_sec_code =(byte *) diag_tool_des_sec_code;\r
2081 \r
2082         rsp->mask = 0x02;\r
2083 \r
2084         memcpy(diagdiag_des_sec_scrunch, diag_des_sec_key, sizeof(diagdiag_des_sec_scrunch));\r
2085 \r
2086         diag_deskey(diagdiag_des_sec_scrunch, DE1);\r
2087 \r
2088         diag_des(&req->data[0], &diagdiag_des_sec_para[0]);\r
2089 \r
2090         diagdiag_des_sec_ok = TRUE;\r
2091 \r
2092         if((diagdiag_des_sec_rand[0] == 0) &&\r
2093                 (diagdiag_des_sec_rand[1] == 0) &&\r
2094                 (diagdiag_des_sec_rand[2] == 0) &&\r
2095                 (diagdiag_des_sec_rand[3] == 0) &&\r
2096                 (diagdiag_des_sec_rand[4] == 0) &&\r
2097                 (diagdiag_des_sec_rand[5] == 0) &&\r
2098                 (diagdiag_des_sec_rand[6] == 0) &&\r
2099                 (diagdiag_des_sec_rand[7] == 0) )\r
2100         {\r
2101             diagdiag_des_sec_ok = FALSE;\r
2102 \r
2103             diag_powerdown();\r
2104 \r
2105             break;\r
2106         }\r
2107 \r
2108         for (i = 0; i < 8; i++)\r
2109         {\r
2110             if(diag_des_sec_code[i] != (diagdiag_des_sec_para[i] ^ diagdiag_des_sec_rand[i]))\r
2111             {\r
2112                 diagdiag_des_sec_ok = FALSE;\r
2113 \r
2114                 diag_powerdown();\r
2115 \r
2116                 break;\r
2117             }\r
2118         }\r
2119 \r
2120         if(diagdiag_des_sec_ok == TRUE)\r
2121         {\r
2122             rsp->data[0] = 0x01;\r
2123 \r
2124         }\r
2125 \r
2126         sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[0];\r
2127 \r
2128         *sec_rand_ptr = ran_next ();\r
2129 \r
2130         sec_rand_ptr = (dword*)&diagdiag_des_sec_rand[4];\r
2131 \r
2132         *sec_rand_ptr = ran_next ();\r
2133 \r
2134         break;\r
2135 \r
2136     default:\r
2137         rsp->mask = 0xFF;\r
2138         for (i=0 ; i < sizeof(rsp->data); i++)\r
2139         {\r
2140             rsp->data[i] = 0xFF;\r
2141         }\r
2142         break;\r
2143     }\r
2144     return (rsp);\r
2145 }\r
2146 \r
2147 #endif\r
2148 \r
2149 #define DISPATCH_DECLARE(func) \\r
2150 extern PACK(void *) func(PACK(void *) req_pkt, word len)\r
2151 \r
2152 #if defined(FEATURE_DIAG_RPC)\r
2153 #error code not present\r
2154 #endif /* FEATURE_DIAG_RPC */\r
2155 \r
2156 #ifndef FEATURE_DIAG_DISALLOW_MEM_OPS\r
2157 static const diagpkt_user_table_entry_type diagdiag_tbl_mem_ops[] =\r
2158 {\r
2159   {DIAG_PEEKB_F, DIAG_PEEKB_F, diagdiag_peekb},\r
2160   {DIAG_PEEKW_F, DIAG_PEEKW_F, diagdiag_peekw},\r
2161   {DIAG_PEEKD_F, DIAG_PEEKD_F, diagdiag_peekd},\r
2162   {DIAG_POKEB_F, DIAG_POKEB_F, diagdiag_pokeb},\r
2163   {DIAG_POKEW_F, DIAG_POKEW_F, diagdiag_pokew},\r
2164   {DIAG_POKED_F, DIAG_POKED_F, diagdiag_poked},\r
2165   {DIAG_OUTP_F, DIAG_OUTP_F, diagdiag_outp},\r
2166   {DIAG_OUTPW_F, DIAG_OUTPW_F, diagdiag_outpw},\r
2167   {DIAG_INP_F, DIAG_INP_F, diagdiag_inp},\r
2168   {DIAG_INPW_F, DIAG_INPW_F, diagdiag_inpw},\r
2169 };\r
2170 #endif\r
2171 \r
2172 static const diagpkt_user_table_entry_type diagdiag_tbl_ts[]=\r
2173 {\r
2174   {DIAG_TS_F, DIAG_TS_F, diagdiag_ts},\r
2175 \r
2176 };\r
2177 \r
2178 #ifdef FEATURE_TECHNICS_DIAG\r
2179 static const diagpkt_user_table_entry_type diagdiag_tbl_technics[]=\r
2180 {\r
2181     {DIAG_ENCRYPT_TEST_F,DIAG_ENCRYPT_TEST_F, diagdiag_encrypt_test },\r
2182     {DIAG_MANUFACTURE_TEST_F,DIAG_MANUFACTURE_TEST_F, diagdiag_manufacture_test },\r
2183     {DIAG_FACTORY_TEST_F,DIAG_FACTORY_TEST_F, diagdiag_factory_test },\r
2184 };\r
2185 #endif\r
2186 \r
2187 static const diagpkt_user_table_entry_type diagdiag_tbl_feature[]=\r
2188 {\r
2189  {DIAG_FEATURE_QUERY_F, DIAG_FEATURE_QUERY_F, diagdiag_feature_query},\r
2190 };\r
2191 \r
2192 static const diagpkt_user_table_entry_type diagdiag_tbl_misc[]=\r
2193 {\r
2194 \r
2195 #if defined(FEATURE_DIAG_RPC)\r
2196 #error code not present\r
2197 #endif\r
2198   {DIAG_DIAG_VER_F, DIAG_DIAG_VER_F, diagdiag_ver},\r
2199   {DIAG_PASSWORD_F, DIAG_PASSWORD_F, diagdiag_password},\r
2200   {DIAG_GET_GUID_F, DIAG_GET_GUID_F, diagdiag_get_guid },\r
2201 };\r
2202 \r
2203 static const diagpkt_user_table_entry_type diagdiag_tbl_listener[] =\r
2204 {  \r
2205   {DIAGDIAG_ADD_EVENT_LISTENER_F, DIAGDIAG_REMOVE_LOG_LISTENER_F, diagdiag_listener_pkt},\r
2206 };\r
2207 \r
2208 \r
2209 void diagdiag_tbl_init()\r
2210 {\r
2211 #ifndef FEATURE_DIAG_DISALLOW_MEM_OPS\r
2212         DIAGPKT_DISPATCH_TABLE_REGISTER_PROC (DIAG_MODEM_PROC, DIAGPKT_NO_SUBSYS_ID, diagdiag_tbl_mem_ops);\r
2213 #endif\r
2214         DIAGPKT_DISPATCH_TABLE_REGISTER_PROC (DIAG_MODEM_PROC, DIAGPKT_NO_SUBSYS_ID, diagdiag_tbl_feature);\r
2215         DIAGPKT_DISPATCH_TABLE_REGISTER_PROC (DIAG_MODEM_PROC, DIAGPKT_NO_SUBSYS_ID, diagdiag_tbl_ts);\r
2216         DIAGPKT_DISPATCH_TABLE_REGISTER_PROC (DIAG_MODEM_PROC, DIAGPKT_NO_SUBSYS_ID, diagdiag_tbl_misc);\r
2217 #ifdef FEATURE_TECHNICS_DIAG\r
2218         DIAGPKT_DISPATCH_TABLE_REGISTER_PROC(DIAG_MODEM_PROC,DIAGPKT_NO_SUBSYS_ID,diagdiag_tbl_technics);\r
2219 #endif\r
2220 #if defined(DIAG_IMAGE_APPS_PROC)\r
2221         DIAGPKT_DISPATCH_TABLE_REGISTER_PROC( DIAG_APP_PROC, DIAG_SUBSYS_DIAG_SERV, diagdiag_tbl_listener);\r
2222 #else\r
2223 #if defined(DIAG_IMAGE_MODEM_PROC)|| defined(DIAG_SINGLE_PROC)\r
2224         DIAGPKT_DISPATCH_TABLE_REGISTER_PROC( DIAG_MODEM_PROC, DIAG_SUBSYS_DIAG_SERV, diagdiag_tbl_listener);\r
2225 #endif\r
2226 #endif \r
2227 }\r
2228 \r
2229 #if defined __cplusplus\r
2230   }\r
2231 #endif\r