upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / usb / host / s3c-otg / s3c-otg-transferchecker-control.c
1 /****************************************************************************
2  *  (C) Copyright 2008 Samsung Electronics Co., Ltd., All rights reserved
3  *
4  *  [File Name]   : ControlTransferChecker.c
5  *  [Description] : The Source file implements the external and internal functions of ControlTransferChecker.
6  *  [Author]      : Yang Soon Yeal { syatom.yang@samsung.com }
7  *  [Department]  : System LSI Division/System SW Lab
8  *  [Created Date]: 2009/02/10
9  *  [Revision History]
10  *      (1) 2008/06/13   by Yang Soon Yeal { syatom.yang@samsung.com }
11  *          - Created this file and implements functions of ControlTransferChecker
12  *      (2) 2008/06/18   by Yang Soon Yeal { syatom.yang@samsung.com }
13  *          - Completed to implement ControlTransferChecker.c v1.0
14  *
15  ****************************************************************************/
16 /****************************************************************************
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation; either version 2 of the License, or
20  * (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
30  ****************************************************************************/
31
32 #include "s3c-otg-transferchecker-control.h"
33 #include "s3c-otg-isr.h"
34
35
36
37 /******************************************************************************/
38 /*!
39  * @name        u8      process_control_transfer(td_t   *result_td,
40                                              hc_info_t  *hc_reg_data)
41
42  *
43  * @brief               this function processes the result of the Control Transfer.
44  *                      firstly, this function checks the result the Control Transfer.
45  *                      and according to the result, calls the sub-functions to process the result.
46  *
47  *
48  * @param       [IN]    result_td               -indicates  the pointer of the td_t to be mapped with the uChNum.
49  *              [IN]    ubChNum -indicates the number of the channel to be interrupted.
50  *              [IN]    hc_reg_data     -indicates the interrupt information of the Channel to be interrupted
51  *
52  * @return      RE_TRANSMIT     -if need to retransmit the result_td.
53  *              RE_SCHEDULE     -if need to reschedule the result_td.
54  *              DE_ALLOCATE     -if USB Transfer is completed.
55  */
56 /******************************************************************************/
57 u8      process_control_transfer(td_t   *result_td,
58                                 hc_info_t       *hc_reg_data)
59 {
60         hcintn_t                hcintr_info;
61         u8              ret_val=0;
62
63         //we just deal with the interrupts to be unmasked.
64         hcintr_info.d32 = hc_reg_data->hc_int.d32&result_td->cur_stransfer.hc_reg.hc_int_msk.d32;
65
66         if(result_td->parent_ed_p->ed_desc.is_ep_in)
67         {
68                 if(hcintr_info.b.chhltd)
69                 {
70                         ret_val = process_chhltd_on_control(result_td, hc_reg_data);
71                 }
72
73                 else if (hcintr_info.b.ack)
74                 {
75                         ret_val =process_ack_on_control(result_td, hc_reg_data);
76                 }
77
78                 else if (hcintr_info.b.nak)
79                 {
80                         ret_val =process_nak_on_control(result_td, hc_reg_data);
81                 }
82
83                 else if (hcintr_info.b.datatglerr)
84                 {
85                         ret_val = process_datatgl_on_control(result_td,hc_reg_data);
86                 }
87         }
88         else
89         {
90                 if(hcintr_info.b.chhltd)
91                 {
92                         ret_val = process_chhltd_on_control(result_td,  hc_reg_data);
93                 }
94
95                 else if(hcintr_info.b.ack)
96                 {
97                         ret_val =process_ack_on_control( result_td, hc_reg_data);
98
99                 }
100         }
101
102         return ret_val;
103 }
104
105 /******************************************************************************/
106 /*!
107  * @name        u8      process_chhltd_on_control(      td_t    *result_td,
108  *                                              hc_info_t *hc_reg_data)
109  *
110  *
111  * @brief               this function processes Channel Halt event according to Synopsys OTG Spec.
112  *                      firstly, this function checks the reason of the Channel Halt, and according to the reason,
113  *                      calls the sub-functions to process the result.
114  *
115  *
116  * @param       [IN]    result_td               -indicates  the pointer of the td_t to be mapped with the uChNum.
117  *              [IN]    hc_reg_data     -indicates the interrupt information of the Channel to be interrupted
118  *
119  * @return      RE_TRANSMIT     -if need to retransmit the result_td.
120  *              RE_SCHEDULE     -if need to reschedule the result_td.
121  *              DE_ALLOCATE     -if USB Transfer is completed.
122  */
123 /******************************************************************************/
124 u8      process_chhltd_on_control(      td_t    *result_td,
125                                         hc_info_t *hc_reg_data)
126 {
127         if(hc_reg_data->hc_int.b.xfercompl)
128         {
129                 return process_xfercompl_on_control( result_td, hc_reg_data);
130         }
131         else if(hc_reg_data->hc_int.b.stall)
132         {
133                 return process_stall_on_control(result_td, hc_reg_data);
134         }
135         else if(hc_reg_data->hc_int.b.bblerr)
136         {
137                 return process_bblerr_on_control(result_td, hc_reg_data);
138         }
139         else if(hc_reg_data->hc_int.b.xacterr)
140         {
141                 return process_xacterr_on_control(result_td, hc_reg_data);
142         }
143         else if(hc_reg_data->hc_int.b.nak)
144         {
145                 return process_nak_on_control(result_td, hc_reg_data);
146         }
147         else if(hc_reg_data->hc_int.b.nyet)
148         {
149                 return process_nyet_on_control(result_td, hc_reg_data);
150         }
151         else
152         {
153
154                 //Occure Error State.....
155                 clear_ch_intr(result_td->cur_stransfer.alloc_chnum,     CH_STATUS_ALL);
156
157                 //Mask ack Interrupt..
158                 mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
159                 mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
160                 mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
161                 result_td->err_cnt++;
162                 if(result_td->err_cnt == 3)
163                 {
164                         result_td->error_code = USB_ERR_STATUS_XACTERR;
165                         result_td->err_cnt = 0;
166                         return DE_ALLOCATE;
167                 }
168                 return RE_TRANSMIT;
169         }
170         return USB_ERR_SUCCESS;
171 }
172
173 /******************************************************************************/
174 /*!
175  * @name        u8      process_xfercompl_on_control(td_t       *result_td,
176  *                                              hc_info_t *hc_reg_data)
177  *
178  *
179  * @brief               this function deals with the xfercompl event according to Synopsys OTG Spec.
180  *                      the procedure of this function is as following
181  *                              1. clears all bits of the channel' HCINT by using clear_ch_intr() of S3CIsr.
182  *                              2. masks some bit of HCINTMSK
183  *                              3. updates the result_td fields
184  *                                      err_cnt/u8/standard_dev_req_info.
185  *                              4. updates the result_td->parent_ed_p->ed_status.
186  *                                      control_data_tgl.
187  *                              5. calculates the tranferred size by calling calc_transferred_size() on DATA_STAGE.
188  *
189  * @param       [IN]    result_td               -indicates  the pointer of the td_t to be mapped with the uChNum.
190  *              [IN]    hc_reg_data     -indicates the interrupt information of the Channel to be interrupted
191  *
192  * @return      USB_ERR_SUCCESS
193  */
194 /******************************************************************************/
195 u8 process_xfercompl_on_control(td_t *result_td, hc_info_t *hc_reg_data)
196 {
197         u8 ret_val = 0;
198
199         result_td->err_cnt = 0;
200
201         clear_ch_intr(result_td->cur_stransfer.alloc_chnum,CH_STATUS_ALL);
202         //Mask ack Interrupt..
203         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
204         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
205         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
206
207         result_td->parent_ed_p->ed_status.is_ping_enable = false;
208
209         switch(result_td->standard_dev_req_info.conrol_transfer_stage) {
210         case SETUP_STAGE:
211                 if(result_td->standard_dev_req_info.is_data_stage) {
212                         result_td->standard_dev_req_info.conrol_transfer_stage = DATA_STAGE;
213                 }
214                 else {
215                         result_td->standard_dev_req_info.conrol_transfer_stage = STATUS_STAGE;
216                 }
217                 ret_val = RE_TRANSMIT;
218
219                 break;
220
221         case DATA_STAGE:
222
223                 result_td->transferred_szie += calc_transferred_size(true,result_td, hc_reg_data);
224                 
225                 /* at IN Transfer, short transfer is accepted. */
226                 if(result_td->transferred_szie==result_td->buf_size) {
227                         result_td->standard_dev_req_info.conrol_transfer_stage  =STATUS_STAGE;
228                         result_td->error_code = USB_ERR_STATUS_COMPLETE;
229                 }
230                 else {
231                         if(result_td->parent_ed_p->ed_desc.is_ep_in&& hc_reg_data->hc_size.b.xfersize) {
232                                 if(result_td->transfer_flag&USB_TRANS_FLAG_NOT_SHORT) {
233                                         result_td->error_code = USB_ERR_STATUS_SHORTREAD;
234                                         result_td->standard_dev_req_info.conrol_transfer_stage=STATUS_STAGE;
235                                 }
236                                 else {
237                                         result_td->error_code = USB_ERR_STATUS_COMPLETE;
238                                         result_td->standard_dev_req_info.conrol_transfer_stage  =STATUS_STAGE;
239                                 }
240                         }
241                         else {  // the Data Stage is not completed. So we need to continue Data Stage.
242                                 result_td->standard_dev_req_info.conrol_transfer_stage = DATA_STAGE;
243                                 update_datatgl(hc_reg_data->hc_size.b.pid, result_td);
244                         }
245                 }
246
247                 if(hc_reg_data->hc_int.b.nyet) {
248                         /* at OUT Transfer, we must re-transmit. */
249                         if(result_td->parent_ed_p->ed_desc.is_ep_in==false) {
250                                 if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG) {
251                                         result_td->parent_ed_p->ed_status.is_ping_enable = true;
252                                 }
253                                 else {
254                                         result_td->parent_ed_p->ed_status.is_ping_enable = false;
255                                 }
256                         }
257                 }
258                 ret_val = RE_TRANSMIT;
259                 break;
260
261         case STATUS_STAGE:
262                 result_td->standard_dev_req_info.conrol_transfer_stage = COMPLETE_STAGE;
263
264                 if(hc_reg_data->hc_int.b.nyet) {
265                         //at OUT Transfer, we must re-transmit.
266                         if(result_td->parent_ed_p->ed_desc.is_ep_in==false) {
267                                 if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG) {
268                                         result_td->parent_ed_p->ed_status.is_ping_enable = true;
269                                 }
270                                 else {
271                                         result_td->parent_ed_p->ed_status.is_ping_enable = false;
272                                 }
273                         }
274                 }
275
276                 ret_val = DE_ALLOCATE;
277                 break;
278
279         default:
280                 break;
281         }
282
283         return ret_val;
284 }
285
286 /******************************************************************************/
287 /*!
288  * @name        u8      process_ahb_on_control( td_t    *result_td,
289  *                                              hc_info_t *hc_reg_data)
290  *
291  *
292  * @brief               this function deals with theAHB Errorl event according to Synopsys OTG Spec.
293  *                      this function stop the channel to be executed
294  *
295  * @param       [IN]    result_td               -indicates  the pointer of the td_t to be mapped with the uChNum.
296  *              [IN]    hc_reg_data     -indicates the interrupt information of the Channel to be interrupted
297  *
298  * @return      DE_ALLOCATE
299  */
300 /******************************************************************************/
301 u8      process_ahb_on_control( td_t    *result_td,
302                                         hc_info_t *hc_reg_data)
303 {
304         result_td->err_cnt      =0;
305         result_td->error_code   =USB_ERR_STATUS_AHBERR;
306
307         clear_ch_intr(result_td->cur_stransfer.alloc_chnum,     CH_STATUS_AHBErr);
308
309         //Mask ack Interrupt..
310         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
311         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
312         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
313
314         // we just calculate the size of the transferred data on Data Stage of Control Transfer.
315         if(result_td->standard_dev_req_info.conrol_transfer_stage == DATA_STAGE)
316         {
317                 result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data);
318         }
319
320         return DE_ALLOCATE;
321
322 }
323
324 /******************************************************************************/
325 /*!
326  * @name        u8      process_stall_on_control(       td_t    *result_td,
327  *                                              hc_info_t *hc_reg_data)
328  *
329  *
330  * @brief               this function deals with theStall event according to Synopsys OTG Spec.
331  *                      but USB2.0 Spec don't permit the Stall on Setup Stage of Control Transfer.
332  *
333  * @param       [IN]    result_td               -indicates  the pointer of the td_t to be mapped with the uChNum.
334  *              [IN]    hc_reg_data     -indicates the interrupt information of the Channel to be interrupted
335  *
336  * @return      DE_ALLOCATE
337  */
338 /******************************************************************************/
339 u8      process_stall_on_control(       td_t    *result_td,
340                                         hc_info_t *hc_reg_data)
341 {
342         result_td->err_cnt      =0;
343         result_td->error_code   =USB_ERR_STATUS_STALL;
344
345         clear_ch_intr(result_td->cur_stransfer.alloc_chnum,     CH_STATUS_ALL);
346
347         //Mask ack Interrupt..
348         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
349         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
350         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
351
352         result_td->parent_ed_p->ed_status.is_ping_enable = false;
353
354         // we just calculate the size of the transferred data on Data Stage of Control Transfer.
355         if(result_td->standard_dev_req_info.conrol_transfer_stage == DATA_STAGE)
356         {
357                 result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data);
358         }
359
360         return DE_ALLOCATE;
361 }
362
363 /******************************************************************************/
364 /*!
365  * @name        u8      process_nak_on_control( td_t    *result_td,
366  *                                              hc_info_t *hc_reg_data)
367  *
368  *
369  * @brief               this function deals with the nak event according to Synopsys OTG Spec.
370  *                      nak is occured at OUT/IN Transaction of Data/Status Stage, and is not occured at Setup Stage.
371  *                      If nak is occured at IN Transaction, this function processes this interrupt as following.
372  *                              1. resets the result_td->err_cnt.
373  *                              2. masks ack/nak/DaaTglErr bit of HCINTMSK.
374  *                              3. clears the nak bit of HCINT
375  *                              4. be careful, nak of IN Transaction don't require re-transmit.
376  *                      If nak is occured at OUT Transaction, this function processes this interrupt as following.
377  *                              1. all procedures of IN Transaction are executed.
378  *                              2. calculates the size of the transferred data.
379  *                              3. if the speed of USB Device is High-Speed, sets the ping protocol.
380  *                              4. update the Toggle
381  *                      at OUT Transaction, this function check whether the speed of USB Device is High-Speed or not.
382  *                      if USB Device is High-Speed, then
383  *                      this function sets the ping protocol.
384  *
385  * @param       [IN]    result_td               -indicates  the pointer of the td_t to be mapped with the uChNum.
386  *               [IN]   hc_reg_data     -indicates the interrupt information of the Channel to be interrupted
387  *
388  * @return      RE_SCHEDULE
389  */
390 /******************************************************************************/
391 u8      process_nak_on_control( td_t    *result_td,
392                                         hc_info_t *hc_reg_data)
393 {
394         result_td->err_cnt = 0;
395
396         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
397         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
398         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
399         clear_ch_intr(result_td->cur_stransfer.alloc_chnum,     CH_STATUS_NAK);
400
401         //at OUT Transfer, we must re-transmit.
402         if(result_td->parent_ed_p->ed_desc.is_ep_in==false)
403         {
404                 result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data);
405
406                 update_datatgl(hc_reg_data->hc_size.b.pid, result_td);
407         }
408
409         if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG)
410         {
411                 if(result_td->standard_dev_req_info.conrol_transfer_stage == DATA_STAGE)
412                 {
413                         if(result_td->parent_ed_p->ed_desc.is_ep_in==false)
414                         {
415                                 result_td->parent_ed_p->ed_status.is_ping_enable = true;
416                         }
417                 }
418                 else if(result_td->standard_dev_req_info.conrol_transfer_stage == STATUS_STAGE)
419                 {
420                         if(result_td->parent_ed_p->ed_desc.is_ep_in==true)
421                         {
422                                 result_td->parent_ed_p->ed_status.is_ping_enable = true;
423                         }
424                 }
425                 else
426                 {
427                         result_td->parent_ed_p->ed_status.is_ping_enable = false;
428                 }
429
430         }
431
432         return RE_SCHEDULE;
433
434
435 }
436
437 /******************************************************************************/
438 /*!
439  * @name        u8      process_ack_on_control( td_t    *result_td,
440  *                                              hc_info_t *hc_reg_data)
441  *
442  *
443  * @brief               this function deals with the ack event according to Synopsys OTG Spec.
444  *                      ack of IN/OUT Transaction don't need any retransmit.
445  *                      this function just resets result_td->err_cnt and masks ack/nak/DataTgl of HCINTMSK.
446  *                      finally, this function clears ack bit of HCINT.
447  *
448  * @param       [IN]    result_td               -indicates  the pointer of the td_t to be mapped with the uChNum.
449  *              [IN]    hc_reg_data     -indicates the interrupt information of the Channel to be interrupted
450  *
451  * @return      NO_ACTION
452  */
453 /******************************************************************************/
454 u8      process_ack_on_control(td_t *result_td,
455                                 hc_info_t *hc_reg_data)
456 {
457         result_td->err_cnt = 0;
458
459         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
460         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
461         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
462         clear_ch_intr(result_td->cur_stransfer.alloc_chnum,     CH_STATUS_ACK);
463
464         result_td->parent_ed_p->ed_status.is_ping_enable        =false;
465
466         return NO_ACTION;
467
468 }
469
470 /******************************************************************************/
471 /*!
472  * @name        u8      process_nyet_on_control(td_t    *result_td,
473  *                                      hc_info_t       *hc_reg_data)
474  *
475  *
476  * @brief               this function deals with the nyet event according to Synopsys OTG Spec.
477  *                      nyet is occured at OUT Transaction of Data/Status Stage, and is not occured at Setup Stage.
478  *                      If nyet is occured at OUT Transaction, this function processes this interrupt as following.
479  *                              1. resets the result_td->err_cnt.
480  *                              2. masks ack/nak/datatglerr bit of HCINTMSK.
481  *                              3. clears the nyet bit of HCINT
482  *                              4. calculates the size of the transferred data.
483  *                              5. if the speed of USB Device is High-Speed, sets the ping protocol.
484  *                              6. update the Data Toggle.
485  *
486  * @param       [IN]    result_td               -indicates  the pointer of the td_t to be mapped with the uChNum.
487  *              [IN]    hc_reg_data     -indicates the interrupt information of the Channel to be interrupted
488  *
489  * @return      RE_SCHEDULE
490  */
491 /******************************************************************************/
492 u8      process_nyet_on_control(td_t    *result_td,
493                                 hc_info_t               *hc_reg_data)
494 {
495         result_td->err_cnt = 0;
496
497         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
498         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
499         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
500         clear_ch_intr(result_td->cur_stransfer.alloc_chnum,     CH_STATUS_NYET);
501
502         result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data);
503
504         if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG)
505         {
506                 if(result_td->standard_dev_req_info.conrol_transfer_stage == DATA_STAGE)
507                 {
508                         if(result_td->parent_ed_p->ed_desc.is_ep_in==false)
509                         {
510                                 result_td->parent_ed_p->ed_status.is_ping_enable = true;
511                         }
512                 }
513                 else if(result_td->standard_dev_req_info.conrol_transfer_stage == STATUS_STAGE)
514                 {
515                         if(result_td->parent_ed_p->ed_desc.is_ep_in==true)
516                         {
517                                 result_td->parent_ed_p->ed_status.is_ping_enable = true;
518                         }
519                 }
520                 else
521                 {
522                         result_td->parent_ed_p->ed_status.is_ping_enable = false;
523                 }
524
525         }
526
527         update_datatgl(hc_reg_data->hc_size.b.pid, result_td);
528
529         return RE_SCHEDULE;
530 }
531
532 /******************************************************************************/
533 /*!
534  * @name        u8      process_xacterr_on_control(     td_t    *result_td,
535  *                                              hc_info_t *hc_reg_data)
536  *
537  *
538  * @brief               this function deals with the xacterr event according to Synopsys OTG Spec.
539  *                      xacterr is occured at OUT/IN Transaction of Data/Status Stage, and is not occured at Setup Stage.
540  *                      if Timeout/CRC error/false EOP is occured, then xacterr is occured.
541  *                      the procedure to process xacterr is as following.
542  *                              1. increses the result_td->err_cnt
543  *                              2. check whether the result_td->err_cnt is equal to 3.
544  *                              2. unmasks ack/nak/datatglerr bit of HCINTMSK.
545  *                              3. clears the xacterr bit of HCINT
546  *                              4. calculates the size of the transferred data.
547  *                              5. if the speed of USB Device is High-Speed, sets the ping protocol.
548  *                              6. update the Data Toggle.
549  *
550  * @param       [IN]    result_td               -indicates  the pointer of the td_t to be mapped with the uChNum.
551  *              [IN]    hc_reg_data     -indicates the interrupt information of the Channel to be interrupted
552  *
553  * @return      RE_TRANSMIT     -if the Error Counter is less than RETRANSMIT_THRESHOLD
554  *              DE_ALLOCATE     -if the Error Counter is equal to RETRANSMIT_THRESHOLD
555  */
556 /******************************************************************************/
557 u8      process_xacterr_on_control(td_t         *result_td,
558                                         hc_info_t *hc_reg_data)
559 {
560         u8      ret_val=0;
561
562         if(result_td->err_cnt<RETRANSMIT_THRESHOLD)
563         {
564                 result_td->cur_stransfer.hc_reg.hc_int_msk.d32 |= (CH_STATUS_ACK+CH_STATUS_NAK+CH_STATUS_DataTglErr);
565                 ret_val = RE_TRANSMIT;
566                 unmask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
567                 unmask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
568                 unmask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
569                 result_td->err_cnt++ ;
570         }
571         else
572         {
573                 mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
574                 mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
575                 mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
576                 ret_val = DE_ALLOCATE;
577                 result_td->err_cnt = 0 ;
578                 result_td->error_code = USB_ERR_STATUS_XACTERR;
579         }
580
581         clear_ch_intr(result_td->cur_stransfer.alloc_chnum,     CH_STATUS_DataTglErr);
582
583         if(result_td->standard_dev_req_info.conrol_transfer_stage == DATA_STAGE)
584         {
585                 result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data);
586
587         }
588
589         if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG)
590         {
591                 if(result_td->standard_dev_req_info.conrol_transfer_stage == DATA_STAGE)
592                 {
593                         if(result_td->parent_ed_p->ed_desc.is_ep_in==false)
594                         {
595                                 result_td->parent_ed_p->ed_status.is_ping_enable = true;
596                         }
597                 }
598                 else if(result_td->standard_dev_req_info.conrol_transfer_stage == STATUS_STAGE)
599                 {
600                         if(result_td->parent_ed_p->ed_desc.is_ep_in==true)
601                         {
602                                 result_td->parent_ed_p->ed_status.is_ping_enable = true;
603                         }
604                 }
605                 else
606                 {
607                         result_td->parent_ed_p->ed_status.is_ping_enable = false;
608                 }
609
610
611         }
612
613
614
615         update_datatgl(hc_reg_data->hc_size.b.pid, result_td);
616
617         return ret_val;
618
619 }
620
621 /******************************************************************************/
622 /*!
623  * @name        void    process_bblerr_on_control(      td_t    *result_td,
624  *                                              hc_info_t *hc_reg_data)
625  *
626  *
627  * @brief               this function deals with the Babble event according to Synopsys OTG Spec.
628  *                      babble error can be just occured at IN Transaction. So if the direction of transfer is
629  *                      OUT, this function return Error Code.
630  *
631  * @param       [IN]    result_td               -indicates  the pointer of the td_t to be mapped with the uChNum.
632  *              [IN]    hc_reg_data     -indicates the interrupt information of the Channel to be interrupted
633  *
634  * @return      DE_ALLOCATE
635  *              NO_ACTION       -if the direction is OUT
636  */
637 /******************************************************************************/
638 u8      process_bblerr_on_control(      td_t    *result_td,
639                                         hc_info_t *hc_reg_data)
640 {
641
642         if(!result_td->parent_ed_p->ed_desc.is_ep_in)
643         {
644                 return NO_ACTION;
645         }
646
647         result_td->err_cnt      = 0;
648         result_td->error_code   =USB_ERR_STATUS_BBLERR;
649
650         clear_ch_intr(result_td->cur_stransfer.alloc_chnum,     CH_STATUS_ALL);
651
652         //Mask ack Interrupt..
653         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
654         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
655         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
656
657         result_td->parent_ed_p->ed_status.is_ping_enable        =false;
658
659         // we just calculate the size of the transferred data on Data Stage of Control Transfer.
660         if(result_td->standard_dev_req_info.conrol_transfer_stage == DATA_STAGE)
661         {
662                 result_td->transferred_szie += calc_transferred_size(false, result_td, hc_reg_data);
663         }
664
665         return DE_ALLOCATE;
666 }
667
668 /******************************************************************************/
669 /*!
670  * @name        u8      process_datatgl_on_control(td_t         *result_td,
671  *                                              hc_info_t *hc_reg_data)
672  *
673  *
674  * @brief               this function deals with the datatglerr event according to Synopsys OTG Spec.
675  *                      the datatglerr event is occured at IN Transfer.
676  *                      this function just resets result_td->err_cnt and masks ack/nak/DataTgl of HCINTMSK.
677  *                      finally, this function clears datatglerr bit of HCINT.
678  *
679  * @param       [IN]    result_td               -indicates  the pointer of the td_t to be mapped with the uChNum.
680  *              [IN]    hc_reg_data     -indicates the interrupt information of the Channel to be interrupted
681  *
682  * @return      NO_ACTION
683  */
684 /******************************************************************************/
685 u8      process_datatgl_on_control(     td_t *          result_td,
686                                                 hc_info_t *     hc_reg_data)
687 {
688         result_td->err_cnt = 0;
689         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
690         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
691         mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
692         clear_ch_intr(result_td->cur_stransfer.alloc_chnum,     CH_STATUS_DataTglErr);
693
694         return NO_ACTION;
695
696 }
697
698