1*53ee8cc1Swenshuai.xi //<MStar Software>
2*53ee8cc1Swenshuai.xi //******************************************************************************
3*53ee8cc1Swenshuai.xi // MStar Software
4*53ee8cc1Swenshuai.xi // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5*53ee8cc1Swenshuai.xi // All software, firmware and related documentation herein ("MStar Software") are
6*53ee8cc1Swenshuai.xi // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7*53ee8cc1Swenshuai.xi // law, including, but not limited to, copyright law and international treaties.
8*53ee8cc1Swenshuai.xi // Any use, modification, reproduction, retransmission, or republication of all
9*53ee8cc1Swenshuai.xi // or part of MStar Software is expressly prohibited, unless prior written
10*53ee8cc1Swenshuai.xi // permission has been granted by MStar.
11*53ee8cc1Swenshuai.xi //
12*53ee8cc1Swenshuai.xi // By accessing, browsing and/or using MStar Software, you acknowledge that you
13*53ee8cc1Swenshuai.xi // have read, understood, and agree, to be bound by below terms ("Terms") and to
14*53ee8cc1Swenshuai.xi // comply with all applicable laws and regulations:
15*53ee8cc1Swenshuai.xi //
16*53ee8cc1Swenshuai.xi // 1. MStar shall retain any and all right, ownership and interest to MStar
17*53ee8cc1Swenshuai.xi // Software and any modification/derivatives thereof.
18*53ee8cc1Swenshuai.xi // No right, ownership, or interest to MStar Software and any
19*53ee8cc1Swenshuai.xi // modification/derivatives thereof is transferred to you under Terms.
20*53ee8cc1Swenshuai.xi //
21*53ee8cc1Swenshuai.xi // 2. You understand that MStar Software might include, incorporate or be
22*53ee8cc1Swenshuai.xi // supplied together with third party`s software and the use of MStar
23*53ee8cc1Swenshuai.xi // Software may require additional licenses from third parties.
24*53ee8cc1Swenshuai.xi // Therefore, you hereby agree it is your sole responsibility to separately
25*53ee8cc1Swenshuai.xi // obtain any and all third party right and license necessary for your use of
26*53ee8cc1Swenshuai.xi // such third party`s software.
27*53ee8cc1Swenshuai.xi //
28*53ee8cc1Swenshuai.xi // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29*53ee8cc1Swenshuai.xi // MStar`s confidential information and you agree to keep MStar`s
30*53ee8cc1Swenshuai.xi // confidential information in strictest confidence and not disclose to any
31*53ee8cc1Swenshuai.xi // third party.
32*53ee8cc1Swenshuai.xi //
33*53ee8cc1Swenshuai.xi // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34*53ee8cc1Swenshuai.xi // kind. Any warranties are hereby expressly disclaimed by MStar, including
35*53ee8cc1Swenshuai.xi // without limitation, any warranties of merchantability, non-infringement of
36*53ee8cc1Swenshuai.xi // intellectual property rights, fitness for a particular purpose, error free
37*53ee8cc1Swenshuai.xi // and in conformity with any international standard. You agree to waive any
38*53ee8cc1Swenshuai.xi // claim against MStar for any loss, damage, cost or expense that you may
39*53ee8cc1Swenshuai.xi // incur related to your use of MStar Software.
40*53ee8cc1Swenshuai.xi // In no event shall MStar be liable for any direct, indirect, incidental or
41*53ee8cc1Swenshuai.xi // consequential damages, including without limitation, lost of profit or
42*53ee8cc1Swenshuai.xi // revenues, lost or damage of data, and unauthorized system use.
43*53ee8cc1Swenshuai.xi // You agree that this Section 4 shall still apply without being affected
44*53ee8cc1Swenshuai.xi // even if MStar Software has been modified by MStar in accordance with your
45*53ee8cc1Swenshuai.xi // request or instruction for your use, except otherwise agreed by both
46*53ee8cc1Swenshuai.xi // parties in writing.
47*53ee8cc1Swenshuai.xi //
48*53ee8cc1Swenshuai.xi // 5. If requested, MStar may from time to time provide technical supports or
49*53ee8cc1Swenshuai.xi // services in relation with MStar Software to you for your use of
50*53ee8cc1Swenshuai.xi // MStar Software in conjunction with your or your customer`s product
51*53ee8cc1Swenshuai.xi // ("Services").
52*53ee8cc1Swenshuai.xi // You understand and agree that, except otherwise agreed by both parties in
53*53ee8cc1Swenshuai.xi // writing, Services are provided on an "AS IS" basis and the warranty
54*53ee8cc1Swenshuai.xi // disclaimer set forth in Section 4 above shall apply.
55*53ee8cc1Swenshuai.xi //
56*53ee8cc1Swenshuai.xi // 6. Nothing contained herein shall be construed as by implication, estoppels
57*53ee8cc1Swenshuai.xi // or otherwise:
58*53ee8cc1Swenshuai.xi // (a) conferring any license or right to use MStar name, trademark, service
59*53ee8cc1Swenshuai.xi // mark, symbol or any other identification;
60*53ee8cc1Swenshuai.xi // (b) obligating MStar or any of its affiliates to furnish any person,
61*53ee8cc1Swenshuai.xi // including without limitation, you and your customers, any assistance
62*53ee8cc1Swenshuai.xi // of any kind whatsoever, or any information; or
63*53ee8cc1Swenshuai.xi // (c) conferring any license or right under any intellectual property right.
64*53ee8cc1Swenshuai.xi //
65*53ee8cc1Swenshuai.xi // 7. These terms shall be governed by and construed in accordance with the laws
66*53ee8cc1Swenshuai.xi // of Taiwan, R.O.C., excluding its conflict of law rules.
67*53ee8cc1Swenshuai.xi // Any and all dispute arising out hereof or related hereto shall be finally
68*53ee8cc1Swenshuai.xi // settled by arbitration referred to the Chinese Arbitration Association,
69*53ee8cc1Swenshuai.xi // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70*53ee8cc1Swenshuai.xi // Rules of the Association by three (3) arbitrators appointed in accordance
71*53ee8cc1Swenshuai.xi // with the said Rules.
72*53ee8cc1Swenshuai.xi // The place of arbitration shall be in Taipei, Taiwan and the language shall
73*53ee8cc1Swenshuai.xi // be English.
74*53ee8cc1Swenshuai.xi // The arbitration award shall be final and binding to both parties.
75*53ee8cc1Swenshuai.xi //
76*53ee8cc1Swenshuai.xi //******************************************************************************
77*53ee8cc1Swenshuai.xi //<MStar Software>
78*53ee8cc1Swenshuai.xi
79*53ee8cc1Swenshuai.xi //#include <MsCommon.h> // NUSED
80*53ee8cc1Swenshuai.xi
81*53ee8cc1Swenshuai.xi //#include "include/drvPorts.h" // NUSED
82*53ee8cc1Swenshuai.xi #include "include/drvConfig.h"
83*53ee8cc1Swenshuai.xi //#include "include/drvCompiler.h" // NUSED
84*53ee8cc1Swenshuai.xi //#include "include/drvErrno.h" // NUSED
85*53ee8cc1Swenshuai.xi //#include "include/drvTimer.h" // NUSED
86*53ee8cc1Swenshuai.xi //#include "include/drvList.h" // NUSED
87*53ee8cc1Swenshuai.xi #include "include/drvKernel.h"
88*53ee8cc1Swenshuai.xi #include "include/drvBitops.h"
89*53ee8cc1Swenshuai.xi //#include "include/drvCPE_AMBA.h" // NUSED
90*53ee8cc1Swenshuai.xi
91*53ee8cc1Swenshuai.xi // USB related header files
92*53ee8cc1Swenshuai.xi //#include "include/drvUSBHost.h" // NUSED
93*53ee8cc1Swenshuai.xi #include "drvUSBCore.h"
94*53ee8cc1Swenshuai.xi #include "drvUsbd.h"
95*53ee8cc1Swenshuai.xi #include "drvUSBHwCtl.h"
96*53ee8cc1Swenshuai.xi #include "drvEHCI.h"
97*53ee8cc1Swenshuai.xi //#include "drvUSB.h" // NUSED
98*53ee8cc1Swenshuai.xi /* applying drvUsbHostConfig.h (inside drvUsbd.h <- drvHub.h) */
99*53ee8cc1Swenshuai.xi
100*53ee8cc1Swenshuai.xi extern int ms_usb_hub_init(void);
101*53ee8cc1Swenshuai.xi extern int ms_usb_hub_uninit(void);
102*53ee8cc1Swenshuai.xi //extern void ms_qh_ehci_reinit(struct usb_hcd *pHcd, int fix);
103*53ee8cc1Swenshuai.xi
104*53ee8cc1Swenshuai.xi //int USB_core_lock=0; // NUSED
105*53ee8cc1Swenshuai.xi //int Timer_task_lock=0; // NUSED
106*53ee8cc1Swenshuai.xi
107*53ee8cc1Swenshuai.xi char usb_product_string_buf[64];
108*53ee8cc1Swenshuai.xi char usb_manufacturer_string_buf[64];
109*53ee8cc1Swenshuai.xi char usb_serialnumber_string_buf[64];
110*53ee8cc1Swenshuai.xi
ms_generic_probe(struct device_s * pDev)111*53ee8cc1Swenshuai.xi static int ms_generic_probe (struct device_s *pDev)
112*53ee8cc1Swenshuai.xi {
113*53ee8cc1Swenshuai.xi return 0;
114*53ee8cc1Swenshuai.xi }
ms_generic_remove(struct device_s * pDev)115*53ee8cc1Swenshuai.xi static int ms_generic_remove (struct device_s *pDev)
116*53ee8cc1Swenshuai.xi {
117*53ee8cc1Swenshuai.xi return 0;
118*53ee8cc1Swenshuai.xi }
119*53ee8cc1Swenshuai.xi
120*53ee8cc1Swenshuai.xi static struct device_driver ms_usb_generic_driver = {
121*53ee8cc1Swenshuai.xi "usb_gdrv",
122*53ee8cc1Swenshuai.xi &usb_bus_type,
123*53ee8cc1Swenshuai.xi {NULL,NULL},
124*53ee8cc1Swenshuai.xi {&ms_usb_generic_driver.devices,&ms_usb_generic_driver.devices},
125*53ee8cc1Swenshuai.xi ms_generic_probe,
126*53ee8cc1Swenshuai.xi ms_generic_remove,
127*53ee8cc1Swenshuai.xi };
128*53ee8cc1Swenshuai.xi
129*53ee8cc1Swenshuai.xi static int usb_generic_driver_data;
130*53ee8cc1Swenshuai.xi #if 0 // NUSED
131*53ee8cc1Swenshuai.xi void ms_usb_show_string(struct usb_device *pDev, char *pStringId, int iIdx)
132*53ee8cc1Swenshuai.xi {
133*53ee8cc1Swenshuai.xi char *pCbuf;
134*53ee8cc1Swenshuai.xi
135*53ee8cc1Swenshuai.xi if (!iIdx)
136*53ee8cc1Swenshuai.xi return;
137*53ee8cc1Swenshuai.xi
138*53ee8cc1Swenshuai.xi if (!(pCbuf = (char*) kmalloc(256, GFP_KERNEL)))
139*53ee8cc1Swenshuai.xi return;
140*53ee8cc1Swenshuai.xi
141*53ee8cc1Swenshuai.xi if (ms_usb_string(pDev, iIdx, pCbuf, 256) > 0)
142*53ee8cc1Swenshuai.xi {
143*53ee8cc1Swenshuai.xi diag_printf("<%s> %s: %s\n",__FUNCTION__, pStringId, pCbuf);
144*53ee8cc1Swenshuai.xi }
145*53ee8cc1Swenshuai.xi kfree(pCbuf);
146*53ee8cc1Swenshuai.xi }
147*53ee8cc1Swenshuai.xi #endif
148*53ee8cc1Swenshuai.xi const struct usb_device_id *
ms_usb_match_id(struct usb_interface * pUintf,const struct usb_device_id * pDevId)149*53ee8cc1Swenshuai.xi ms_usb_match_id(struct usb_interface *pUintf, const struct usb_device_id *pDevId)
150*53ee8cc1Swenshuai.xi {
151*53ee8cc1Swenshuai.xi struct usb_host_interface *ms_intf;
152*53ee8cc1Swenshuai.xi struct usb_device *pUdev;
153*53ee8cc1Swenshuai.xi
154*53ee8cc1Swenshuai.xi if (pDevId == NULL)
155*53ee8cc1Swenshuai.xi return NULL;
156*53ee8cc1Swenshuai.xi
157*53ee8cc1Swenshuai.xi ms_intf = &pUintf->altsetting [pUintf->act_altsetting];
158*53ee8cc1Swenshuai.xi pUdev = interface_to_usbdev(pUintf);
159*53ee8cc1Swenshuai.xi
160*53ee8cc1Swenshuai.xi for (; pDevId->idVendor || pDevId->bDeviceClass || pDevId->bInterfaceClass ||
161*53ee8cc1Swenshuai.xi pDevId->match_id_info; pDevId++)
162*53ee8cc1Swenshuai.xi {
163*53ee8cc1Swenshuai.xi if ((pDevId->match_id_flags & USBDEV_MATCH_ID_VENDOR) &&
164*53ee8cc1Swenshuai.xi pDevId->idVendor != pUdev->descriptor.idVendor)
165*53ee8cc1Swenshuai.xi continue;
166*53ee8cc1Swenshuai.xi
167*53ee8cc1Swenshuai.xi if ((pDevId->match_id_flags & USBDEV_MATCH_ID_PRODUCT) &&
168*53ee8cc1Swenshuai.xi pDevId->idProduct != pUdev->descriptor.idProduct)
169*53ee8cc1Swenshuai.xi continue;
170*53ee8cc1Swenshuai.xi
171*53ee8cc1Swenshuai.xi if ((pDevId->match_id_flags & USBDEV_MATCH_ID_DEV_LO) &&
172*53ee8cc1Swenshuai.xi (pDevId->bcdDevice_lo >= pUdev->descriptor.bcdDevice))
173*53ee8cc1Swenshuai.xi continue;
174*53ee8cc1Swenshuai.xi
175*53ee8cc1Swenshuai.xi if ((pDevId->match_id_flags & USBDEV_MATCH_ID_DEV_HI) &&
176*53ee8cc1Swenshuai.xi (pDevId->bcdDevice_hi <= pUdev->descriptor.bcdDevice))
177*53ee8cc1Swenshuai.xi continue;
178*53ee8cc1Swenshuai.xi
179*53ee8cc1Swenshuai.xi if ((pDevId->match_id_flags & USBDEV_MATCH_ID_DEV_CLASS) &&
180*53ee8cc1Swenshuai.xi (pDevId->bDeviceClass != pUdev->descriptor.bDeviceClass))
181*53ee8cc1Swenshuai.xi continue;
182*53ee8cc1Swenshuai.xi
183*53ee8cc1Swenshuai.xi if ((pDevId->match_id_flags & USBDEV_MATCH_ID_DEV_SUBCLASS) &&
184*53ee8cc1Swenshuai.xi (pDevId->bDeviceSubClass!= pUdev->descriptor.bDeviceSubClass))
185*53ee8cc1Swenshuai.xi continue;
186*53ee8cc1Swenshuai.xi
187*53ee8cc1Swenshuai.xi if ((pDevId->match_id_flags & USBDEV_MATCH_ID_DEV_PROTOCOL) &&
188*53ee8cc1Swenshuai.xi (pDevId->bDeviceProtocol != pUdev->descriptor.bDeviceProtocol))
189*53ee8cc1Swenshuai.xi continue;
190*53ee8cc1Swenshuai.xi
191*53ee8cc1Swenshuai.xi if ((pDevId->match_id_flags & USBDEV_MATCH_ID_INT_CLASS) &&
192*53ee8cc1Swenshuai.xi (pDevId->bInterfaceClass != ms_intf->desc.bInterfaceClass))
193*53ee8cc1Swenshuai.xi continue;
194*53ee8cc1Swenshuai.xi
195*53ee8cc1Swenshuai.xi if ((pDevId->match_id_flags & USBDEV_MATCH_ID_INT_SUBCLASS) &&
196*53ee8cc1Swenshuai.xi (pDevId->bInterfaceSubClass != ms_intf->desc.bInterfaceSubClass))
197*53ee8cc1Swenshuai.xi continue;
198*53ee8cc1Swenshuai.xi
199*53ee8cc1Swenshuai.xi if ((pDevId->match_id_flags & USBDEV_MATCH_ID_INT_PROTOCOL) &&
200*53ee8cc1Swenshuai.xi (pDevId->bInterfaceProtocol != ms_intf->desc.bInterfaceProtocol))
201*53ee8cc1Swenshuai.xi continue;
202*53ee8cc1Swenshuai.xi
203*53ee8cc1Swenshuai.xi return pDevId;
204*53ee8cc1Swenshuai.xi }
205*53ee8cc1Swenshuai.xi
206*53ee8cc1Swenshuai.xi return NULL;
207*53ee8cc1Swenshuai.xi }
208*53ee8cc1Swenshuai.xi
ms_usb_probe_interface(struct device_s * pDev)209*53ee8cc1Swenshuai.xi int ms_usb_probe_interface(struct device_s *pDev)
210*53ee8cc1Swenshuai.xi {
211*53ee8cc1Swenshuai.xi struct usb_interface * pUintf = get_usb_interface(pDev);
212*53ee8cc1Swenshuai.xi struct usb_driver * pUdriver = get_usb_driver(pDev->driver);
213*53ee8cc1Swenshuai.xi const struct usb_device_id *pUdev_id;
214*53ee8cc1Swenshuai.xi int s32Error = -ENODEV;
215*53ee8cc1Swenshuai.xi
216*53ee8cc1Swenshuai.xi if (!pUdriver->probe_func)
217*53ee8cc1Swenshuai.xi return s32Error;
218*53ee8cc1Swenshuai.xi
219*53ee8cc1Swenshuai.xi pUdev_id = ms_usb_match_id (pUintf, pUdriver->match_id_table);
220*53ee8cc1Swenshuai.xi if (pUdev_id)
221*53ee8cc1Swenshuai.xi {
222*53ee8cc1Swenshuai.xi ms_usbhost_debug ("<%s> - got id\n", __FUNCTION__);
223*53ee8cc1Swenshuai.xi s32Error = pUdriver->probe_func (pUintf, pUdev_id);
224*53ee8cc1Swenshuai.xi }
225*53ee8cc1Swenshuai.xi if (!s32Error)
226*53ee8cc1Swenshuai.xi pUintf->driver = pUdriver;
227*53ee8cc1Swenshuai.xi
228*53ee8cc1Swenshuai.xi return s32Error;
229*53ee8cc1Swenshuai.xi }
230*53ee8cc1Swenshuai.xi
ms_usb_driver_release_interface(struct usb_driver * pUdriver,struct usb_interface * iface)231*53ee8cc1Swenshuai.xi void ms_usb_driver_release_interface(struct usb_driver *pUdriver, struct usb_interface *iface)
232*53ee8cc1Swenshuai.xi {
233*53ee8cc1Swenshuai.xi // this should never happen, don't release something that's not ours
234*53ee8cc1Swenshuai.xi if (iface->driver && iface->driver != pUdriver)
235*53ee8cc1Swenshuai.xi return;
236*53ee8cc1Swenshuai.xi
237*53ee8cc1Swenshuai.xi #if 0 // ???
238*53ee8cc1Swenshuai.xi iface->driver = NULL;
239*53ee8cc1Swenshuai.xi ms_usb_set_interface(interface_to_usbdev(iface),
240*53ee8cc1Swenshuai.xi iface->altsetting[0].desc.bInterfaceNumber,
241*53ee8cc1Swenshuai.xi 0);
242*53ee8cc1Swenshuai.xi #endif
243*53ee8cc1Swenshuai.xi ms_usb_set_intfdata(iface, NULL);
244*53ee8cc1Swenshuai.xi iface->driver = NULL;
245*53ee8cc1Swenshuai.xi }
246*53ee8cc1Swenshuai.xi
ms_usb_unbind_interface(struct device_s * pDev)247*53ee8cc1Swenshuai.xi int ms_usb_unbind_interface(struct device_s *pDev)
248*53ee8cc1Swenshuai.xi {
249*53ee8cc1Swenshuai.xi struct usb_interface *pUintf = get_usb_interface(pDev);
250*53ee8cc1Swenshuai.xi struct usb_driver *pUdriver = get_usb_driver(pDev->driver);
251*53ee8cc1Swenshuai.xi
252*53ee8cc1Swenshuai.xi ms_usb_disable_interface(interface_to_usbdev(pUintf), pUintf);
253*53ee8cc1Swenshuai.xi
254*53ee8cc1Swenshuai.xi if (pUintf->driver && pUintf->driver->discon_func)
255*53ee8cc1Swenshuai.xi pUintf->driver->discon_func(pUintf);
256*53ee8cc1Swenshuai.xi
257*53ee8cc1Swenshuai.xi ms_usb_driver_release_interface(pUdriver, pUintf);
258*53ee8cc1Swenshuai.xi
259*53ee8cc1Swenshuai.xi return 0;
260*53ee8cc1Swenshuai.xi }
261*53ee8cc1Swenshuai.xi
ms_usb_register(struct usb_driver * n_driver)262*53ee8cc1Swenshuai.xi int ms_usb_register(struct usb_driver *n_driver)
263*53ee8cc1Swenshuai.xi {
264*53ee8cc1Swenshuai.xi int s32Retval = 0;
265*53ee8cc1Swenshuai.xi
266*53ee8cc1Swenshuai.xi memcpy(n_driver->driver.name, n_driver->name, sizeof(n_driver->name));
267*53ee8cc1Swenshuai.xi n_driver->driver.bus = &usb_bus_type;
268*53ee8cc1Swenshuai.xi n_driver->driver.probe = ms_usb_probe_interface;
269*53ee8cc1Swenshuai.xi n_driver->driver.remove = ms_usb_unbind_interface;
270*53ee8cc1Swenshuai.xi
271*53ee8cc1Swenshuai.xi s32Retval = ms_driver_register(&n_driver->driver);
272*53ee8cc1Swenshuai.xi
273*53ee8cc1Swenshuai.xi if (!s32Retval)
274*53ee8cc1Swenshuai.xi {
275*53ee8cc1Swenshuai.xi ms_usbhost_debug("regtered new driver %s", n_driver->name);
276*53ee8cc1Swenshuai.xi }
277*53ee8cc1Swenshuai.xi else
278*53ee8cc1Swenshuai.xi {
279*53ee8cc1Swenshuai.xi ms_usbhost_err("problem %d when registering driver %s",
280*53ee8cc1Swenshuai.xi s32Retval, n_driver->name);
281*53ee8cc1Swenshuai.xi }
282*53ee8cc1Swenshuai.xi
283*53ee8cc1Swenshuai.xi return s32Retval;
284*53ee8cc1Swenshuai.xi }
285*53ee8cc1Swenshuai.xi
ms_usb_deregister(struct usb_driver * pUdriver)286*53ee8cc1Swenshuai.xi void ms_usb_deregister(struct usb_driver *pUdriver)
287*53ee8cc1Swenshuai.xi {
288*53ee8cc1Swenshuai.xi ms_usbhost_msg("deregistering driver %s\n", pUdriver->name);
289*53ee8cc1Swenshuai.xi ms_driver_unregister (&pUdriver->driver);
290*53ee8cc1Swenshuai.xi }
291*53ee8cc1Swenshuai.xi
ms_usb_ifnum_to_if(struct usb_device * pUdev,int ifnum)292*53ee8cc1Swenshuai.xi struct usb_interface *ms_usb_ifnum_to_if(struct usb_device *pUdev, int ifnum)
293*53ee8cc1Swenshuai.xi {
294*53ee8cc1Swenshuai.xi int i;
295*53ee8cc1Swenshuai.xi
296*53ee8cc1Swenshuai.xi for (i = 0; i < pUdev->actconfig->desc.bNumInterfaces; i++)
297*53ee8cc1Swenshuai.xi if (pUdev->actconfig->interface[i]->altsetting[0]
298*53ee8cc1Swenshuai.xi .desc.bInterfaceNumber == ifnum)
299*53ee8cc1Swenshuai.xi return pUdev->actconfig->interface[i];
300*53ee8cc1Swenshuai.xi
301*53ee8cc1Swenshuai.xi return NULL;
302*53ee8cc1Swenshuai.xi }
303*53ee8cc1Swenshuai.xi #if 0 // NUSED
304*53ee8cc1Swenshuai.xi BOOL ms_usb_find_dev_for_driver(struct device_driver *pDriver, struct usb_device **pudev, struct usb_hcd *hcd)
305*53ee8cc1Swenshuai.xi {
306*53ee8cc1Swenshuai.xi struct list_head *entry;
307*53ee8cc1Swenshuai.xi struct device_s *pDev;
308*53ee8cc1Swenshuai.xi
309*53ee8cc1Swenshuai.xi list_for_loop(entry, &pDriver->devices)
310*53ee8cc1Swenshuai.xi {
311*53ee8cc1Swenshuai.xi const struct list_head *_mptr = entry;
312*53ee8cc1Swenshuai.xi pDev = (struct device_s *) ( (char *)_mptr - (char *)offsetof(struct device_s, driver_list) );
313*53ee8cc1Swenshuai.xi
314*53ee8cc1Swenshuai.xi *pudev = (struct usb_device *) ((char *)pDev - (char *)offsetof( struct usb_device, dev));
315*53ee8cc1Swenshuai.xi if ((*pudev)->parent == NULL) // skip root hub, 2012.02.29
316*53ee8cc1Swenshuai.xi continue;
317*53ee8cc1Swenshuai.xi
318*53ee8cc1Swenshuai.xi if ((*pudev)->bus->hcpriv == hcd)
319*53ee8cc1Swenshuai.xi return TRUE;
320*53ee8cc1Swenshuai.xi }
321*53ee8cc1Swenshuai.xi diag_printf(" \n\nusb_find_dev_for_driver> NOT FOUND!!!\n\n");
322*53ee8cc1Swenshuai.xi return FALSE;
323*53ee8cc1Swenshuai.xi }
324*53ee8cc1Swenshuai.xi #endif
325*53ee8cc1Swenshuai.xi //NSTL_060406 Sony MSAC-US5 MS Reader
ms_usb_get_connected_dev_state(int * pdevstate,unsigned char * pDevClass,struct usb_device * pusbdev,BOOL * pIntfDrvMatched)326*53ee8cc1Swenshuai.xi BOOL ms_usb_get_connected_dev_state(int *pdevstate,
327*53ee8cc1Swenshuai.xi unsigned char *pDevClass, struct usb_device *pusbdev, BOOL *pIntfDrvMatched)
328*53ee8cc1Swenshuai.xi {
329*53ee8cc1Swenshuai.xi BOOL status = FALSE;
330*53ee8cc1Swenshuai.xi struct usb_interface *pusbintf = NULL;
331*53ee8cc1Swenshuai.xi *pIntfDrvMatched = FALSE;
332*53ee8cc1Swenshuai.xi
333*53ee8cc1Swenshuai.xi if (!pusbdev)
334*53ee8cc1Swenshuai.xi return status;
335*53ee8cc1Swenshuai.xi
336*53ee8cc1Swenshuai.xi status = TRUE;
337*53ee8cc1Swenshuai.xi *pdevstate = pusbdev->eState;
338*53ee8cc1Swenshuai.xi if (pusbdev->eState < USB_STATE_ADDRESS)
339*53ee8cc1Swenshuai.xi return status;
340*53ee8cc1Swenshuai.xi
341*53ee8cc1Swenshuai.xi if (pusbdev->descriptor.bDeviceClass)
342*53ee8cc1Swenshuai.xi {
343*53ee8cc1Swenshuai.xi *pDevClass = pusbdev->descriptor.bDeviceClass;
344*53ee8cc1Swenshuai.xi }
345*53ee8cc1Swenshuai.xi else if (pusbdev->actconfig && pusbdev->actconfig->desc.bNumInterfaces)
346*53ee8cc1Swenshuai.xi {
347*53ee8cc1Swenshuai.xi pusbintf = ms_usb_ifnum_to_if(pusbdev, 0);
348*53ee8cc1Swenshuai.xi
349*53ee8cc1Swenshuai.xi if(pusbintf)
350*53ee8cc1Swenshuai.xi {
351*53ee8cc1Swenshuai.xi *pDevClass = pusbintf->altsetting->desc.bInterfaceClass;
352*53ee8cc1Swenshuai.xi *pIntfDrvMatched = (pusbintf->driver != NULL) ? TRUE : FALSE;
353*53ee8cc1Swenshuai.xi }
354*53ee8cc1Swenshuai.xi }
355*53ee8cc1Swenshuai.xi
356*53ee8cc1Swenshuai.xi return status;
357*53ee8cc1Swenshuai.xi }
358*53ee8cc1Swenshuai.xi
ms_usb_device_match(struct device_s * pDev,struct device_driver * pDrv)359*53ee8cc1Swenshuai.xi static int ms_usb_device_match (struct device_s *pDev, struct device_driver *pDrv)
360*53ee8cc1Swenshuai.xi {
361*53ee8cc1Swenshuai.xi struct usb_interface *pUintf;
362*53ee8cc1Swenshuai.xi struct usb_driver *usb_drv;
363*53ee8cc1Swenshuai.xi const struct usb_device_id *pUdev_id;
364*53ee8cc1Swenshuai.xi
365*53ee8cc1Swenshuai.xi /* check for generic driver, which we don't match any device with */
366*53ee8cc1Swenshuai.xi if (pDrv == &ms_usb_generic_driver)
367*53ee8cc1Swenshuai.xi return 0;
368*53ee8cc1Swenshuai.xi
369*53ee8cc1Swenshuai.xi pUintf = get_usb_interface(pDev);
370*53ee8cc1Swenshuai.xi usb_drv = get_usb_driver(pDrv);
371*53ee8cc1Swenshuai.xi pUdev_id = usb_drv->match_id_table;
372*53ee8cc1Swenshuai.xi
373*53ee8cc1Swenshuai.xi pUdev_id = ms_usb_match_id (pUintf, usb_drv->match_id_table);
374*53ee8cc1Swenshuai.xi if (pUdev_id)
375*53ee8cc1Swenshuai.xi return 1; //found id
376*53ee8cc1Swenshuai.xi
377*53ee8cc1Swenshuai.xi return 0; //id not found
378*53ee8cc1Swenshuai.xi }
379*53ee8cc1Swenshuai.xi
ms_usb_release_dev(struct device_s * pDev)380*53ee8cc1Swenshuai.xi void ms_usb_release_dev(struct device_s *pDev)
381*53ee8cc1Swenshuai.xi {
382*53ee8cc1Swenshuai.xi struct usb_device *pUdev;
383*53ee8cc1Swenshuai.xi int retv;
384*53ee8cc1Swenshuai.xi
385*53ee8cc1Swenshuai.xi pUdev = ms_to_usb_device(pDev);
386*53ee8cc1Swenshuai.xi
387*53ee8cc1Swenshuai.xi //if (pUdev->bus && pUdev->bus->bus_ops && pUdev->bus->bus_ops->ms_deallo_hcd_dev)
388*53ee8cc1Swenshuai.xi // pUdev->bus->bus_ops->ms_deallo_hcd_dev(pUdev);
389*53ee8cc1Swenshuai.xi if ((retv = ms_hcd_free_dev(pUdev)) != ENOERR) {
390*53ee8cc1Swenshuai.xi ms_usbhost_err("free device error %d\n", retv);
391*53ee8cc1Swenshuai.xi }
392*53ee8cc1Swenshuai.xi ms_usb_destroy_config(pUdev);
393*53ee8cc1Swenshuai.xi kfree (pUdev);
394*53ee8cc1Swenshuai.xi }
395*53ee8cc1Swenshuai.xi
ms_usb_alloc_dev(struct usb_device * parent,struct usb_bus * bus)396*53ee8cc1Swenshuai.xi struct usb_device *ms_usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus)
397*53ee8cc1Swenshuai.xi {
398*53ee8cc1Swenshuai.xi struct usb_device *pUdev;
399*53ee8cc1Swenshuai.xi int retv;
400*53ee8cc1Swenshuai.xi
401*53ee8cc1Swenshuai.xi pUdev = (struct usb_device*) kmalloc(sizeof(*pUdev), GFP_KERNEL);
402*53ee8cc1Swenshuai.xi if (!pUdev)
403*53ee8cc1Swenshuai.xi return NULL;
404*53ee8cc1Swenshuai.xi
405*53ee8cc1Swenshuai.xi memset(pUdev, 0, sizeof(*pUdev));
406*53ee8cc1Swenshuai.xi
407*53ee8cc1Swenshuai.xi ms_device_initialize(&pUdev->dev);
408*53ee8cc1Swenshuai.xi pUdev->dev.release_func = ms_usb_release_dev;
409*53ee8cc1Swenshuai.xi /* the only way to escape from USB_STATE_NOTATTACHED */
410*53ee8cc1Swenshuai.xi pUdev->eState = USB_STATE_ATTACHED;
411*53ee8cc1Swenshuai.xi
412*53ee8cc1Swenshuai.xi if (!parent)
413*53ee8cc1Swenshuai.xi pUdev->devpath [0] = '0';
414*53ee8cc1Swenshuai.xi pUdev->bus = bus;
415*53ee8cc1Swenshuai.xi pUdev->parent = parent;
416*53ee8cc1Swenshuai.xi
417*53ee8cc1Swenshuai.xi //if (pUdev->bus->bus_ops->ms_alloc_hcd_dev)
418*53ee8cc1Swenshuai.xi // pUdev->bus->bus_ops->ms_alloc_hcd_dev(pUdev);
419*53ee8cc1Swenshuai.xi if ((retv = ms_hcd_alloc_dev(pUdev)) != ENOERR) {
420*53ee8cc1Swenshuai.xi ms_usbhost_err("alloc device error %d\n", retv);
421*53ee8cc1Swenshuai.xi }
422*53ee8cc1Swenshuai.xi
423*53ee8cc1Swenshuai.xi return pUdev;
424*53ee8cc1Swenshuai.xi }
425*53ee8cc1Swenshuai.xi
ms_usb_get_dev(struct usb_device * pUdev)426*53ee8cc1Swenshuai.xi struct usb_device *ms_usb_get_dev (struct usb_device *pUdev)
427*53ee8cc1Swenshuai.xi {
428*53ee8cc1Swenshuai.xi struct device_s *pDev_t;
429*53ee8cc1Swenshuai.xi
430*53ee8cc1Swenshuai.xi if (!pUdev)
431*53ee8cc1Swenshuai.xi return NULL;
432*53ee8cc1Swenshuai.xi
433*53ee8cc1Swenshuai.xi pDev_t = ms_get_device(&pUdev->dev);
434*53ee8cc1Swenshuai.xi if (pDev_t)
435*53ee8cc1Swenshuai.xi return ms_to_usb_device(pDev_t);
436*53ee8cc1Swenshuai.xi else
437*53ee8cc1Swenshuai.xi return NULL;
438*53ee8cc1Swenshuai.xi }
439*53ee8cc1Swenshuai.xi
ms_usb_put_dev(struct usb_device * pUdev)440*53ee8cc1Swenshuai.xi void ms_usb_put_dev(struct usb_device *pUdev)
441*53ee8cc1Swenshuai.xi {
442*53ee8cc1Swenshuai.xi if (pUdev)
443*53ee8cc1Swenshuai.xi {
444*53ee8cc1Swenshuai.xi if (osapi_atomic_dec_and_test(&((&pUdev->dev)->dev_refcnt)))
445*53ee8cc1Swenshuai.xi {
446*53ee8cc1Swenshuai.xi //release allocated buffer for saving device's configurations and device info
447*53ee8cc1Swenshuai.xi ms_device_unregister(&pUdev->dev);
448*53ee8cc1Swenshuai.xi }
449*53ee8cc1Swenshuai.xi }
450*53ee8cc1Swenshuai.xi }
451*53ee8cc1Swenshuai.xi
ms_usb_disconnect(struct usb_device ** pdev)452*53ee8cc1Swenshuai.xi void ms_usb_disconnect(struct usb_device **pdev)
453*53ee8cc1Swenshuai.xi {
454*53ee8cc1Swenshuai.xi struct usb_device *pUdev = *pdev;
455*53ee8cc1Swenshuai.xi //struct usb_bus *pUbus; // NUSED
456*53ee8cc1Swenshuai.xi int i, devnum = 0;
457*53ee8cc1Swenshuai.xi struct usb_hcd *pHcd = (struct usb_hcd*) pUdev->bus->hcpriv;
458*53ee8cc1Swenshuai.xi
459*53ee8cc1Swenshuai.xi if (!pUdev)
460*53ee8cc1Swenshuai.xi {
461*53ee8cc1Swenshuai.xi ms_usbhost_debug ("%s nodev\n", __FUNCTION__);
462*53ee8cc1Swenshuai.xi return;
463*53ee8cc1Swenshuai.xi }
464*53ee8cc1Swenshuai.xi //pUbus = pUdev->bus;
465*53ee8cc1Swenshuai.xi //if (!pUbus)
466*53ee8cc1Swenshuai.xi //{
467*53ee8cc1Swenshuai.xi // ms_usbhost_debug ("%s nobus\n", __FUNCTION__);
468*53ee8cc1Swenshuai.xi // return;
469*53ee8cc1Swenshuai.xi //}
470*53ee8cc1Swenshuai.xi
471*53ee8cc1Swenshuai.xi //*pdev = NULL; // moved
472*53ee8cc1Swenshuai.xi
473*53ee8cc1Swenshuai.xi //pUdev->eState = USB_STATE_NOTATTACHED;
474*53ee8cc1Swenshuai.xi ms_usb_set_device_state(pUdev, USB_STATE_NOTATTACHED); // patch from Linux 2.6.28
475*53ee8cc1Swenshuai.xi
476*53ee8cc1Swenshuai.xi ms_usbhost_msg ("USB disconnect, address %d\n", pUdev->u32DevNum);
477*53ee8cc1Swenshuai.xi if (pUdev->parent)
478*53ee8cc1Swenshuai.xi devnum = pUdev->parent->u32DevNum;
479*53ee8cc1Swenshuai.xi
480*53ee8cc1Swenshuai.xi /* If EHC halted while roothub dev disconnect, restart EHC by set
481*53ee8cc1Swenshuai.xi * its run bit. The periodic schedule urb reclaiming will reference
482*53ee8cc1Swenshuai.xi * the frame index, so we should not halt the EHC while disconnect.
483*53ee8cc1Swenshuai.xi */
484*53ee8cc1Swenshuai.xi if (devnum == 1)
485*53ee8cc1Swenshuai.xi {
486*53ee8cc1Swenshuai.xi /* Make sure the EHC is halted already */
487*53ee8cc1Swenshuai.xi ms_forceHcdRun(pHcd);
488*53ee8cc1Swenshuai.xi }
489*53ee8cc1Swenshuai.xi
490*53ee8cc1Swenshuai.xi /* Free up all the children before we remove this device */
491*53ee8cc1Swenshuai.xi for (i = 0; i < USB_MAXCHILDREN; i++)
492*53ee8cc1Swenshuai.xi {
493*53ee8cc1Swenshuai.xi struct usb_device **child = pUdev->children + i;
494*53ee8cc1Swenshuai.xi if (*child)
495*53ee8cc1Swenshuai.xi ms_usb_disconnect(child);
496*53ee8cc1Swenshuai.xi }
497*53ee8cc1Swenshuai.xi
498*53ee8cc1Swenshuai.xi /* the following code merged into ms_usb_disable_device()
499*53ee8cc1Swenshuai.xi * based on Linux USB driver
500*53ee8cc1Swenshuai.xi */
501*53ee8cc1Swenshuai.xi //ms_usbhost_debug("%s - unregistering interface %s\n", pUdev->dev.dev_name, pUdev->dev.bus_id);
502*53ee8cc1Swenshuai.xi //
503*53ee8cc1Swenshuai.xi //if (pUdev->actconfig)
504*53ee8cc1Swenshuai.xi //{
505*53ee8cc1Swenshuai.xi // for (i = 0; i < pUdev->actconfig->desc.bNumInterfaces; i++)
506*53ee8cc1Swenshuai.xi // {
507*53ee8cc1Swenshuai.xi // struct usb_interface *pUiface;
508*53ee8cc1Swenshuai.xi //
509*53ee8cc1Swenshuai.xi // /* remove this interface */
510*53ee8cc1Swenshuai.xi // pUiface = pUdev->actconfig->interface[i];
511*53ee8cc1Swenshuai.xi // ms_device_unregister(&pUiface->dev);
512*53ee8cc1Swenshuai.xi // }
513*53ee8cc1Swenshuai.xi //}
514*53ee8cc1Swenshuai.xi
515*53ee8cc1Swenshuai.xi /* deallocate hcd/hardware state ... and nuke all pending urbs */
516*53ee8cc1Swenshuai.xi ms_usb_disable_device(pUdev, 0);
517*53ee8cc1Swenshuai.xi /* synchronize unlinks, may this works only in SMP case */
518*53ee8cc1Swenshuai.xi osapi_spin_lock_irq(&hcd_urb_unlink_lock);
519*53ee8cc1Swenshuai.xi osapi_spin_unlock_irq(&hcd_urb_unlink_lock);
520*53ee8cc1Swenshuai.xi
521*53ee8cc1Swenshuai.xi /* patch code sequence by Linux */
522*53ee8cc1Swenshuai.xi ms_usbhost_debug("unregistering device\n");
523*53ee8cc1Swenshuai.xi ms_device_unregister(&pUdev->dev);
524*53ee8cc1Swenshuai.xi
525*53ee8cc1Swenshuai.xi /* Free the device number and remove the /proc/bus/usb entry */
526*53ee8cc1Swenshuai.xi if (pUdev->u32DevNum > 0)
527*53ee8cc1Swenshuai.xi {
528*53ee8cc1Swenshuai.xi //ms_clear_bit(pUdev->u32DevNum, pUdev->bus->devmap.usb_devicemap, unsigned long);
529*53ee8cc1Swenshuai.xi ms_devmap_clear_bit(pUdev->u32DevNum, pUdev->bus->devmap.usb_devicemap);
530*53ee8cc1Swenshuai.xi pUdev->u32DevNum = -1;
531*53ee8cc1Swenshuai.xi }
532*53ee8cc1Swenshuai.xi
533*53ee8cc1Swenshuai.xi osapi_spin_lock_irq(&device_state_lock);
534*53ee8cc1Swenshuai.xi *pdev = NULL;
535*53ee8cc1Swenshuai.xi osapi_spin_unlock_irq(&device_state_lock);
536*53ee8cc1Swenshuai.xi
537*53ee8cc1Swenshuai.xi #ifdef ENABLE_ROOTHUB_DISCONN_REINIT // new patch to release qh and recover async qh
538*53ee8cc1Swenshuai.xi if (devnum == 1) // root hub is always assigned address 1
539*53ee8cc1Swenshuai.xi {
540*53ee8cc1Swenshuai.xi ms_roothub_disconn_reinit(pHcd);
541*53ee8cc1Swenshuai.xi }
542*53ee8cc1Swenshuai.xi #endif
543*53ee8cc1Swenshuai.xi }
544*53ee8cc1Swenshuai.xi
ms_usb_choose_address(struct usb_device * pUdev)545*53ee8cc1Swenshuai.xi void ms_usb_choose_address(struct usb_device *pUdev)
546*53ee8cc1Swenshuai.xi {
547*53ee8cc1Swenshuai.xi int s32Devnum;
548*53ee8cc1Swenshuai.xi // TODO: FIXME needs locking for SMP!!
549*53ee8cc1Swenshuai.xi
550*53ee8cc1Swenshuai.xi s32Devnum = find_next_zero_bit(pUdev->bus->devmap.usb_devicemap, 128, pUdev->bus->devnum_next);
551*53ee8cc1Swenshuai.xi if (s32Devnum >= 128)
552*53ee8cc1Swenshuai.xi s32Devnum = find_next_zero_bit(pUdev->bus->devmap.usb_devicemap, 128, 1);
553*53ee8cc1Swenshuai.xi
554*53ee8cc1Swenshuai.xi pUdev->bus->devnum_next = ( s32Devnum >= 127 ? 1 : s32Devnum + 1);
555*53ee8cc1Swenshuai.xi
556*53ee8cc1Swenshuai.xi if (s32Devnum < 128)
557*53ee8cc1Swenshuai.xi {
558*53ee8cc1Swenshuai.xi //ms_set_bit(s32Devnum, pUdev->bus->devmap.usb_devicemap, unsigned long);
559*53ee8cc1Swenshuai.xi ms_devmap_set_bit(s32Devnum, pUdev->bus->devmap.usb_devicemap);
560*53ee8cc1Swenshuai.xi pUdev->u32DevNum = s32Devnum;
561*53ee8cc1Swenshuai.xi }
562*53ee8cc1Swenshuai.xi }
563*53ee8cc1Swenshuai.xi
ms_usb_set_address(struct usb_device * pUdev)564*53ee8cc1Swenshuai.xi int ms_usb_set_address(struct usb_device *pUdev)
565*53ee8cc1Swenshuai.xi {
566*53ee8cc1Swenshuai.xi int s32Retval;
567*53ee8cc1Swenshuai.xi
568*53ee8cc1Swenshuai.xi if (pUdev->u32DevNum == 0)
569*53ee8cc1Swenshuai.xi return -EINVAL;
570*53ee8cc1Swenshuai.xi if ((pUdev->eState != USB_STATE_DEFAULT) && (pUdev->eState != USB_STATE_ADDRESS))
571*53ee8cc1Swenshuai.xi return -EINVAL;
572*53ee8cc1Swenshuai.xi
573*53ee8cc1Swenshuai.xi s32Retval = ms_usb_control_cmd(pUdev, usb_snddefctrl(pUdev), USB_REQ_SET_ADDRESS,
574*53ee8cc1Swenshuai.xi 0, pUdev->u32DevNum, 0, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
575*53ee8cc1Swenshuai.xi
576*53ee8cc1Swenshuai.xi if (s32Retval == 0)
577*53ee8cc1Swenshuai.xi //pUdev->eState = USB_STATE_ADDRESS;
578*53ee8cc1Swenshuai.xi ms_usb_set_device_state(pUdev, USB_STATE_ADDRESS);
579*53ee8cc1Swenshuai.xi return s32Retval;
580*53ee8cc1Swenshuai.xi }
581*53ee8cc1Swenshuai.xi
582*53ee8cc1Swenshuai.xi #if USB_IF_EHSET_SUPPORT
583*53ee8cc1Swenshuai.xi extern int ms_usb_test_proc_vid(U16 vid, U16 pid);
584*53ee8cc1Swenshuai.xi extern void ms_usb_high_speed_test_proc(struct usb_device *udev, int flag);
585*53ee8cc1Swenshuai.xi #endif
586*53ee8cc1Swenshuai.xi #define NEW_DEVICE_RETRYS 2
587*53ee8cc1Swenshuai.xi #define SET_ADDRESS_RETRYS 2
588*53ee8cc1Swenshuai.xi
ms_usb_new_device(struct usb_device * pUdev,struct device_s * parent)589*53ee8cc1Swenshuai.xi int ms_usb_new_device(struct usb_device *pUdev, struct device_s *parent)
590*53ee8cc1Swenshuai.xi {
591*53ee8cc1Swenshuai.xi static U8 u8MaxPacketSize = 8;
592*53ee8cc1Swenshuai.xi int s32Err = -EINVAL;
593*53ee8cc1Swenshuai.xi int i;
594*53ee8cc1Swenshuai.xi int j;
595*53ee8cc1Swenshuai.xi
596*53ee8cc1Swenshuai.xi //diag_printf("usb_new_device\n");
597*53ee8cc1Swenshuai.xi
598*53ee8cc1Swenshuai.xi ms_usb_generic_driver.bus = &usb_bus_type;
599*53ee8cc1Swenshuai.xi pUdev->dev.parent = parent;
600*53ee8cc1Swenshuai.xi pUdev->dev.driver = &ms_usb_generic_driver;
601*53ee8cc1Swenshuai.xi pUdev->dev.bus_type = &usb_bus_type;
602*53ee8cc1Swenshuai.xi pUdev->dev.driver_data = &usb_generic_driver_data;
603*53ee8cc1Swenshuai.xi strcpy(pUdev->dev.dev_name,"usbdev");
604*53ee8cc1Swenshuai.xi
605*53ee8cc1Swenshuai.xi ms_usb_get_dev(pUdev);
606*53ee8cc1Swenshuai.xi
607*53ee8cc1Swenshuai.xi if (pUdev->dev.bus_id[0] == 0)
608*53ee8cc1Swenshuai.xi USB_sprintf(&pUdev->dev.bus_id[0], "%d-%s", (int)pUdev->bus->busnum, pUdev->devpath);
609*53ee8cc1Swenshuai.xi pUdev->dev.dma_mask = parent->dma_mask;
610*53ee8cc1Swenshuai.xi
611*53ee8cc1Swenshuai.xi switch (pUdev->eSpeed)
612*53ee8cc1Swenshuai.xi {
613*53ee8cc1Swenshuai.xi case USB_HIGH_SPEED:
614*53ee8cc1Swenshuai.xi i = 64;
615*53ee8cc1Swenshuai.xi break;
616*53ee8cc1Swenshuai.xi case USB_FULL_SPEED:
617*53ee8cc1Swenshuai.xi i = u8MaxPacketSize;
618*53ee8cc1Swenshuai.xi break;
619*53ee8cc1Swenshuai.xi case USB_LOW_SPEED:
620*53ee8cc1Swenshuai.xi i = 8;
621*53ee8cc1Swenshuai.xi break;
622*53ee8cc1Swenshuai.xi
623*53ee8cc1Swenshuai.xi default:
624*53ee8cc1Swenshuai.xi goto fail;
625*53ee8cc1Swenshuai.xi }
626*53ee8cc1Swenshuai.xi pUdev->pEpMaxPacketIn [0] = i;
627*53ee8cc1Swenshuai.xi pUdev->pEpMaxPacketOut[0] = i;
628*53ee8cc1Swenshuai.xi
629*53ee8cc1Swenshuai.xi
630*53ee8cc1Swenshuai.xi for (i = 0; i < NEW_DEVICE_RETRYS; ++i)
631*53ee8cc1Swenshuai.xi {
632*53ee8cc1Swenshuai.xi for (j = 0; j < SET_ADDRESS_RETRYS; ++j)
633*53ee8cc1Swenshuai.xi {
634*53ee8cc1Swenshuai.xi s32Err = ms_usb_set_address(pUdev);
635*53ee8cc1Swenshuai.xi if (s32Err >= 0)
636*53ee8cc1Swenshuai.xi break;
637*53ee8cc1Swenshuai.xi
638*53ee8cc1Swenshuai.xi diag_printf("Device state = %s, (i,j) = (%d, %d)\n",
639*53ee8cc1Swenshuai.xi pUdev->eState == 3 ? "default" :
640*53ee8cc1Swenshuai.xi pUdev->eState == 4 ? "address": "unknown", i, j);
641*53ee8cc1Swenshuai.xi //if (0) // unpatch from Linux
642*53ee8cc1Swenshuai.xi //{
643*53ee8cc1Swenshuai.xi // struct usb_hcd *hcd = pUdev->bus->hcpriv;
644*53ee8cc1Swenshuai.xi // if (hcd->isBadDevice)
645*53ee8cc1Swenshuai.xi // {
646*53ee8cc1Swenshuai.xi // diag_printf(" @ usb_new_device(): set address fail to set gIsBadDevice=1\n");
647*53ee8cc1Swenshuai.xi // break;
648*53ee8cc1Swenshuai.xi // }
649*53ee8cc1Swenshuai.xi //}
650*53ee8cc1Swenshuai.xi
651*53ee8cc1Swenshuai.xi wait_ms(200);
652*53ee8cc1Swenshuai.xi }
653*53ee8cc1Swenshuai.xi
654*53ee8cc1Swenshuai.xi if (s32Err < 0) {
655*53ee8cc1Swenshuai.xi ms_usbhost_err("device not accepting address %d, error %d\n", (int)pUdev->u32DevNum, s32Err);
656*53ee8cc1Swenshuai.xi goto fail;
657*53ee8cc1Swenshuai.xi }
658*53ee8cc1Swenshuai.xi
659*53ee8cc1Swenshuai.xi wait_ms(10); /* Let the SET_ADDRESS settle */
660*53ee8cc1Swenshuai.xi s32Err = ms_usb_get_descriptor(pUdev, USB_DT_DEVICE, 0, &pUdev->descriptor, 8);
661*53ee8cc1Swenshuai.xi if (s32Err >= 8 || s32Err == -ENODEV) //Received 8 byress?
662*53ee8cc1Swenshuai.xi break;
663*53ee8cc1Swenshuai.xi wait_ms(100);
664*53ee8cc1Swenshuai.xi }
665*53ee8cc1Swenshuai.xi
666*53ee8cc1Swenshuai.xi if (s32Err < 8)
667*53ee8cc1Swenshuai.xi {
668*53ee8cc1Swenshuai.xi ms_usbhost_err("device descriptor read/8, error %d\n", s32Err);
669*53ee8cc1Swenshuai.xi goto fail;
670*53ee8cc1Swenshuai.xi }
671*53ee8cc1Swenshuai.xi
672*53ee8cc1Swenshuai.xi if (pUdev->eSpeed == USB_FULL_SPEED)
673*53ee8cc1Swenshuai.xi {
674*53ee8cc1Swenshuai.xi pUdev->pEpMaxPacketIn [0] = pUdev->descriptor.bMaxPacketSize0;
675*53ee8cc1Swenshuai.xi pUdev->pEpMaxPacketOut[0] = pUdev->descriptor.bMaxPacketSize0;
676*53ee8cc1Swenshuai.xi u8MaxPacketSize = pUdev->descriptor.bMaxPacketSize0;
677*53ee8cc1Swenshuai.xi }
678*53ee8cc1Swenshuai.xi
679*53ee8cc1Swenshuai.xi s32Err = ms_usb_get_dev_descriptor(pUdev);
680*53ee8cc1Swenshuai.xi if (s32Err < (signed)sizeof(pUdev->descriptor))
681*53ee8cc1Swenshuai.xi {
682*53ee8cc1Swenshuai.xi ms_usbhost_err("device descriptor read/all, error %d\n", s32Err);
683*53ee8cc1Swenshuai.xi goto fail;
684*53ee8cc1Swenshuai.xi }
685*53ee8cc1Swenshuai.xi
686*53ee8cc1Swenshuai.xi // annouce the VID/PID to the world
687*53ee8cc1Swenshuai.xi if (pUdev->parent) // not root hub
688*53ee8cc1Swenshuai.xi diag_printf("usb new device VID = %4x, PID = %4x\n", pUdev->descriptor.idVendor, pUdev->descriptor.idProduct);
689*53ee8cc1Swenshuai.xi
690*53ee8cc1Swenshuai.xi #if USB_IF_EHSET_SUPPORT // embedded host electrical test procedure
691*53ee8cc1Swenshuai.xi if (pUdev->parent ) // not root hub
692*53ee8cc1Swenshuai.xi {
693*53ee8cc1Swenshuai.xi //dev->descriptor.idVendor = 0x1A0A; // test only, marked for fomal release
694*53ee8cc1Swenshuai.xi //dev->descriptor.idProduct = 0x0102;
695*53ee8cc1Swenshuai.xi //diag_printf("<usb_new_device> force VID = %x, PID = %x\n", pUdev->descriptor.idVendor, pUdev->descriptor.idProduct);
696*53ee8cc1Swenshuai.xi if (ms_usb_test_proc_vid(pUdev->descriptor.idVendor, pUdev->descriptor.idProduct) == 1)
697*53ee8cc1Swenshuai.xi ms_usb_high_speed_test_proc(pUdev, 1);
698*53ee8cc1Swenshuai.xi }
699*53ee8cc1Swenshuai.xi #endif
700*53ee8cc1Swenshuai.xi
701*53ee8cc1Swenshuai.xi s32Err = ms_usb_get_config(pUdev);
702*53ee8cc1Swenshuai.xi if (s32Err < 0)
703*53ee8cc1Swenshuai.xi {
704*53ee8cc1Swenshuai.xi ms_usbhost_err("unable to get device %d configuration (error=%d)\n",
705*53ee8cc1Swenshuai.xi (int)pUdev->u32DevNum, s32Err);
706*53ee8cc1Swenshuai.xi goto fail;
707*53ee8cc1Swenshuai.xi }
708*53ee8cc1Swenshuai.xi
709*53ee8cc1Swenshuai.xi if (pUdev->descriptor.bNumConfigurations != 1)
710*53ee8cc1Swenshuai.xi {
711*53ee8cc1Swenshuai.xi diag_printf("configuration #%d chosen from %d choices\n",
712*53ee8cc1Swenshuai.xi pUdev->config[0].desc.bConfigurationValue,
713*53ee8cc1Swenshuai.xi pUdev->descriptor.bNumConfigurations);
714*53ee8cc1Swenshuai.xi }
715*53ee8cc1Swenshuai.xi // Add string
716*53ee8cc1Swenshuai.xi if (pUdev->descriptor.iManufacturer)
717*53ee8cc1Swenshuai.xi {
718*53ee8cc1Swenshuai.xi int retv;
719*53ee8cc1Swenshuai.xi
720*53ee8cc1Swenshuai.xi retv = ms_usb_string(pUdev, pUdev->descriptor.iManufacturer, usb_manufacturer_string_buf, 64);
721*53ee8cc1Swenshuai.xi if (retv > 0)
722*53ee8cc1Swenshuai.xi pUdev->pManufacturerString = usb_manufacturer_string_buf;
723*53ee8cc1Swenshuai.xi else
724*53ee8cc1Swenshuai.xi pUdev->pManufacturerString = NULL;
725*53ee8cc1Swenshuai.xi }
726*53ee8cc1Swenshuai.xi else
727*53ee8cc1Swenshuai.xi pUdev->pManufacturerString = NULL;
728*53ee8cc1Swenshuai.xi if (pUdev->pManufacturerString)
729*53ee8cc1Swenshuai.xi ms_usbhost_msg("USB device manufacturer string (index %d) = %s\n", pUdev->descriptor.iManufacturer, pUdev->pManufacturerString);
730*53ee8cc1Swenshuai.xi if (pUdev->descriptor.iProduct)
731*53ee8cc1Swenshuai.xi {
732*53ee8cc1Swenshuai.xi int retv;
733*53ee8cc1Swenshuai.xi
734*53ee8cc1Swenshuai.xi retv = ms_usb_string(pUdev, pUdev->descriptor.iProduct, usb_product_string_buf, 64);
735*53ee8cc1Swenshuai.xi if (retv > 0)
736*53ee8cc1Swenshuai.xi pUdev->pProductString = usb_product_string_buf;
737*53ee8cc1Swenshuai.xi else
738*53ee8cc1Swenshuai.xi pUdev->pProductString = NULL;
739*53ee8cc1Swenshuai.xi }
740*53ee8cc1Swenshuai.xi else
741*53ee8cc1Swenshuai.xi pUdev->pProductString = NULL;
742*53ee8cc1Swenshuai.xi if (pUdev->pProductString)
743*53ee8cc1Swenshuai.xi ms_usbhost_msg("USB device product string (index %d) = %s\n", pUdev->descriptor.iProduct, pUdev->pProductString);
744*53ee8cc1Swenshuai.xi if (pUdev->descriptor.iSerialNumber)
745*53ee8cc1Swenshuai.xi {
746*53ee8cc1Swenshuai.xi int retv;
747*53ee8cc1Swenshuai.xi
748*53ee8cc1Swenshuai.xi retv = ms_usb_string(pUdev, pUdev->descriptor.iSerialNumber, usb_serialnumber_string_buf, 64);
749*53ee8cc1Swenshuai.xi if (retv > 0)
750*53ee8cc1Swenshuai.xi pUdev->pSerialNumberString = usb_serialnumber_string_buf;
751*53ee8cc1Swenshuai.xi else
752*53ee8cc1Swenshuai.xi pUdev->pSerialNumberString = NULL;
753*53ee8cc1Swenshuai.xi }
754*53ee8cc1Swenshuai.xi else
755*53ee8cc1Swenshuai.xi pUdev->pSerialNumberString = NULL;
756*53ee8cc1Swenshuai.xi if (pUdev->pSerialNumberString)
757*53ee8cc1Swenshuai.xi ms_usbhost_msg("USB device serial number string (index %d) = %s\n", pUdev->descriptor.iSerialNumber, pUdev->pSerialNumberString);
758*53ee8cc1Swenshuai.xi
759*53ee8cc1Swenshuai.xi //if(pUdev->descriptor.bDeviceClass == USB_CLASS_COMM)
760*53ee8cc1Swenshuai.xi // s32Err = ms_usb_set_config(pUdev, pUdev->config[1].desc.bConfigurationValue);
761*53ee8cc1Swenshuai.xi //else
762*53ee8cc1Swenshuai.xi s32Err = ms_usb_set_config(pUdev, pUdev->config[0].desc.bConfigurationValue);
763*53ee8cc1Swenshuai.xi
764*53ee8cc1Swenshuai.xi if (s32Err)
765*53ee8cc1Swenshuai.xi {
766*53ee8cc1Swenshuai.xi ms_usbhost_err("failed to set device %d default configuration (error=%d)\n",
767*53ee8cc1Swenshuai.xi (int)pUdev->u32DevNum, s32Err);
768*53ee8cc1Swenshuai.xi goto fail;
769*53ee8cc1Swenshuai.xi }
770*53ee8cc1Swenshuai.xi
771*53ee8cc1Swenshuai.xi #if USB_IF_EHSET_SUPPORT // embedded host electrical test procedure
772*53ee8cc1Swenshuai.xi if (pUdev->parent ) // not root hub
773*53ee8cc1Swenshuai.xi {
774*53ee8cc1Swenshuai.xi if (ms_usb_test_proc_vid(pUdev->descriptor.idVendor, pUdev->descriptor.idProduct) == 2)
775*53ee8cc1Swenshuai.xi ms_usb_high_speed_test_proc(pUdev, 2);
776*53ee8cc1Swenshuai.xi }
777*53ee8cc1Swenshuai.xi #endif
778*53ee8cc1Swenshuai.xi
779*53ee8cc1Swenshuai.xi s32Err = ms_device_add (&pUdev->dev);
780*53ee8cc1Swenshuai.xi if (s32Err)
781*53ee8cc1Swenshuai.xi goto fail;
782*53ee8cc1Swenshuai.xi
783*53ee8cc1Swenshuai.xi for (i = 0; i < pUdev->actconfig->desc.bNumInterfaces; i++)
784*53ee8cc1Swenshuai.xi {
785*53ee8cc1Swenshuai.xi struct usb_interface *iface = pUdev->actconfig->interface[i];
786*53ee8cc1Swenshuai.xi struct usb_interface_descriptor *i_desc;
787*53ee8cc1Swenshuai.xi
788*53ee8cc1Swenshuai.xi i_desc = &iface->altsetting [iface->act_altsetting].desc;
789*53ee8cc1Swenshuai.xi iface->dev.parent = &pUdev->dev;
790*53ee8cc1Swenshuai.xi iface->dev.driver = NULL;
791*53ee8cc1Swenshuai.xi iface->dev.bus_type = &usb_bus_type;
792*53ee8cc1Swenshuai.xi iface->dev.dma_mask = parent->dma_mask;
793*53ee8cc1Swenshuai.xi
794*53ee8cc1Swenshuai.xi strcpy(iface->dev.dev_name,"intf");
795*53ee8cc1Swenshuai.xi USB_sprintf(&iface->dev.bus_id[0], "%d-%s:%d",
796*53ee8cc1Swenshuai.xi (int)pUdev->bus->busnum, pUdev->devpath,
797*53ee8cc1Swenshuai.xi i_desc->bInterfaceNumber);
798*53ee8cc1Swenshuai.xi ms_usbhost_msg("%s %s - registering interface %s\n", pUdev->dev.dev_name, pUdev->dev.bus_id, iface->dev.bus_id);
799*53ee8cc1Swenshuai.xi ms_device_add (&iface->dev);
800*53ee8cc1Swenshuai.xi // Unsupport usb driverfs
801*53ee8cc1Swenshuai.xi }
802*53ee8cc1Swenshuai.xi return 0;
803*53ee8cc1Swenshuai.xi fail:
804*53ee8cc1Swenshuai.xi //pUdev->eState = USB_STATE_DEFAULT;
805*53ee8cc1Swenshuai.xi ms_usb_set_device_state(pUdev, USB_STATE_NOTATTACHED); // patch from Linux 3.1.10
806*53ee8cc1Swenshuai.xi //ms_clear_bit(pUdev->u32DevNum, pUdev->bus->devmap.usb_devicemap, unsigned long);
807*53ee8cc1Swenshuai.xi ms_devmap_clear_bit(pUdev->u32DevNum, pUdev->bus->devmap.usb_devicemap);
808*53ee8cc1Swenshuai.xi pUdev->u32DevNum = -1;
809*53ee8cc1Swenshuai.xi ms_usb_put_dev(pUdev);
810*53ee8cc1Swenshuai.xi return s32Err;
811*53ee8cc1Swenshuai.xi }
812*53ee8cc1Swenshuai.xi
ms_usb_buffer_alloc(struct usb_device * pUdev,size_t size,int mem_flags,dma_addr_t * dma)813*53ee8cc1Swenshuai.xi void *ms_usb_buffer_alloc (
814*53ee8cc1Swenshuai.xi struct usb_device *pUdev,
815*53ee8cc1Swenshuai.xi size_t size,
816*53ee8cc1Swenshuai.xi int mem_flags,
817*53ee8cc1Swenshuai.xi dma_addr_t *dma
818*53ee8cc1Swenshuai.xi )
819*53ee8cc1Swenshuai.xi {
820*53ee8cc1Swenshuai.xi if (!pUdev || !pUdev->bus /*|| !pUdev->bus->bus_ops || !pUdev->bus->bus_ops->ms_alloc_hcd_buffer*/)
821*53ee8cc1Swenshuai.xi return 0;
822*53ee8cc1Swenshuai.xi //return pUdev->bus->bus_ops->ms_alloc_hcd_buffer (pUdev->bus, size, mem_flags, dma);
823*53ee8cc1Swenshuai.xi return ms_hcd_buffer_alloc(pUdev->bus, size, mem_flags, dma);
824*53ee8cc1Swenshuai.xi }
825*53ee8cc1Swenshuai.xi
ms_usb_buffer_free(struct usb_device * pUdev,size_t size,void * addr,dma_addr_t dma)826*53ee8cc1Swenshuai.xi void ms_usb_buffer_free (
827*53ee8cc1Swenshuai.xi struct usb_device *pUdev,
828*53ee8cc1Swenshuai.xi size_t size,
829*53ee8cc1Swenshuai.xi void *addr,
830*53ee8cc1Swenshuai.xi dma_addr_t dma
831*53ee8cc1Swenshuai.xi )
832*53ee8cc1Swenshuai.xi {
833*53ee8cc1Swenshuai.xi if (!pUdev || !pUdev->bus /*|| !pUdev->bus->bus_ops || !pUdev->bus->bus_ops->ms_free_hcd_buffer*/)
834*53ee8cc1Swenshuai.xi return;
835*53ee8cc1Swenshuai.xi if (!addr)
836*53ee8cc1Swenshuai.xi return;
837*53ee8cc1Swenshuai.xi //pUdev->bus->bus_ops->ms_free_hcd_buffer (pUdev->bus, size, addr, dma);
838*53ee8cc1Swenshuai.xi ms_hcd_buffer_free(pUdev->bus, size, addr, dma);
839*53ee8cc1Swenshuai.xi }
840*53ee8cc1Swenshuai.xi
841*53ee8cc1Swenshuai.xi
842*53ee8cc1Swenshuai.xi struct ms_bus_type usb_bus_type = {
843*53ee8cc1Swenshuai.xi {&usb_bus_type.drivers_list,&usb_bus_type.drivers_list},
844*53ee8cc1Swenshuai.xi {&usb_bus_type.devices_list,&usb_bus_type.devices_list},
845*53ee8cc1Swenshuai.xi ms_usb_device_match,
846*53ee8cc1Swenshuai.xi };
847*53ee8cc1Swenshuai.xi
ms_usb_core_init(void)848*53ee8cc1Swenshuai.xi int ms_usb_core_init(void)
849*53ee8cc1Swenshuai.xi {
850*53ee8cc1Swenshuai.xi ms_usb_hub_init();
851*53ee8cc1Swenshuai.xi ms_driver_register(&ms_usb_generic_driver);
852*53ee8cc1Swenshuai.xi
853*53ee8cc1Swenshuai.xi return 0;
854*53ee8cc1Swenshuai.xi }
855*53ee8cc1Swenshuai.xi
ms_usb_core_uninit(void)856*53ee8cc1Swenshuai.xi int ms_usb_core_uninit(void)
857*53ee8cc1Swenshuai.xi {
858*53ee8cc1Swenshuai.xi ms_usb_hub_uninit();
859*53ee8cc1Swenshuai.xi ms_driver_unregister(&ms_usb_generic_driver);
860*53ee8cc1Swenshuai.xi
861*53ee8cc1Swenshuai.xi return 0;
862*53ee8cc1Swenshuai.xi }
863*53ee8cc1Swenshuai.xi
864