xref: /utopia/UTPA2-700.0.x/modules/usb/drv/usb_ecos/newhost/drvUsbd.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 
79 //#include <MsCommon.h> // NUSED
80 #include  "include/drvConfig.h"
81 
82 #ifdef CONFIG_USB_DEBUG
83 #define DEBUG
84 #endif
85 
86 //#include  "include/drvCompiler.h" // NUSED
87 #include  "include/drvErrno.h"
88 //#include  "include/drvPorts.h" // NUSED
89 //#include  "include/drvPCIMEM.h" // NUSED
90 //#include  "include/drvTimer.h" // NUSED
91 //#include  "include/drvList.h" // NUSED
92 //#include  "include/drvCompletion.h" // NUSED
93 //#include  "include/drvOSAPI.h" // NUSED
94 //#include  "include/drvKernel.h" // NUSED
95 //#include  "include/drvBitops.h" // NUSED
96 //#include <cyg/hal/hal_if.h> // NUSED
97 //#include <cyg/hal/hal_cache.h> // NUSED
98 
99 // USB related header files
100 //#include "include/drvUSBHost.h" // NUSED
101 //#include "drvUsbd.h" // NUSED
102 #include "drvEHCI.h"
103 #include "drvUSBHwCtl.h"
104 //#include "drvMassStor.h" // NUSED
105 
106 extern void ms_ehci_disable_ep (struct usb_hcd *pHcd, struct s_hcd_dev *pDev, int iEp);
107 extern int ms_hub_status_data (struct usb_hcd *pHcd, char *pBuf);
108 extern int ms_hub_control (  struct usb_hcd  *pHcd,  U16    typeReq,  U16    u16Value,  U16    u16Index,  char    *pBuf) ;
109 
110 struct list_head usb_bus_list = { &(usb_bus_list), &(usb_bus_list) };
111 
112 #define MS_USB_MAXBUS    32
113 struct ms_usb_busmap {
114   U32 busmap [MS_USB_MAXBUS / (8*sizeof (U32))];
115 };
116 static struct ms_usb_busmap busmap;
117 S32 usb_bus_list_lock;
118 
119 /*-------------------------------------------------------------------------*/
120 
121 #define KERNEL_REL  1
122 #define KERNEL_VER  10
123 
124 #define DBG_MSG
125 #define DBG_WARN
126 //#define DBG_FUNC
127 
128 #undef  ms_debug_msg
129 #undef  ms_debug_warn
130 #undef  ms_debug_func
131 
132 #ifdef DBG_MSG
133 #define ms_debug_msg(fmt, arg...)    \
134         do {diag_printf(fmt, ##arg);} while(0)
135 #else
136 #define ms_debug_msg(fmt, arg...) do {} while (0)
137 #endif
138 
139 #ifdef DBG_WARN
140 #define ms_debug_warn(fmt, arg...)    \
141         do {diag_printf(fmt, ##arg);} while(0)
142 #else
143 #define ms_debug_warn(fmt, arg...) do {} while (0)
144 #endif
145 
146 #ifdef DBG_FUNC
147 #define ms_debug_func(fmt, arg...)    \
148         do {diag_printf(fmt, ##arg);} while(0)
149 #else
150 #define ms_debug_func(fmt, arg...) do {} while (0)
151 #endif
152 
153 
154 static const unsigned char hs_rh_dev_descriptor [18] = {
155   0x12,
156   0x01,
157   0x00, 0x02,
158 
159   0x09,
160   0x00,
161   0x01,
162   0x08,
163 
164   0x00, 0x00,
165   0x00, 0x00,
166   KERNEL_VER, KERNEL_REL,
167 
168   0x03,
169   0x02,
170   0x01,
171   0x01
172 };
173 
174 static const unsigned char fs_rh_dev_descriptor [18] = {
175   0x12,
176   0x01,
177   0x10, 0x01,
178 
179   0x09,
180   0x00,
181   0x00,
182   0x08,
183 
184   0x00, 0x00,
185   0x00, 0x00,
186   KERNEL_VER, KERNEL_REL,
187 
188   0x03,
189   0x02,
190   0x01,
191   0x01
192 };
193 
194 static const unsigned char fs_rh_config_descriptor [] = {
195 
196   0x09,
197   0x02,
198   0x19, 0x00,
199   0x01,
200   0x01,
201   0x00,
202   0x40,
203   0x00,
204 
205   0x09,
206   0x04,
207   0x00,
208   0x00,
209   0x01,
210   0x09,
211   0x00,
212   0x00,
213   0x00,
214 
215   0x07,
216   0x05,
217   0x81,
218   0x03,
219   0x02, 0x00,
220   0xff
221 };
222 
223 static const unsigned char hs_rh_config_descriptor [] = {
224 
225   0x09,
226   0x02,
227   0x19, 0x00,
228   0x01,
229   0x01,
230   0x00,
231   0x40,
232   0x00,
233   0x09,
234   0x04,
235   0x00,
236   0x00,
237   0x01,
238   0x09,
239   0x00,
240   0x00,
241   0x00,
242   0x07,
243   0x05,
244   0x81,
245   0x03,
246   0x02, 0x00,
247   0x0c
248 };
249 
250 /*-------------------------------------------------------------------------*/
ms_ascii2utf(char * s,unsigned char * pUtf,int iUtfMax)251 static int ms_ascii2utf (char *s, unsigned char *pUtf, int iUtfMax)
252 {
253   int iRetval;
254 
255   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
256   for (iRetval = 0; *s && iUtfMax > 1; iUtfMax -= 2, iRetval += 2)
257   {
258     *pUtf++ = *s++;
259     *pUtf++ = 0;
260   }
261   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
262   return iRetval;
263 }
264 
ms_rh_string(int iId,struct usb_hcd * pHcd,unsigned char * pData,int iLen)265 static int ms_rh_string (
266   int    iId,
267   struct usb_hcd  *pHcd,
268   unsigned char    *pData,
269   int    iLen
270 )
271 {
272   char pu8Buf [100];
273 
274   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
275   if (iId == 0)
276   {
277     *pData++ = 4; *pData++ = 3;
278     *pData++ = 0x09; *pData++ = 0x04;
279     return 4;
280   }
281   else if (iId == 1) // Serial number
282   {
283     strncpy(pu8Buf, pHcd->self.bus_name, sizeof(pu8Buf)-1);
284     pu8Buf[sizeof(pu8Buf)-1] = '\0';
285   }
286   else if (iId == 2) // Product
287   {
288     strncpy(pu8Buf, pHcd->product_desc, sizeof(pu8Buf));
289   }
290   else if (iId == 3) // Manufacturer
291   {
292     USB_sprintf(pu8Buf,"%s %s ehci_hcd", "MStar eCos", "1.0");
293   }
294   else
295     return 0;
296   pData [0] = 2 * (strlen(pu8Buf) + 1);
297   pData [1] = 3;  /* type == string */
298   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
299   return 2 + ms_ascii2utf (pu8Buf, pData + 2, iLen - 2);
300 }
301 
302 /*
303   * @brief             process request from root hub urb
304   *
305   * @param          struct usb_hcd *hcd
306   * @param          struct urb *urb
307   *
308   * @return           0
309   */
310 
ms_rh_call_control(struct usb_hcd * pHcd,struct urb * pUrb)311 static int ms_rh_call_control (struct usb_hcd *pHcd, struct urb *pUrb)
312 {
313     struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *) pUrb->pSetupPacket;
314     U16    u16TypeReq, u16Value, u16Index, u16Length;
315     const unsigned char  *bufp = 0;
316     unsigned char    *ubuf = (unsigned char*) pUrb->pTransferBuffer;
317     int    iLen = 0;
318 
319     ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
320     pUrb->hcpriv = pHcd;
321 
322     u16TypeReq  = (cmd->bRequestType << 8) | cmd->bRequest;
323     u16Value   = cmd->wValue;
324     u16Index   = cmd->wIndex;
325     u16Length  = cmd->wLength;
326 
327     if (u16Length > pUrb->u32TransferBufferLength)
328         goto error;
329 
330     pUrb->s32Status = 0;
331     pUrb->u32ActualLength = u16Length;
332     switch (u16TypeReq)
333     {
334         case ReqType_Device | USB_REQ_GET_STATUS:
335             ubuf [0] = 1;
336             ubuf [1] = 0;
337         case ReqType_DeviceOut | USB_REQ_CLEAR_FEATURE:
338         case ReqType_DeviceOut | USB_REQ_SET_FEATURE:
339             ms_debug_msg ("no device features set yet\n");
340             break;
341         case ReqType_Device | USB_REQ_GET_CONFIGURATION:
342             ubuf [0] = 1;
343         case ReqType_DeviceOut | USB_REQ_SET_CONFIGURATION:
344             break;
345         case ReqType_Device | USB_REQ_GET_DESCRIPTOR:
346             switch (u16Value & 0xff00)
347             {
348                 case USB_DT_DEVICE << 8:
349                     if (pHcd->hcd_flags & HCD_HS)
350                         bufp = hs_rh_dev_descriptor;
351                     else if (pHcd->hcd_flags & HCD_FS)
352                         bufp = fs_rh_dev_descriptor;
353                     else
354                         goto error;
355                     iLen = 18;
356                     break;
357                 case USB_DT_CONFIG << 8:
358                     if (pHcd->hcd_flags & HCD_HS)
359                     {
360                         bufp = hs_rh_config_descriptor;
361                         iLen = sizeof hs_rh_config_descriptor;
362                     }
363                     else
364                     {
365                         bufp = fs_rh_config_descriptor;
366                         iLen = sizeof fs_rh_config_descriptor;
367                     }
368                     break;
369                 case USB_DT_STRING << 8:
370                     pUrb->u32ActualLength = ms_rh_string (
371                         u16Value & 0xff, pHcd, ubuf, u16Length);
372                     break;
373                 default:
374                   goto error;
375             }
376             break;
377         case ReqType_Device | USB_REQ_GET_INTERFACE:
378             ubuf [0] = 0;
379         case ReqType_DeviceOut | USB_REQ_SET_INTERFACE:
380             break;
381         case ReqType_DeviceOut | USB_REQ_SET_ADDRESS:
382             ms_debug_msg ("[root hub] device address %d\n", u16Value);
383             break;
384         case ReqType_Endpoint | USB_REQ_GET_STATUS:
385             ubuf [0] = 0;
386             ubuf [1] = 0;
387         case ReqType_EndpointOut | USB_REQ_CLEAR_FEATURE:
388         case ReqType_EndpointOut | USB_REQ_SET_FEATURE:
389             ms_debug_msg ("[no endpoint features yet]\n");
390             break;
391         default:
392             pUrb->s32Status = ms_hub_control (pHcd, u16TypeReq, u16Value, u16Index,
393               (char*) ubuf);
394         break;
395 error:
396         pUrb->s32Status = -EPIPE;
397         ms_debug_msg ("[unsupported hub control message] (maxchild %d)\n", (int)pUrb->dev->u32MaxChild);
398     }
399     if (pUrb->s32Status)
400     {
401         pUrb->u32ActualLength = 0;
402         ms_debug_debug("CTRL: TypeReq=0x%x val=0x%x idx=0x%x iLen=%d ==> %d\n",
403           u16TypeReq, u16Value, u16Index, u16Length, (int)pUrb->s32Status);
404     }
405     if (bufp)
406     {
407         if (pUrb->u32TransferBufferLength < iLen)
408             iLen = pUrb->u32TransferBufferLength;
409         pUrb->u32ActualLength = iLen;
410         memcpy(ubuf, bufp, iLen);
411     }
412     osapi_spin_lock_irq(&hcd_root_hub_lock);
413     // SMP should unlock hcd_root_hub_lock, but not to enable local irq
414     osapi_spin_unlock(&hcd_root_hub_lock);
415     ms_usb_hcd_giveback_urb (pUrb, NULL);
416     osapi_spin_lock(&hcd_root_hub_lock);
417     osapi_spin_unlock_irq (&hcd_root_hub_lock);
418     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
419     return 0;
420 }
421 
422 /*-------------------------------------------------------------------------*/
423 /*
424   * @brief             check root hub port connect status change and
425   *                        run urb's completion funciton
426   *
427   * @param          struct usb_hcd *pHcd
428   *
429   * @return           none
430   */
431 
ms_hcd_poll_rh_status(struct usb_hcd * pHcd)432 void ms_hcd_poll_rh_status(struct usb_hcd *pHcd)
433 {
434     struct urb	*pUrb;
435     int     iLen;
436     unsigned long   ulFlags;
437     char    aBuf[4];
438 
439     ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
440     if (!pHcd->roothub_registered)
441     {
442         ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
443         return;
444     }
445     iLen = ms_hub_status_data(pHcd, aBuf);
446     if (iLen > 0)
447     {
448 
449         osapi_spin_lock_irqsave(&hcd_root_hub_lock, ulFlags);
450         pUrb = pHcd->hcd_status_urb;
451         if (pUrb)
452         {
453             pHcd->hcd_poll_pending = 0;
454             pHcd->hcd_status_urb = NULL;
455             pUrb->u32ActualLength = iLen;
456             pUrb->s32Status = 0; // update status
457             pUrb->hcpriv = 0;
458             memcpy(pUrb->pTransferBuffer, aBuf, iLen);
459             osapi_spin_unlock(&hcd_root_hub_lock);
460             ms_usb_hcd_giveback_urb(pUrb, NULL);
461             osapi_spin_lock(&hcd_root_hub_lock);
462         }
463         else
464         {
465             diag_printf("#### null urb in usb_hcd_poll_rh_status\n");
466             iLen = 0;
467             pHcd->hcd_poll_pending = 1;
468         }
469         osapi_spin_unlock_irqrestore(&hcd_root_hub_lock, ulFlags);
470     }
471 
472     /* new polling scheme applied, not to modify timer */
473     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
474 }
475 
476 /*-------------------------------------------------------------------------*/
477 /*
478   * @brief             assign urb to hcd and check need report hub status change or not?
479   *
480   * @param          struct usb_hcd *pHcd
481   * @param          struct urb *pUrb
482   *
483   * @return           error code
484   */
485 
ms_rh_queue_status(struct usb_hcd * pHcd,struct urb * pUrb)486 static int ms_rh_queue_status (struct usb_hcd *pHcd, struct urb *pUrb)
487 {
488     int     iRet;
489     unsigned long   ulFlags;
490     int     iLen = 1 + (pUrb->dev->u32MaxChild / 8);
491 
492     ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
493     osapi_spin_lock_irqsave (&hcd_root_hub_lock, ulFlags);
494     if (pHcd->hcd_status_urb || pUrb->u32TransferBufferLength < iLen)
495     {
496         ms_debug_warn ("not queuing rh status urb\n");
497         iRet = -EINVAL;
498         goto done;
499     }
500 
501     pHcd->hcd_status_urb = pUrb;
502     pUrb->hcpriv = pHcd;
503 
504     /* quickly report hub status change event */
505     if (pHcd->hcd_poll_pending)
506         ms_update_timer(&pHcd->roothub_timer, USB_SW_TIMER_TICK, 0);
507     iRet = 0;
508  done:
509     osapi_spin_unlock_irqrestore (&hcd_root_hub_lock, ulFlags);
510     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
511     return iRet;
512 }
513 /*-------------------------------------------------------------------------*/
514 /*
515   * @brief             dispatch urb for HW
516   *
517   * @param          struct usb_hcd *pHcd
518   * @param          struct urb *pUrb
519   *
520   * @return           error code
521   */
522 
ms_rh_urb_enqueue(struct usb_hcd * pHcd,struct urb * pUrb)523 static int ms_rh_urb_enqueue (struct usb_hcd *pHcd, struct urb *pUrb)
524 {
525   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
526   if (usb_pipeint (pUrb->u32Pipe))
527   {
528     int  iRetval;
529     //U32  u32Flags;
530 
531     //osapi_spin_lock_irqsave (&hcd_data_lock, u32Flags);  // unpatch from Linux
532     iRetval = ms_rh_queue_status (pHcd, pUrb);
533     //osapi_spin_unlock_irqrestore (&hcd_data_lock, u32Flags);
534     return iRetval;
535   }
536   else if (usb_pipecontrol (pUrb->u32Pipe))
537   {
538     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
539     return ms_rh_call_control (pHcd, pUrb);
540   }
541   else
542   {
543     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
544     return -EINVAL;
545   }
546 }
547 
548 /*-------------------------------------------------------------------------*/
549 
ms_rh_status_dequeue(struct usb_hcd * pHcd,struct urb * pUrb)550 void ms_rh_status_dequeue (struct usb_hcd *pHcd, struct urb *pUrb)
551 {
552    unsigned long   ulFlags;
553 
554    ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
555    osapi_spin_lock_irqsave(&hcd_root_hub_lock, ulFlags);
556    if (usb_pipecontrol (pUrb->u32Pipe))
557    {       /* Control URB */
558        ;   /* Do nothing */
559    }
560    else
561    {
562        /* Status URB */
563        if (pUrb == pHcd->hcd_status_urb)
564        {
565            pHcd->hcd_status_urb = NULL;
566            // TODO: FIXME
567            //usb_hcd_unlink_urb_from_ep(hcd, urb);
568 
569            osapi_spin_unlock(&hcd_root_hub_lock);
570            ms_usb_hcd_giveback_urb(pUrb, NULL);
571            osapi_spin_lock(&hcd_root_hub_lock);
572        }
573    }
574    osapi_spin_unlock_irqrestore(&hcd_root_hub_lock, ulFlags);
575    ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
576 }
577 
578 extern void ms_release_OS_Resource_EX(S32 *USBWaitFlg);
579 extern void ms_ehci_end (struct usb_hcd *hcd);
580 extern S32 usb_bus_list_lock;
ms_usb_hcd_cpe_ehci_remove(struct usb_hcd * pHcd)581 void ms_usb_hcd_cpe_ehci_remove (struct usb_hcd *pHcd)
582 {
583     struct usb_device  *pHub;
584 
585     ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
586     ms_debug_msg ("remove: %s, state %x\n", pHcd->self.bus_name, pHcd->state);
587     pHub = pHcd->self.root_hub;
588     ms_usb_get_dev(pHub); // patch from Linux 2.6.28
589     if (HCD_IS_RUNNING (pHcd->state))
590         pHcd->state = HCD_STATE_QUIESCING;
591 
592     osapi_spin_lock_irq (&hcd_root_hub_lock);
593     pHcd->roothub_registered = 0;
594     osapi_spin_unlock_irq (&hcd_root_hub_lock);
595 
596     ms_debug_msg ("%s: roothub graceful disconnect\n", pHcd->self.bus_name);
597     osapi_mutex_lock(usb_bus_list_lock);
598     ms_usb_disconnect (&pHub);
599     osapi_mutex_unlock(usb_bus_list_lock);
600     ms_debug_msg ("%s: roothub disconnect done\n", pHcd->self.bus_name);
601 
602     ms_del_timer_sync(&pHcd->roothub_timer);
603 
604     ms_ehci_end(pHcd); // hcd driver stop
605     pHcd->state = HCD_STATE_HALT;
606 
607     //free_irq (pHcd->irq, pHcd);
608     ms_release_OS_Resource_EX(&pHcd->USBWaitFlg);
609     ms_hcd_buffer_destroy (pHcd);
610     ms_usb_put_dev(pHub); // patch from Linux 2.6.28
611     ms_usb_deregister_bus (&pHcd->self);
612     kfree (hcd_to_ehci(pHcd));
613     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
614 }
615 
616 #ifdef CONFIG_PM
ms_usb_hcd_cpe_ehci_suspend(struct usb_hcd * hcd)617 int ms_usb_hcd_cpe_ehci_suspend (struct usb_hcd *hcd)
618 {
619     int retval = 0;
620 
621     ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
622     switch (hcd->state)
623     {
624         case HCD_STATE_HALT:
625             ms_debug_msg ("halted; hcd not suspended\n");
626             break;
627         case HCD_STATE_SUSPENDED:
628             ms_debug_msg ("hcd already suspended\n");
629             break;
630         default:
631             hcd->state = HCD_STATE_QUIESCING;
632             retval = ms_ehci_suspend (hcd, 0);
633             if (retval)
634                 ms_debug_msg ("suspend fail, retval %d\n", retval);
635             break;
636     }
637     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
638     return retval;
639 }
ms_usb_hcd_cpe_ehci_resume(struct usb_hcd * hcd)640 int ms_usb_hcd_cpe_ehci_resume(struct usb_hcd *hcd)
641 {
642     int retval=0;
643 
644     ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
645     if (hcd->state != HCD_STATE_SUSPENDED)
646     {
647         ms_debug_msg ("can't resume, not suspended!\n");
648         ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
649         return -46;//return -EL3HLT;
650     }
651     hcd->state = HCD_STATE_RESUMING;
652     /* remote wakeup needs hub->suspend() cooperation */
653     retval = ms_ehci_resume (hcd);
654     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
655     return retval;
656 }
657 
658 #endif /* CONFIG_PM */
659 
660 
661 // -------------------------------------------------------------------------
ms_rh_timer_func(unsigned long pHcd)662 inline static void ms_rh_timer_func (unsigned long pHcd)
663 {
664 	ms_hcd_poll_rh_status((struct usb_hcd *) pHcd);
665 }
666 
667 /*
668   * @brief             allocate struct usb_hcd and initial it
669   *
670   * @param          struct usb_hcd **hcd_out
671   * @param          struct cpe_dev *dev
672   *
673   * @return           error code
674   */
675 extern int ms_ehci_init (struct usb_hcd *pHcd);
676 extern int ms_urb_enqueue (struct usb_hcd *pHcd, struct urb *pUrb, int iMem_flags);
677 extern int ms_urb_dequeue (struct usb_hcd *pHcd, struct urb *pUrb);
678 extern void ms_init_OS_Resource_EX(S32 *USBWaitFlg);
679 extern int ms_ehci_begin (struct usb_hcd *hcd);
ms_new_usb_hcd(struct usb_hcd ** pHcd_out,struct cpe_dev * pDev)680 int ms_new_usb_hcd(struct usb_hcd **pHcd_out, struct cpe_dev *pDev)
681 {
682     int iRetVal;
683     struct usb_hcd *pHcd = 0;
684     struct ehci_hcd *pEhci;
685 
686     ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
687     pEhci = (struct ehci_hcd *)kmalloc (sizeof (struct ehci_hcd), GFP_KERNEL);
688     if (pEhci == NULL)
689     {
690         ms_debug_err ("ehci_hcd allocate failed\n");
691         iRetVal = -ENOMEM;
692         goto ex_err1;
693     }
694 
695     ms_debug_func("pEhci: %lx\n", (U32) pEhci);
696     memset (pEhci, 0, sizeof (struct ehci_hcd));
697     strncpy(pEhci->hcd.product_desc, "EHCI Host Controller", sizeof(pEhci->hcd.product_desc));
698     pHcd = (struct usb_hcd *)(&pEhci->hcd);
699     ms_debug_func("pHcd: %lx\n", (U32)pHcd);
700 
701     pHcd->host_id = pDev->devid; // chcek the definition
702     pHcd->phub_event = pDev->pHubEvent;
703     pHcd->ehci_irq = pDev->intNum;
704     pHcd->uhc_regs = (U32*) pDev->uhcbase;
705     pHcd->self.controller = &pDev->dev;
706     pHcd->controller = pHcd->self.controller;
707     pHcd->hcd_flags = HCD_HS;
708 
709     iRetVal = ms_hcd_buffer_create (pHcd);
710     if (iRetVal != 0)
711     {
712         ms_debug_err ("pool alloc fail\n");
713         goto ex_err1;
714     }
715 
716     if ((iRetVal = ms_ehci_init(pHcd)) < 0)
717     {
718         ms_debug_err("can't reset\n");
719         goto ex_err2;
720     }
721 
722     ms_debug_msg ("ehci_hcd (CPE_AMBA) at 0x%p, irq %d\n",
723         pHcd->uhc_regs, pHcd->ehci_irq);
724     ms_usb_bus_init (&pHcd->self);
725     //pHcd->self.bus_ops = &ms_usb_hcd_operations;
726     pHcd->self.hcpriv = (void *) pHcd;
727 
728     pHcd->self.bus_name = pDev->bus_name;
729     //pHcd->product_desc = pDev->product_desc;
730     memcpy(pHcd->product_desc, pDev->product_desc, sizeof(pHcd->product_desc));
731 
732     ms_init_timer(&pHcd->roothub_timer);
733     pHcd->roothub_timer.function = (void *)ms_rh_timer_func;
734     pHcd->roothub_timer.data = (unsigned long) pHcd;
735 
736     pHcd->ms_urb_enqueue = ms_urb_enqueue;
737     pHcd->ms_urb_dequeue = ms_urb_dequeue;
738 
739     //pHcd->pre_sts = 0; // new
740     //pHcd->pre_temp = 0; // new
741     ms_init_OS_Resource_EX(&pHcd->USBWaitFlg);
742     ms_list_init (&pHcd->hcd_dev_list);
743     ms_list_init (&pHcd->tt_clear_list);
744     ms_usb_register_bus (&pHcd->self);
745 
746     if ((iRetVal = ms_ehci_begin(pHcd)) < 0) // start HCD
747     {
748         ms_usb_hcd_cpe_ehci_remove(pHcd);
749         return iRetVal;
750     }
751 
752     *pHcd_out = pHcd;
753 
754     return iRetVal;
755 
756 ex_err2:
757     ms_hcd_buffer_destroy (pHcd);
758     if (pHcd)
759         kfree (hcd_to_ehci (pHcd));
760 ex_err1:
761     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
762     return iRetVal;
763 }
764 
765 extern void ms_InitUSBIntr_EX(struct usb_hcd *, int);
ms_create_cpe_hcd(struct cpe_dev * dev)766 int ms_create_cpe_hcd(struct cpe_dev *dev)
767 {
768     struct usb_hcd *hcd = NULL;
769     int ret;
770 
771     ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
772     ms_device_initialize(&dev->dev);
773     ret = ms_new_usb_hcd(&hcd, dev);
774 
775     if (ret == 0)
776     {
777         ms_debug_func("ms_ehci_hcd_cpe_ehci_drv_probe_EX -> allocate usb_hcd\n");
778         dev->dev.driver_data = hcd;
779         ms_InitUSBIntr_EX(hcd, 0);
780     }
781     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
782     return ret;
783 }
784 
785 /*-------------------------------------------------------------------------*/
ms_usb_bus_init(struct usb_bus * bus)786 void ms_usb_bus_init (struct usb_bus *bus)
787 {
788   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
789   memset (&bus->devmap, 0, sizeof(struct ms_usb_devmap));
790 
791   bus->devnum_next = 1;
792   bus->root_hub = NULL;
793   bus->hcpriv = NULL;
794   bus->busnum = -1;
795 
796   ms_list_init (&bus->bus_list);
797   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
798 }
799 
ms_usb_register_bus(struct usb_bus * pBus)800 int ms_usb_register_bus(struct usb_bus *pBus)
801 {
802   int iBusNum;
803 
804   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, (int)__LINE__);
805   //osapi_down (&usb_bus_list_lock);
806   osapi_mutex_lock(usb_bus_list_lock);
807   iBusNum = find_next_zero_bit (busmap.busmap, MS_USB_MAXBUS, 1);
808   if (iBusNum < MS_USB_MAXBUS)
809   {
810     ms_set_bit (iBusNum, busmap.busmap, U32);
811     pBus->busnum = iBusNum;
812   }
813   else
814   {
815     ms_debug_warn ("too many buses %s\n", pBus->bus_name);
816     osapi_mutex_unlock(usb_bus_list_lock);
817     return -MS_ERR_2BIG;
818   }
819   ms_insert_list_after (&pBus->bus_list, &usb_bus_list);
820   //osapi_up (&usb_bus_list_lock);
821   osapi_mutex_unlock(usb_bus_list_lock);
822 
823   ms_debug_msg ("new USB Bus, assigned pBus number %d\n", (int)pBus->busnum);
824   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, (int)__LINE__);
825   return 0;
826 }
827 
ms_usb_deregister_bus(struct usb_bus * pBus)828 void ms_usb_deregister_bus (struct usb_bus *pBus)
829 {
830   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
831   ms_debug_msg ("USB pBus %d deregistered\n", (int)pBus->busnum);
832   //osapi_down (&usb_bus_list_lock);
833   osapi_mutex_lock(usb_bus_list_lock);
834   ms_list_remove (&pBus->bus_list);
835   //osapi_up (&usb_bus_list_lock);
836   osapi_mutex_unlock(usb_bus_list_lock);
837   ms_clear_bit (pBus->busnum, busmap.busmap, U32);
838   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
839 }
840 
ms_register_root_hub(struct usb_hcd * pHcd)841 int ms_register_root_hub(struct usb_hcd *pHcd)
842 {
843     //struct device *parent_dev = pHcd->self.controller;
844     struct device_s *pParent_dev = pHcd->controller;
845     struct usb_device *pUsb_dev = pHcd->self.root_hub;
846     const int iDevnum = 1;
847     int iRetval;
848 
849     ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
850     //pUsb_dev->eState = USB_STATE_DEFAULT;
851 
852     pUsb_dev->u32DevNum = iDevnum;
853     pUsb_dev->bus->devnum_next = iDevnum + 1;
854     //ms_set_bit (iDevnum, pUsb_dev->bus->devmap.usb_devicemap, U32);
855     ms_devmap_set_bit (iDevnum, pUsb_dev->bus->devmap.usb_devicemap);
856     ms_usb_set_device_state(pUsb_dev, USB_STATE_ADDRESS); // patch from Linux 2.6.28
857 
858     osapi_mutex_lock(usb_bus_list_lock);
859 
860     iRetval = ms_usb_new_device (pUsb_dev, pParent_dev);
861     if (iRetval)
862         ms_debug_err ("can't register root hub for %s, %d\n",
863           pUsb_dev->dev.bus_id, iRetval);
864     osapi_mutex_unlock(usb_bus_list_lock);
865 
866     if (iRetval == 0)
867     {
868         osapi_spin_lock_irq (&hcd_root_hub_lock);
869         pHcd->roothub_registered = 1;
870         osapi_spin_unlock_irq (&hcd_root_hub_lock);
871     }
872 
873     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
874     return iRetval;
875 }
876 
877 /*-------------------------------------------------------------------------*/
878 /*
879   * @brief             estimate periodic transaction time in nano-second
880   *
881   * @param          int iSpeed
882   * @param          int is_input
883   * @param          int iBytes
884   *
885   * @return           how many nano-seconds
886   */
ms_usb_calc_bus_time(int iSpeed,int is_input,int iBytes)887 int ms_usb_calc_bus_time (int iSpeed, int is_input, int iBytes)
888 {
889   U32  u32Tmp;
890   int  iRet;
891 
892   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
893   /* support interrupt pipe now */
894   switch (iSpeed)
895   {
896   case USB_LOW_SPEED:
897     if (is_input)
898     {
899       u32Tmp = (67667L * (31L + 10L * ms_CalcBitTime (iBytes))) / 1000L;
900       iRet = (64060L + (2 * HUB_BW_LS_SETUP) + EHCI_BW_DELAY + u32Tmp);
901     }
902     else
903     {
904       u32Tmp = (66700L * (31L + 10L * ms_CalcBitTime (iBytes))) / 1000L;
905       iRet = (64107L + (2 * HUB_BW_LS_SETUP) + EHCI_BW_DELAY + u32Tmp);
906     }
907     break;
908   case USB_FULL_SPEED:
909     u32Tmp = (8354L * (31L + 10L * ms_CalcBitTime (iBytes))) / 1000L;
910     iRet = (9107L + EHCI_BW_DELAY + u32Tmp);
911     break;
912   case USB_HIGH_SPEED:
913     u32Tmp = HIGHSPEED_NS(iBytes);
914     iRet = (int)u32Tmp;
915     break;
916   default:
917     ms_debug_err ("Unknown device iSpeed!\n");
918     iRet = -1;
919   }
920 
921   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
922   return iRet;
923 }
924 
925 /*-------------------------------------------------------------------------*/
ms_hcd_alloc_dev(struct usb_device * iUdev)926 int ms_hcd_alloc_dev (struct usb_device *iUdev)
927 {
928   struct s_hcd_dev    *pDev;
929   struct usb_hcd    *pHcd;
930   U32    u32Flags;
931   int    iRet = 0;
932 
933   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
934   if (!iUdev || iUdev->hcpriv)
935     iRet = -EINVAL;
936   if (!iUdev->bus || !iUdev->bus->hcpriv)
937     iRet = -ENODEV;
938   pHcd = (struct usb_hcd*) iUdev->bus->hcpriv;
939   if (pHcd->state == HCD_STATE_QUIESCING)
940     iRet = -MS_ERR_NOLINK;
941 
942   pDev = (struct s_hcd_dev *) kmalloc (sizeof *pDev, GFP_KERNEL);
943   if (pDev == NULL)
944     iRet = -ENOMEM;
945   memset (pDev, 0, sizeof *pDev);
946 
947   ms_list_init (&pDev->dev_list);
948   ms_list_init (&pDev->urb_list);
949 
950   osapi_spin_lock_irqsave (&hcd_data_lock, u32Flags);
951   ms_insert_list_after (&pDev->dev_list, &pHcd->hcd_dev_list);
952 
953   iUdev->hcpriv = pDev;
954   osapi_spin_unlock_irqrestore (&hcd_data_lock, u32Flags);
955 
956   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
957   return iRet;
958 }
959 
960 /*-------------------------------------------------------------------------*/
ms_urb_unlink(struct urb * pUrb)961 void ms_urb_unlink (struct urb *pUrb)
962 {
963   U32    u32Flags;
964   struct usb_device  *dev;
965 
966   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
967   /* clear and release pUrb allocate resource */
968   osapi_spin_lock_irqsave (&hcd_data_lock, u32Flags);
969   ms_list_remove_and_init (&pUrb->urb_list);
970   dev = pUrb->dev;
971   osapi_spin_unlock_irqrestore (&hcd_data_lock, u32Flags);
972   ms_usb_put_dev (dev);
973   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
974 }
975 
976 /*
977   * @brief             allocate struct usb_hcd and initial it
978   *
979   * @param          struct urb *urb
980   * @param          int mem_flags
981   *
982   * @return           status
983   */
984 
ms_hcd_submit_urb(struct urb * pUrb,int iMem_flags)985 int ms_hcd_submit_urb (struct urb *pUrb, int iMem_flags)
986 {
987   int      iStatus;
988   struct usb_hcd    *pHcd = (struct usb_hcd*) pUrb->dev->bus->hcpriv;
989   struct s_hcd_dev    *pDev = (struct s_hcd_dev*) pUrb->dev->hcpriv;
990   //struct ehci_hcd    *pEhci = hcd_to_ehci (pHcd);
991   U32    u32Flags;
992 
993   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
994   if (!pHcd || !pDev)
995   {
996     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
997     return -ENODEV;
998   }
999 
1000   //pEhci->uDontSendIAA = 0;	//Set IAA interrupt (default)
1001 
1002   osapi_spin_lock_irqsave (&hcd_data_lock, u32Flags);
1003   // ROOTHUB_INTERRUPT_MODE should adding urb into the list in any condition
1004   if ((HCD_IS_RUNNING (pHcd->state) && pHcd->state != HCD_STATE_QUIESCING) || (pUrb->dev == pHcd->self.root_hub))
1005   {
1006     ms_usb_get_dev (pUrb->dev);
1007     ms_insert_list_before (&pUrb->urb_list, &pDev->urb_list);
1008     iStatus = 0;
1009   }
1010   else
1011   {
1012     ms_list_init (&pUrb->urb_list);
1013     ms_debug_func("[ms_hcd_submit_urb] return ESHUTDOWN !!! pHcd->state = %x\n", pHcd->state);
1014     iStatus = -ESHUTDOWN;
1015   }
1016   osapi_spin_unlock_irqrestore (&hcd_data_lock, u32Flags);
1017   if (iStatus)
1018     return iStatus;
1019 
1020   pUrb = ms_usb_get_urb (pUrb);
1021   if (pUrb->dev == pHcd->self.root_hub)
1022   {
1023     pUrb->u32TransferFlags |= (MS_FLAG_URB_NO_TRANSFER_DMA_MAP
1024           | MS_FLAG_URB_NO_SETUP_DMA_MAP);
1025     iStatus = ms_rh_urb_enqueue (pHcd, pUrb);
1026     goto done;
1027   }
1028 
1029   if (pHcd->controller->dma_mask)
1030   {
1031   }
1032   else
1033   {
1034     // Non DMA support
1035     if (usb_pipecontrol (pUrb->u32Pipe))
1036     {
1037         //if ((((U32) pUrb->setup_packet) & 0xF) != 0 || ((sizeof(struct usb_ctrlrequest)  & 0xF) != 0) )
1038         if ((((U32) pUrb->pSetupPacket) & CPU_L1_CACHE_BOUND) != 0 || ((sizeof(struct usb_ctrlrequest)  & CPU_L1_CACHE_BOUND) != 0) ) // J
1039         {
1040             pUrb->SetDMALen = sizeof(struct usb_ctrlrequest);
1041             //pUrb->SetDMABuf = Usb_AllocateNonCachedMemory(((pUrb->SetDMALen+15) & ~0xF));
1042             pUrb->SetDMABuf = Usb_AllocateNonCachedMemory(((pUrb->SetDMALen+CPU_L1_CACHE_BOUND) & ~CPU_L1_CACHE_BOUND)); // J
1043             USB_ASSERT(pUrb->SetDMABuf != NULL, "Allocate SetDMABuf error\n");
1044 
1045             memcpy(pUrb->SetDMABuf, pUrb->pSetupPacket, pUrb->SetDMALen);
1046             //HAL_DCACHE_FLUSH((void*) pUrb->SetDMABuf, pUrb->SetDMALen);
1047 
1048             pUrb->tSetupDma = (dma_addr_t) USB_VA2PA((U32)pUrb->SetDMABuf);
1049             //diag_printf("[1]SetDMA address %x SetDMA length %x\n", pUrb->tSetupDma, pUrb->SetDMALen);
1050         }
1051         else
1052         {
1053             if ( pUrb->pSetupPacket != KSEG02KSEG1(pUrb->pSetupPacket) )
1054                 MsOS_Dcache_Flush((U32) pUrb->pSetupPacket, sizeof(struct usb_ctrlrequest));
1055 
1056             pUrb->tSetupDma = (dma_addr_t) USB_VA2PA((U32)pUrb->pSetupPacket);
1057             //diag_printf("[2]Setup DMA address %x DMA length %x\n", pUrb->tSetupDma, sizeof(struct usb_ctrlrequest));
1058         }
1059         USB_ASSERT((pUrb->tSetupDma & 0xF) == 0, "DMA address is not 16 bytes aligned\n");
1060 
1061    }
1062 
1063     if (pUrb->u32TransferBufferLength != 0)
1064     {
1065         {
1066             //if ((((U32) pUrb->transfer_buffer) & 0xF) != 0 || ((pUrb->transfer_buffer_length  & 0xF) != 0) )
1067             if ((((U32) pUrb->pTransferBuffer) & CPU_L1_CACHE_BOUND) != 0 || ((pUrb->u32TransferBufferLength  & CPU_L1_CACHE_BOUND) != 0) ) // 20161227, for short buffer
1068             {
1069                 //diag_printf("<ms_hcd_submit_urb> bouncing A[%x], L[%d]\n", pUrb->pTransferBuffer, pUrb->u32TransferBufferLength);
1070                 #ifdef DEBUG_PERFORMANCE
1071                 if (pUrb->u32TransferBufferLength >= 512)
1072                     ms_debug_msg("DMA address %x DMA length %x\n", pUrb->pTransferBuffer, pUrb->u32TransferBufferLength);
1073                 #endif
1074                 pUrb->TxDMALen= pUrb->u32TransferBufferLength;
1075                 //pUrb->TxDMABuf = Usb_AllocateNonCachedMemory(((pUrb->TxDMALen+15) & ~0xF));
1076                 pUrb->TxDMABuf = Usb_AllocateNonCachedMemory(((pUrb->TxDMALen+CPU_L1_CACHE_BOUND) & ~CPU_L1_CACHE_BOUND)); // J
1077                 USB_ASSERT(pUrb->TxDMABuf != NULL, "Allocate TxDMABuf error\n");
1078 
1079                 if (!usb_pipein(pUrb->u32Pipe))
1080                 {
1081                     memcpy(pUrb->TxDMABuf, pUrb->pTransferBuffer, pUrb->u32TransferBufferLength);
1082                 }
1083 
1084                 pUrb->tTransferDma= (dma_addr_t) USB_VA2PA((U32)pUrb->TxDMABuf);
1085                 //diag_printf("TxDMA address %x TxDMA length %x\n", pUrb->tTransferDma, pUrb->TxDMALen);
1086             }
1087             else
1088             {
1089                 if (  pUrb->pTransferBuffer != KSEG02KSEG1(pUrb->pTransferBuffer) )
1090                 {
1091                     if (usb_pipein(pUrb->u32Pipe))
1092                     {
1093                         //MsOS_Dcache_Invalidate((U32) pUrb->transfer_buffer, pUrb->transfer_buffer_length);
1094                         MsOS_Dcache_Flush((U32) pUrb->pTransferBuffer, pUrb->u32TransferBufferLength);
1095                         //MsOS_Dcache_Invalidate((U32) pUrb->pTransferBuffer, pUrb->u32TransferBufferLength);
1096                         /* MsOS_Dcache_Invalidate seems to cause stack crashed... , change to MsOS_Dcache_Flush temporiarly */
1097                     }
1098                     else
1099                         MsOS_Dcache_Flush((U32) pUrb->pTransferBuffer, pUrb->u32TransferBufferLength);
1100 
1101                 }
1102 
1103                 pUrb->tTransferDma= (dma_addr_t) USB_VA2PA((U32)pUrb->pTransferBuffer);
1104                 //diag_printf("DMA address %x DMA length %x, transfer buffer (%x, %x)\n", pUrb->tTransferDma, pUrb->u32TransferBufferLength, pUrb->pTransferBuffer, KSEG02KSEG1(pUrb->pTransferBuffer));
1105             }
1106         }
1107         USB_ASSERT((pUrb->tTransferDma & 0xF) == 0, "DMA address is not 16 bytes aligned\n");
1108     }
1109   }
1110 
1111   iStatus = pHcd->ms_urb_enqueue (pHcd, pUrb, iMem_flags);
1112 done:
1113   if (iStatus)
1114   {
1115     if (pUrb->SetDMABuf != NULL)
1116     {
1117         Usb_FreeNonCachedMemory(pUrb->SetDMABuf);
1118         pUrb->SetDMABuf = NULL;
1119     }
1120     if (pUrb->TxDMABuf != NULL)
1121     {
1122         Usb_FreeNonCachedMemory(pUrb->TxDMABuf);
1123         pUrb->TxDMABuf = NULL;
1124     }
1125     if (!usb_pipecontrol(pUrb->u32Pipe))
1126         diag_printf("[UM] submit_urb fail @ done, rval %d\n", iStatus);
1127     ms_urb_unlink (pUrb);
1128     usb_put_urb (pUrb);
1129   }
1130   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1131   return iStatus;
1132 }
1133 
1134 /*-------------------------------------------------------------------------*/
1135 int
ms_unlink1(struct usb_hcd * pHcd,struct urb * pUrb)1136 ms_unlink1 (struct usb_hcd *pHcd, struct urb *pUrb)
1137 {
1138 	int    retval = 0;
1139 
1140 	ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1141 
1142 	if (pUrb->dev->parent == NULL)
1143 		ms_rh_status_dequeue(pHcd, pUrb);
1144 	else
1145 	{
1146                 retval = pHcd->ms_urb_dequeue(pHcd, pUrb);
1147 	}
1148 	if (retval != 0)
1149 		ms_debug_err("[unlink1] dequeue %p --> %d\n", pUrb, retval);
1150 
1151 	ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1152 	return retval;
1153 }
1154 
1155 /* create completion splice to add "done" when the completion
1156  * function is called, thus urb done is guaranteed
1157  */
1158 struct ms_completion_splice {    // for modified urb context
1159   struct stCompletion  done;
1160   usb_complete_t    stComplete;
1161   void      *pContext;
1162 };
1163 
ms_unlink_complete(struct urb * pUrb,struct stPtRegs * pRegs)1164 static void ms_unlink_complete (struct urb *pUrb, struct stPtRegs *pRegs)
1165 {
1166   struct ms_completion_splice  *pSplice;
1167 
1168   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1169   pSplice = (struct ms_completion_splice *) pUrb->pContext;
1170   pUrb->complete_func = pSplice->stComplete;
1171   pUrb->pContext = pSplice->pContext;
1172   pUrb->complete_func (pUrb, pRegs);  //Callback function
1173   complete (&pSplice->done);
1174   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1175 }
1176 
ms_hcd_unlink_urb(struct urb * pUrb,int sts)1177 int ms_hcd_unlink_urb (struct urb *pUrb, int sts)
1178 {
1179   struct s_hcd_dev      *dev;
1180   struct usb_hcd      *pHcd = 0;
1181   //struct device_s      *pSys = 0;
1182   U32      u32Flags;
1183   struct ms_completion_splice  stSplice;
1184   int        iRetval = 0;
1185   U32    u32Cnt = 0;
1186 
1187   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1188   //if (!pUrb)
1189   //{
1190   //  ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1191   //  return -EINVAL;
1192   //}
1193 
1194   osapi_spin_lock_irqsave (&pUrb->lock, u32Flags);
1195   osapi_spin_lock (&hcd_data_lock);
1196 
1197   if (!pUrb->dev || !pUrb->dev->bus)
1198   {
1199     iRetval = -ENODEV;
1200     goto done;
1201   }
1202 
1203   dev = (struct s_hcd_dev*) pUrb->dev->hcpriv;
1204   //pSys = &pUrb->dev->dev;
1205   pHcd = (struct usb_hcd*) pUrb->dev->bus->hcpriv;
1206   if (!dev || !pHcd)
1207   {
1208     iRetval = -ENODEV;
1209     goto done;
1210   }
1211 
1212   if (!pUrb->hcpriv)
1213   {
1214     iRetval = -EINVAL;
1215     goto done;
1216   }
1217 
1218   if (pUrb->s32Status != -EINPROGRESS)
1219   {
1220     iRetval = -EBUSY;
1221     goto done;
1222   }
1223 
1224   //if (!(pUrb->u32TransferFlags & MS_FLAG_URB_ASYNC_UNLINK))
1225   {
1226     init_completion (&stSplice.done);
1227     stSplice.stComplete = pUrb->complete_func;
1228     stSplice.pContext = pUrb->pContext;
1229     pUrb->complete_func = ms_unlink_complete;
1230     pUrb->pContext = &stSplice;
1231     //pUrb->s32Status = -ENOENT;
1232   }
1233   //else
1234   //{
1235   //  pUrb->s32Status = -ECONNRESET;
1236   //}
1237   pUrb->s32Status = sts;
1238   osapi_spin_unlock (&hcd_data_lock);
1239   osapi_spin_unlock_irqrestore (&pUrb->lock, u32Flags);
1240 
1241   iRetval = ms_unlink1(pHcd, pUrb);
1242   if (iRetval)
1243   {
1244     ms_debug_err ("<%s> dequeue %p --> %d\n", __FUNCTION__, pUrb, iRetval);
1245     if (!(pUrb->u32TransferFlags & MS_FLAG_URB_ASYNC_UNLINK))
1246     {
1247       osapi_spin_lock_irqsave (&pUrb->lock, u32Flags);
1248       pUrb->complete_func = stSplice.stComplete;
1249       pUrb->pContext = stSplice.pContext;
1250       osapi_spin_unlock_irqrestore (&pUrb->lock, u32Flags);
1251     }
1252     goto bye;
1253   }
1254   //if (pUrb == (struct urb *) pHcd->roothub_timer.data)
1255   //if (pUrb->dev->parent == NULL)
1256   //{
1257   //  ms_rh_status_dequeue (pHcd, pUrb);
1258   //  iRetval = 0;
1259   //}
1260   //else
1261   //{
1262   //  iRetval = pHcd->ms_urb_dequeue (pHcd, pUrb);
1263   //
1264   //  if (iRetval)
1265   //  {
1266   //    ms_debug_err ("<%s> dequeue %p --> %d\n", __FUNCTION__, pUrb, iRetval);
1267   //    if (!(pUrb->u32TransferFlags & MS_FLAG_URB_ASYNC_UNLINK))
1268   //    {
1269   //      osapi_spin_lock_irqsave (&pUrb->lock, u32Flags);
1270   //      pUrb->complete_func = stSplice.stComplete;
1271   //      pUrb->pContext = stSplice.pContext;
1272   //      osapi_spin_unlock_irqrestore (&pUrb->lock, u32Flags);
1273   //    }
1274   //    goto bye;
1275   //  }
1276   //}
1277 
1278   if (pUrb->u32TransferFlags & MS_FLAG_URB_ASYNC_UNLINK)
1279   {
1280     ms_debug_err("<%s> MS_FLAG_URB_ASYNC_UNLINK\n", __FUNCTION__);
1281     return -EINPROGRESS;
1282   }
1283 
1284   while ( stSplice.done.done == 0 )
1285   {
1286     if ( u32Cnt > (U32) 3000)
1287     {
1288       break;
1289     }
1290     else
1291     {
1292       //tick base is 1 ms
1293       mdelay(1);
1294       //HAL_DELAY_US(1000); // NUSED
1295       u32Cnt+=1;
1296     }
1297   }
1298 
1299   if (u32Cnt > (U32) 3000)
1300   {
1301      ms_debug_err("<ms_hcd_unlink_urb> timeout!!!\n");
1302      /* restore urb status */
1303      osapi_spin_lock_irqsave (&pUrb->lock, u32Flags);
1304      pUrb->complete_func = stSplice.stComplete;
1305      pUrb->pContext = stSplice.pContext;
1306      pUrb->s32Status = -ETIMEDOUT;
1307      osapi_spin_unlock_irqrestore (&pUrb->lock, u32Flags);
1308      //diag_printf("\n\n\n\n\n\n");
1309      //ms_debug_err("<ms_hcd_unlink_urb> timeout!!!\n");
1310      //diag_printf("\n\n\n\n\n\n");
1311 
1312      //ms_debug_err("Reset HC HW\n"); // no effect
1313      //ms_ResetMstarUsb(pHcd);
1314      return -ETIMEDOUT;
1315   }
1316 
1317   /* Linux code re-assign return-value here */
1318   /* 0 -> -EINPROGRESS */
1319   return 0;
1320 
1321 done:
1322   osapi_spin_unlock (&hcd_data_lock);
1323   osapi_spin_unlock_irqrestore (&pUrb->lock, u32Flags);
1324 bye:
1325   if (iRetval/* && pSys && pSys->driver*/)
1326     ms_debug_err ("<ms_hcd_unlink_urb> %p fail %d\n", pUrb, iRetval);
1327   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1328   return iRetval;
1329 }
1330 
ms_hcd_endpoint_disable(struct usb_device * pUdev,int iEndpoint)1331 void ms_hcd_endpoint_disable (struct usb_device *pUdev, int iEndpoint)
1332 {
1333   struct s_hcd_dev  *pDev;
1334   struct usb_hcd  *pHcd;
1335 
1336   pDev = (struct s_hcd_dev*) pUdev->hcpriv;
1337   pHcd = (struct usb_hcd*) pUdev->bus->hcpriv;
1338 
1339   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1340 
1341   /* move the code to ms_usb_hcd_flush_endpoint() */
1342   /* from: osapi_spin_lock_irq(&hcd_data_lock);
1343    * to: osapi_spin_unlock_irq(&hcd_data_lock);
1344    */
1345 
1346   ms_ehci_disable_ep(pHcd, pDev, iEndpoint);
1347   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1348 }
1349 
ms_usb_hcd_flush_endpoint(struct usb_device * pUdev,int iEndpoint)1350 void ms_usb_hcd_flush_endpoint(struct usb_device *pUdev, int iEndpoint)
1351 {
1352     struct list_head *__mptr;
1353     struct s_hcd_dev  *pDev = (struct s_hcd_dev*) pUdev->hcpriv;
1354     struct usb_hcd  *pHcd = (struct usb_hcd*) pUdev->bus->hcpriv;
1355     struct urb  *pUrb;
1356     U32  u32Epnum = iEndpoint & USB_ENDPOINT_NUMBER_MASK;
1357 
1358     ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1359 
1360     if (iEndpoint & USB_DIR_IN)
1361     {
1362         //usb_endpoint_halt (pUdev, u32Epnum, 0);
1363         pUdev->pEpMaxPacketIn [u32Epnum] = 0;
1364     }
1365     else
1366     {
1367         //usb_endpoint_halt (pUdev, u32Epnum, 1);
1368         pUdev->pEpMaxPacketOut [u32Epnum] = 0;
1369     }
1370 
1371     osapi_spin_lock_irq(&hcd_data_lock);
1372 urb_rescan:
1373     pUrb = entry_to_container((&pDev->urb_list)->next, struct urb, urb_list);
1374     for( ; &(pUrb->urb_list) != &(pDev->urb_list);
1375         __mptr = pUrb->urb_list.next,
1376         pUrb = (struct urb *)( (char *)__mptr - (char *)offsetof(struct urb,urb_list) )
1377     )
1378     {
1379         int  tmp = pUrb->u32Pipe;
1380 
1381         ms_debug_debug("[UM-FLUSH] pUrb %p hcpriv %p,pipe %08x ep%d%s, ep type = %d, status = %d\n",
1382             pUrb, pUrb->hcpriv, tmp, usb_pipeendpoint (tmp),
1383             (tmp & USB_DIR_IN) ? "in" : "out", usb_pipetype (tmp), pUrb->s32Status);
1384 
1385         if ((U32)usb_pipeendpoint (tmp) != u32Epnum)
1386             continue;
1387 
1388         if (u32Epnum != 0 && ((tmp ^ iEndpoint) & USB_DIR_IN))
1389             continue;
1390 
1391         if (pUrb->s32Status != -EINPROGRESS)
1392             continue;
1393         ms_usb_get_urb (pUrb);
1394         osapi_spin_unlock (&hcd_data_lock);
1395 
1396         //osapi_spin_lock (&pUrb->lock);
1397         //tmp = pUrb->s32Status;
1398         //if (tmp == -EINPROGRESS)
1399         //    pUrb->s32Status = -ESHUTDOWN;
1400         //osapi_spin_unlock (&pUrb->lock);
1401 
1402         //if (tmp == -EINPROGRESS)
1403         {
1404             tmp = pUrb->u32Pipe;
1405             pUrb->s32Status = -ESHUTDOWN;
1406             ms_unlink1 (pHcd, pUrb);
1407             ms_debug_debug("<%s> !!! shutdown pUrb %p pipe %08x ep%d%s, ep type = %d\n",
1408                 __FUNCTION__, pUrb, tmp, usb_pipeendpoint (tmp),
1409                 (tmp & USB_DIR_IN) ? "in" : "out", usb_pipetype (tmp));
1410         }
1411         usb_put_urb (pUrb);
1412 
1413         osapi_spin_lock (&hcd_data_lock);
1414         goto urb_rescan;
1415     }
1416     osapi_spin_unlock_irq(&hcd_data_lock);
1417 
1418     // TODO: nuke all urb? depends on ms_hcd_check_dev_urb()'s result
1419     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1420 }
1421 
ms_hcd_check_dev_urb(struct usb_device * pUdev,int iEndpoint)1422 void ms_hcd_check_dev_urb (struct usb_device *pUdev, int iEndpoint)
1423 {
1424     struct list_head *__mptr;
1425     struct s_hcd_dev  *pDev;
1426     //struct usb_hcd  *pHcd;
1427     struct urb  *pUrb;
1428 
1429     pDev = (struct s_hcd_dev*) pUdev->hcpriv;
1430     //pHcd = (struct usb_hcd*) pUdev->bus->hcpriv;
1431 
1432     ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1433     ms_debug_func("[UM-DEV-URB] urb %p, epaddr %d\n", pUrb, iEndpoint);
1434 
1435     osapi_spin_lock_irq(&hcd_data_lock);
1436     pUrb = entry_to_container((&pDev->urb_list)->next, struct urb, urb_list);
1437     for( ; &(pUrb->urb_list) != &(pDev->urb_list);
1438         __mptr = pUrb->urb_list.next,
1439         pUrb = (struct urb *)( (char *)__mptr - (char *)offsetof(struct urb,urb_list) )
1440     )
1441     {
1442         int  tmp = pUrb->u32Pipe;
1443 
1444         diag_printf ("[UM-DEV-URB] pUrb %p (qh %p) pipe %08x ep%d%s, ep type = %d, status = %d\n",
1445             pUrb, pUrb->hcpriv, tmp, usb_pipeendpoint (tmp),
1446             (tmp & USB_DIR_IN) ? "in" : "out", usb_pipetype (tmp), pUrb->s32Status);
1447     }
1448     osapi_spin_unlock_irq(&hcd_data_lock);
1449     ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1450 }
1451 
1452 /*-------------------------------------------------------------------------*/
ms_hcd_free_dev(struct usb_device * pUdev)1453 int ms_hcd_free_dev (struct usb_device *pUdev)
1454 {
1455   struct s_hcd_dev    *pDev;
1456   struct usb_hcd    *pHcd;
1457   U32    u32Flags;
1458   int iRet = ENOERR;
1459 
1460   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1461   if (!pUdev || !pUdev->hcpriv)
1462   {
1463     iRet = -EINVAL;
1464     goto hcd_free_dev_err;
1465   }
1466 
1467   if (!pUdev->bus || !pUdev->bus->hcpriv)
1468   {
1469     iRet = -ENODEV;
1470     goto hcd_free_dev_err;
1471   }
1472 
1473   // should pUdev->devnum == -1 ??
1474 
1475   pDev = (struct s_hcd_dev*) pUdev->hcpriv;
1476   pHcd = (struct usb_hcd*) pUdev->bus->hcpriv;
1477 
1478   if (!ms_is_empty_list (&pDev->urb_list))
1479   {
1480     ms_debug_err ("free busy pDev, %s devnum %d (bug!)\n",
1481       pHcd->self.bus_name, (int)pUdev->u32DevNum);
1482     iRet = -EINVAL;
1483     goto hcd_free_dev_err;
1484   }
1485 
1486   osapi_spin_lock_irqsave (&hcd_data_lock, u32Flags);
1487   ms_list_remove (&pDev->dev_list);
1488   pUdev->hcpriv = NULL;
1489   osapi_spin_unlock_irqrestore (&hcd_data_lock, u32Flags);
1490 
1491   kfree (pDev);
1492 
1493 hcd_free_dev_err:
1494   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1495   return iRet;
1496 }
1497 
1498 /* bus op obsolete */
1499 /*
1500 //struct ms_usb_bus_ops ms_usb_hcd_operations = {
1501 //  ms_hcd_alloc_dev,
1502 //  ms_hcd_free_dev,
1503 //  ms_hcd_submit_urb,
1504 //  ms_hcd_unlink_urb,
1505 //  ms_hcd_buffer_alloc,
1506 //  ms_hcd_buffer_free,
1507 //  ms_hcd_endpoint_disable,
1508 //};
1509 */
1510 
1511 extern void ms_usb_set_dma_buf(struct urb *request_block);
1512 extern void ms_usb_set_tx_dma_buf(struct urb *request_block);
1513 /*-------------------------------------------------------------------------*/
ms_usb_hcd_giveback_urb(struct urb * urb,struct stPtRegs * regs)1514 void ms_usb_hcd_giveback_urb (struct urb *urb, struct stPtRegs *regs)
1515 {
1516   ms_debug_func("++[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1517   ms_urb_unlink (urb);
1518 
1519   /* local setup/tx DMA buffer should be dealed with here, complete function may
1520     lack of such mechanism */
1521   ms_usb_set_dma_buf(urb);
1522   ms_usb_set_tx_dma_buf(urb);
1523 
1524   urb->complete_func (urb, regs);
1525   usb_put_urb (urb);
1526   ms_debug_func("--[%s] line:[%d]\n", __FUNCTION__, __LINE__);
1527 }
1528 /*-------------------------------------------------------------------------*/
1529