xref: /utopia/UTPA2-700.0.x/modules/usb/drv/usb_ecos/usbhost/drvEHCI_MEM.cxx (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 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
80 #include "include/drvPorts.h"
81 #include "drvEHCI.h"
82 
83 #if 1
84 
ehci_hcd_free(struct usb_hcd * hcd)85  void ehci_hcd_free (struct usb_hcd *hcd)
86 {
87   kfree (hcd_to_ehci (hcd));
88 }
89 
90 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
ehci_hcd_alloc(void)91  struct usb_hcd *ehci_hcd_alloc (void)
92 {
93 
94   struct ehci_hcd *ehci;
95 
96   ehci = (struct ehci_hcd *)
97     kmalloc (sizeof (struct ehci_hcd), GFP_KERNEL);
98 
99   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
100   if (ehci != 0)
101   {
102     diag_printf("ehci: %lx\n", (U32) ehci);
103     memset (ehci, 0, sizeof (struct ehci_hcd));
104     //ehci->hcd.product_desc = "EHCI Host Controller";
105     memcpy(ehci->hcd.product_desc, "EHCI Host Controller", sizeof(ehci->hcd.product_desc));
106     return &ehci->hcd;
107   }
108 
109   return 0;
110 }
111 static __inline__ void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma);
112 
113 /*-------------------------------------------------------------------------*/
114 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
ehci_qtd_alloc(struct ehci_hcd * ehci,int flags)115 static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, int flags)
116 {
117   struct ehci_qtd    *qtd;
118   dma_addr_t    dma;
119 
120   qtd = (struct ehci_qtd*) pci_pool_alloc (ehci->qtd_pool, flags, &dma);
121   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
122   if (qtd != 0)
123   {
124     ehci_qtd_init (qtd, dma);
125   }
126 
127   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
128   return qtd;
129 }
130 
131 
ehci_qtd_init(struct ehci_qtd * qtd,dma_addr_t dma)132 static __inline__ void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma)
133 {
134   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
135   memset (qtd, 0, sizeof *qtd);
136   qtd->qtd_dma = dma;
137   qtd->hw_token = CPUToLE32 (QTD_STS_HALT);
138   qtd->hw_next = EHCI_LIST_END;
139   qtd->hw_alt_next = EHCI_LIST_END;
140   INIT_LIST_HEAD (&qtd->qtd_list);
141 }
142 
143 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
ehci_qtd_free(struct ehci_hcd * ehci,struct ehci_qtd * qtd)144 static __inline__ void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd)
145 {
146   pci_pool_free (ehci->qtd_pool, qtd, qtd->qtd_dma);
147 }
148 
149 
ehci_qh_alloc(struct ehci_hcd * ehci,int flags)150 static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags)
151 {
152   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
153   struct ehci_qh    *qh;
154   dma_addr_t    dma;
155 
156   qh = (struct ehci_qh *)
157     pci_pool_alloc (ehci->qh_pool, flags, &dma);
158   if (!qh)
159     return qh;
160 
161   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
162   memset (qh, 0, sizeof *qh);
163   atomic_set (&qh->refcount, 1);
164   qh->qh_dma = dma;
165   // INIT_LIST_HEAD (&qh->qh_list);
166   diag_printf("qh: %p, qh->qh_dma: %p\n", (MS_U32)qh, qh->qh_dma);
167   INIT_LIST_HEAD (&qh->qtd_list);
168 
169   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
170   qh->dummy = ehci_qtd_alloc (ehci, flags);
171   if (qh->dummy == 0)
172   {
173     ehci_dbg (ehci, "no dummy td%s%s","\n","");
174     pci_pool_free (ehci->qh_pool, qh, qh->qh_dma);
175     qh = 0;
176   }
177 
178   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
179   return qh;
180 }
181 
182 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
qh_get(struct ehci_qh * qh)183 static __inline__ struct ehci_qh *qh_get (/* ehci, */ struct ehci_qh *qh)
184 {
185   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
186   atomic_inc (&qh->refcount);
187   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
188   return qh;
189 }
190 
191 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
qh_put(struct ehci_hcd * ehci,struct ehci_qh * qh)192 static void qh_put (struct ehci_hcd *ehci, struct ehci_qh *qh)
193 {
194   if (!atomic_dec_and_test (&qh->refcount))
195     return;
196   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
197   if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr)
198   {
199     ehci_dbg (ehci, "unused qh not empty%s%s","!","\n");
200     BUG ();
201   }
202 
203   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
204   if (qh->dummy)
205     ehci_qtd_free (ehci, qh->dummy);
206 
207   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
208   pci_pool_free (ehci->qh_pool, qh, qh->qh_dma);
209 }
210 
211 /*-------------------------------------------------------------------------*/
212 
213 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
ehci_mem_cleanup(struct ehci_hcd * ehci)214 static void ehci_mem_cleanup (struct ehci_hcd *ehci)
215 {
216   if (ehci->async)
217     qh_put (ehci, ehci->async);
218   ehci->async = 0;
219 
220   /* PCI consistent memory and pools */
221   if (ehci->qtd_pool)
222     pci_pool_destroy (ehci->qtd_pool);
223   ehci->qtd_pool = 0;
224 
225   if (ehci->qh_pool) {
226     pci_pool_destroy (ehci->qh_pool);
227     ehci->qh_pool = 0;
228   }
229 
230   if (ehci->itd_pool)
231     pci_pool_destroy (ehci->itd_pool);
232   ehci->itd_pool = 0;
233 
234   if (ehci->sitd_pool)
235     pci_pool_destroy (ehci->sitd_pool);
236   ehci->sitd_pool = 0;
237 
238   if (ehci->periodic)
239   {
240     /*
241     pci_free_consistent (ehci->hcd.pdev,
242       ehci->periodic_size * sizeof (u32),
243       ehci->periodic, ehci->periodic_dma);
244       ehci->periodic = 0;
245     */
246     //free(ehci->periodic_rptr);
247     hcd_buffer_free(&ehci->hcd.self, ehci->periodic_size * sizeof (void *), ehci->periodic, ehci->periodic_dma);
248   }
249   ehci->periodic = 0;
250   ehci->periodic_dma = 0;
251 
252   /* shadow periodic table */
253   if (ehci->pshadow)
254     kfree (ehci->pshadow);
255   ehci->pshadow = 0;
256 }
257 
258 /*******************************************************************************
259  * Function name: alloc_ehci_periodic
260  *    returns    :
261  * Created by    : Peter Liao
262  * Date created : 2003/12/10
263  * Description  : It will allocate memory for ohci hcca (32-byte boundary) from
264  *                global memory.(32-byte boundary)
265  * Notes        :
266  ******************************************************************************/
267 /*
268 static struct u32 *alloc_ehci_periodic(struct ohci_hcca **rptr,unsigned long size)
269 {
270   *rptr = (struct u32 *)malloc(size+32);
271   if ( *rptr != NULL ) {
272     return (struct u32 *)( (u32)((char *)(*rptr) + 31) & ~31 );
273   }
274   else {
275     return NULL;
276   }
277 }
278 */
279 
280 
281 /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
ehci_mem_init(struct ehci_hcd * ehci,int flags)282 static int ehci_mem_init (struct ehci_hcd *ehci, int flags)
283 {
284 
285   U32 i;
286 
287   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
288   vdbg("Creat Page memory poof for qtd%s","\n");
289   ehci->qtd_pool = pci_pool_create ("ehci_qtd", ehci->hcd.pdev,
290       sizeof (struct ehci_qtd),
291       32 /* byte alignment (for hw parts) */,
292       4096 /* can't cross 4K */);
293   if (!ehci->qtd_pool)
294   {
295     goto fail;
296   }
297 
298   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
299   vdbg("Creat Page memory poof for qh%s","\n");
300   ehci->qh_pool = pci_pool_create ("ehci_qh", ehci->hcd.pdev,
301       sizeof (struct ehci_qh),
302       32 /* byte alignment (for hw parts) */,
303       4096 /* can't cross 4K */);
304   if (!ehci->qh_pool)
305   {
306     goto fail;
307   }
308   ehci->async = ehci_qh_alloc (ehci, flags);
309   if (!ehci->async)
310   {
311     goto fail;
312   }
313 
314   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
315   vdbg("Creat Page memory poof for itd%s","\n");
316   ehci->itd_pool = pci_pool_create ("ehci_itd", ehci->hcd.pdev,
317       sizeof (struct ehci_itd),
318       32 /* byte alignment (for hw parts) */,
319       4096 /* can't cross 4K */);
320   if (!ehci->itd_pool)
321   {
322     goto fail;
323   }
324   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
325   vdbg("Creat Page memory poof for sitd%s","\n");
326   ehci->sitd_pool = pci_pool_create ("ehci_sitd", ehci->hcd.pdev,
327       sizeof (struct ehci_sitd),
328       32 /* byte alignment (for hw parts) */,
329       4096 /* can't cross 4K */);
330   if (!ehci->sitd_pool)
331   {
332     goto fail;
333   }
334 
335   /* Hardware periodic table */
336   /*
337   ehci->periodic = (u32 *)
338     pci_alloc_consistent (ehci->hcd.pdev,
339       ehci->periodic_size * sizeof (u32),
340       &ehci->periodic_dma);
341   */
342   /*
343   ehci->periodic = alloc_ehci_periodic ( ehci->periodic_rptr, ehci->periodic_size * sizeof (u32));
344   ehci->periodic_dma = ehci->periodic;
345   */
346   ehci->periodic = (U32*) hcd_buffer_alloc(&ehci->hcd.self,ehci->periodic_size * sizeof (void *),0,&ehci->periodic_dma);
347   //ehci->periodic_dma = (dma_addr_t) ehci->periodic;	//Note_HC_Test
348   vdbg("Allocate a non-cacheable memory poof for periodic frame list array %p\n",ehci->periodic);
349   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
350   if (ehci->periodic == 0)
351   {
352     goto fail;
353   }
354   for (i = 0; i < ehci->periodic_size; i++)
355     ehci->periodic [i] = EHCI_LIST_END;
356 
357   /*USB HOST USB HOST USB HOST USB HOST USB HOST USB HOST*/
358   ehci->pshadow = (union ehci_shadow  *) kmalloc (ehci->periodic_size * sizeof (void *), flags);
359   if (ehci->pshadow == 0)
360   {
361     goto fail;
362   }
363   memset (ehci->pshadow, 0, ehci->periodic_size * sizeof (void *));
364   return 0;
365 
366 fail:
367   ehci_dbg (ehci, "couldn't init memory%s","");
368   ehci_mem_cleanup (ehci);
369   return -ENOMEM;
370 }
371 #endif	//#ifdef
372 
373