]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/devs/usb/imx/v2_0/src/usbs_imx.c
Initial revision
[karo-tx-redboot.git] / packages / devs / usb / imx / v2_0 / src / usbs_imx.c
1 //==========================================================================
2 //
3 //      usbs_imx.c
4 //
5 //      Device driver for the i.MX51 or i.MX37 USB OTG port.
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is a part of Diagnosis Package based on eCos for Freescale i.MX 
11 // Family microprocessor.
12 // Copyright (C) 2008 Freescale Semiconductor, Inc.
13 //
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
17 //
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21 // for more details.
22 //
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 //
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
33 //
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
36 //
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
43 //
44 // Author(s):    fisherz
45 // Contributors: fisherz
46 // Date:         2008-10-16
47 //
48 // This code implements support for the on-chip USB OTG port on the Freescale i.MX
49 // family of processors. The code has been developed on the i.MX and
50 // may or may not work on other members of the i.MX family. There
51 // have problems with the USB support on certain revisions of the silicon,
52 // so the errata sheet appropriate to the specific processor being used
53 // should be consulted. There also appear to be problems which do not
54 // appear on any errata, which this code attempts to work around.
55 //
56 // [Note] DMA is not enabled for USB transfer
57 //####DESCRIPTIONEND####
58 //
59 //####REVISION HISTORY####
60 //      Date                    Author                          Comments
61 //  22Jul08                     Fisher ZHU(b18985)      Created for i.MX37 eCos USB device driver
62 //  16Oct08                     Fisher ZHU(b18985)  Ported to i.MX51 USB OTG core
63 //==========================================================================
64 #include <string.h>     //use memset() of C run-time library
65 #include <cyg/infra/cyg_type.h>
66 #include <cyg/infra/cyg_ass.h>
67 #include <cyg/infra/cyg_trac.h>
68 #include <cyg/infra/diag.h>
69 #include <pkgconf/hal_arm.h>
70 #include <pkgconf/devs_usb_imx_otg.h>
71 #include <cyg/hal/drv_api.h>
72 #include <cyg/hal/hal_arch.h>
73 #include <cyg/hal/hal_io.h>
74 #include <cyg/hal/hal_cache.h>
75 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
76 #include <cyg/error/codes.h>
77 #endif
78 #include <cyg/io/usb/usb.h>
79 #include <cyg/io/usb/usbs.h>
80 #include <cyg/io/usb/usbs_imx.h>
81
82 #pragma O0      //this pragma is useful when Realview tool chain is used
83 #define VOLATILE volatile
84
85 #if defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
86 //this error code is defined in error/include/codes.h
87 //but when the usb driver is used in redboot, the codes.h won't
88 //be included, so that this definition will solve the problem
89 #define EPIPE 304       
90
91 /* Constants */
92 #define SDP_CMD_MAX_LEN 0x10  /* 16 bytes */
93 #define SDP_CMD_ACK_LEN 0x4   /*  4 bytes */
94 /* Command Packet Format: Header(2)+Address(4)+Format(1)+ByteCount(4)+Data(4) */
95 #define READ_HEADER             0x0101  //Read the flag in an assigned address on the target board
96 #define WRITE_HEADER    0x0202
97 #define WRITE_FILE              0x0404  //Write a file in host PC to target board
98 #define READ_FILE               0x0A0A  //Read a block of RAM to host PC and save in a file
99 #define ERROR_STATUS_HEADER     0x0505
100
101 /* SDP Responses */
102 #define WRITE_COMPLETE  0x128A8A12
103
104 /* SDP States */
105 #define CONTINUE        0
106 #define DONE            1
107 #define COMPLETE        0x88
108
109 #define USB_DOWNLOAD_TIMEOUT_LIMIT      0x1D000000
110 cyg_uint32 usb_download_address;
111 cyg_uint32 usb_download_length;
112 static cyg_uint8 sdp_payload_data[SDP_CMD_MAX_LEN]; /* Used to send or receive Command/ACK */
113 static cyg_uint8 sdp_command[SDP_CMD_MAX_LEN];      /* Used to store Command */
114 static cyg_uint8 g_error_status;
115 static cyg_uint8 g_usb_download_state = CONTINUE;
116 static cyg_uint32 g_timeout_value = 0;
117 static cyg_uint32 g_load_cycle;
118 static cyg_bool pl_get_command(void);
119 static cyg_uint8 pl_command_start(void);
120 static cyg_uint8 pl_handle_command(cyg_uint8 g_error_status);
121 static void pl_command_ack(cyg_uint32 ack);
122 static void pl_handle_write_file(cyg_uint32 address, cyg_uint32 total_bytes);
123 static cyg_uint32 usb_rx_processing(cyg_uint8* read_ptr, usb_status_t* status, cyg_uint32 data_length);
124 static usb_status_t usb_tx_processing(cyg_uint8* write_ptr, cyg_uint32 data_len);
125 #endif
126
127 /*      Bit3 - Mass Storage Information
128         Bit2 - Enumeration Information
129         Bit1 - Transaction Information
130         Bit0 - Basic Information        
131 */
132 //#define DEBUG_TRANS   0x8     //also defined in usbs_msc.c
133 #define DEBUG_ENUM      0x4
134 #define DEBUG_TRANS     0x2
135 #define DEBUG_BASIC     0x1
136
137 //#define USBDBGMSG(str) if(g_debug_switch&0x1) diag_printf(str)
138 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
139 extern cyg_uint32 g_debug_switch; //the lowest 4-bit is used for USB debug
140 #if 1
141 #define USBDBGMSG(opt,fmt,args...) if(g_debug_switch&opt) diag_printf(fmt, ## args)
142 #else
143 #define USBDBGMSG(opt,fmt,args...)
144 #endif
145
146 #else
147 #define USBDBGMSG(opt,fmt,args...) //diag_printf(fmt, ## args)
148 #define D(fmt,args...) diag_printf(fmt, ## args)
149 #endif
150
151 // ----------------------------------------------------------------------------
152 //volatile cyg_uint8 g_bulkbuffer[BULK_TD_BUFFER_TOTAL_SIZE*NUM_OF_BULK_BUFFER] __attribute__((aligned(0x1000)));
153 bulk_buffer_t g_bulkbuffer_a;
154 bulk_buffer_t g_bulkbuffer_b;
155
156 //This variable is used to workaround the 31-byte packet issue in i.MX37
157 //It is initialized as "0x1",
158 //When data read/write, it must initialize as '0x0'
159 cyg_uint32 g_td_buffer_offset = 0;      
160
161 //The below two flags is used to distinguish the received data is data or command
162 cyg_uint32 g_received_data_type;
163
164 /* This is used to pause the EP2 In wait for complete, just a workaround for this issue
165    It is not sure to be a bug of IC or software, need to check later.
166 */
167 //cyg_uint8 g_tx_done=1;        //to keep EP1 issue sempahore to scsi after the previous CBW processed
168 cyg_uint8 g_ep2_complete_bit_set = 0;
169
170 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
171 extern cyg_sem_t usbs_msc_sem;                          //semaphore to schedule mass storage command handling thread
172 #endif
173
174 // ----------------------------------------------------------------------------
175 // Static pointers for USB buffer layout
176 /*=============================================================================
177                                       STATIC VARIABLES
178 //============================================================================*/
179
180 // Allocate 2k-byte buffer as USB QueueHeaderList region.
181 // Don't use #pragma arm section in GCC
182 // !!!!USB buffer should not be cached and buffered.
183 //#pragma arm section rwdata="usb_buffer_no_init", zidata="usb_buffer_no_init"
184 //2k aligned, this buffer must be uncacheable and unbufferable.
185
186 #if defined(CYGHWR_IMX_USB_BUFFER_USE_IRAM)
187 static volatile cyg_uint8 usb_buffer[BUFFER_SIZE] __attribute__((aligned(0x800)));      
188 static volatile cyg_uint8 bulk_buffer[BULK_TD_BUFFER_TOTAL_SIZE*NUM_OF_BULK_BUFFER] __attribute__((aligned(0x1000)));
189 //#pragma arm section
190 #else
191 /* iRAM is configured as uncacheable and unbufferable in MMU initialization
192     Reserve 0x800 bytes as USB buffer
193     Don't use 0x10001000~0x10001800 for other program. */
194 #if defined(CYGHWR_USB_DEVS_MX37_OTG)
195 static volatile cyg_uint8 * usb_buffer=(cyg_uint8 *)(0x10001000); 
196 static volatile cyg_uint8 * bulk_buffer = (cyg_uint8 *)(0x10002000);
197 #endif
198
199 #if defined(CYGHWR_USB_DEVS_MX51_OTG)
200 static volatile cyg_uint8 * usb_buffer=(cyg_uint8 *)(0x1FFE9000); 
201 static volatile cyg_uint8 * bulk_buffer = (cyg_uint8 *)(0x1FFEA000);
202 #endif
203 // 
204 #endif  //defined(CYGHWR_IMX_USB_BUFFER_USE_IRAM)
205
206 VOLATILE usbs_imx_otg_hardware* usbs_imx_otg_base = (VOLATILE usbs_imx_otg_hardware* const) USB_BASE_ADDRESS;
207
208 static void usbs_imx_otg_config_utmi_clock(void);
209
210
211 /* Base address of the buffer allocated to IP Layer */
212 static VOLATILE cyg_uint32              g_bulkbuffer_address_base;
213 /* length of the buffer */
214 static VOLATILE cyg_uint32              g_bulkbuffer_length;    
215 /* Buffer information used for data transfer */
216 static VOLATILE buffer_map_t            g_bulkbuffer_map;               
217 /* Number of Endpoints configured in system */
218 static VOLATILE cyg_uint8               g_max_ep_supported;   
219 /* State os USB Device */
220 static VOLATILE usb_state_t             g_usb_dev_state = USB_DEV_DUMMY_STATE; 
221 /* Length of setup data received */
222 static VOLATILE cyg_uint8 *             g_usb_setup_data;
223 /* Array to keep information about the endpoints used */
224 static VOLATILE usb_end_pt_info_t       g_end_pt_info[USB_DEV_INF_DESC_NUM_OF_EP]; 
225 /* Number of endpoints */
226 static VOLATILE cyg_uint8               g_number_of_endpoints; 
227 /* USB Descriptors */
228 static VOLATILE usb_descriptor  g_usb_desc;             
229 /* Number of Endpoint configured as IN */
230 static VOLATILE cyg_uint8               g_in_endpoint;  
231 /* Number of Endpoint configured as OUT*/
232 static VOLATILE cyg_uint8               g_out_endpoint;         
233
234 /* Support for the interrupt handling code.*/
235 static cyg_interrupt    g_usbs_dev_intr_data;
236 static cyg_handle_t             g_usbs_dev_intr_handle;
237 static volatile int             g_isr_status_bits = 0;
238
239 // ----------------------------------------------------------------------------
240 // get the base address of queue header for an endpointer
241 #define USBS_EP_GET_dQH(endptno,dir) (g_bulkbuffer_map.ep_dqh_base_addrs + (SIZE_OF_QHD * (endptno * 2 + dir)))
242 #define USBS_EP_GET_dTD(endptno,dir)    (g_bulkbuffer_map.ep_dtd_base_addrs + (SIZE_OF_DTD0 + SIZE_OF_DTD1) * ( endptno * 2 + dir))
243 // ----------------------------------------------------------------------------
244 // USB interrupt enable/disable macros
245 #define USBS_IMX_OTG_INTR_MASK()                (usbs_imx_otg_base->usbintrclr = 0xFFFFFFFF)//0|IMX_USB_INTR_DEV_RESET|IMX_USB_INTR_DEV_USBINT)
246 #define USBS_IMX_OTG_INTR_UNMASK(intr)  (usbs_imx_otg_base->usbintr = 0|(intr))
247
248 // ----------------------------------------------------------------------------
249 // Check if the IOS bit of QueueHeader or the IOC bit of Transfer Descriptor are set
250 #define USBS_dQH_IOS_CHECK(ep_num,dir) (((*(cyg_uint32*)USBS_EP_GET_dQH(ep_num,dir))&0x8000)?1:0)
251 #define USBS_dTD_IOC_CHECK(ep_num,dir) (((*(cyg_uint32*)USBS_EP_GET_dTD(ep_num,dir))&0x8000)?1:0)
252
253 // ----------------------------------------------------------------------------
254 // Set USB device address
255 #define USBS_DEVICE_SET_ADDRESS(addr) (usbs_imx_otg_base->devaddr = ((cyg_uint32)addr & 0x7F) << 25)
256 /*  
257 #*************  
258 #   OTG  
259 #*************  
260 */
261 #define  USB_OTG_ID                                     (&(usbs_imx_otg_base->id))                                      /*   Identification Register                                    */
262 #define  USB_OTG_HWGENERAL                      (&(usbs_imx_otg_base->hwgeneral))       /*   General Hardware Parameters                        */
263 #define  USB_OTG_HWHOST                         (&(usbs_imx_otg_base->hwhost))                  /*   Host Hardware Parameters                           */
264 #define  USB_OTG_HWDEVICE                       (&(usbs_imx_otg_base->hwdevice))                /*   Device Hardware Parameters                         */
265 #define  USB_OTG_HWTXBUF                        (&(usbs_imx_otg_base->hwtxbuf))         /*   TX Buffer Hardware Parameters              */
266 #define  USB_OTG_HWRXBUF                        (&(usbs_imx_otg_base->hwrxbuf))         /*   RX Buffer Hardware Parameters              */
267
268 #define  USB_OTG_CAPLENGTH                      (&(usbs_imx_otg_base->caplength))       /*   Capability Register Length                         */
269 #define  USB_OTG_HCIVERSION                     (&(usbs_imx_otg_base->hciversion)) /*   Host Interface Version Number           */
270 #define  USB_OTG_HCSPARAMS                      (&(usbs_imx_otg_base->hcsparams))       /*   Host Ctrl. Structural Parameters */
271 #define  USB_OTG_HCCPARAMS                      (&(usbs_imx_otg_base->hccparams))  /*   Host Ctrl. Capability Parameters */
272 #define  USB_OTG_DCIVERSION                     (&(usbs_imx_otg_base->dciversion)) /*   Dev. Interface Version Number           */
273 #define  USB_OTG_DCCPARAMS                      (&(usbs_imx_otg_base->dccparams))       /*   Dev. Ctrl. Capability Parameters */
274
275 #define  USB_OTG_USBCMD                         (&(usbs_imx_otg_base->usbcmd))                  /*   USB Command                                                                                        */
276 #define  USB_OTG_USBSTS                         (&(usbs_imx_otg_base->usbsts))                  /*   USB Status                                                                                         */
277 #define  USB_OTG_USBINTR                        (&(usbs_imx_otg_base->usbintr))         /*   USB Interrupt Enable                                               */
278 #define  USB_OTG_FRINDEX                        (&(usbs_imx_otg_base->frindex))         /*   USB Frame Index                                                                    */
279
280 #define  USB_OTG_DEVICEADDR                     (&(usbs_imx_otg_base->devaddr))         /*   USB Device Address                                                         */
281 #define  USB_OTG_PERIODICLISTBASE       USB_OTG_DEVICEADDR                                              /*   Frame List Base Address                                    */
282 #define  USB_OTG_ENDPOINTLISTADDR       (&(usbs_imx_otg_base->endptlistaddr)) /*Address of Endpt list in memory*/
283 #define  USB_OTG_ASYNCLISTADDR          USB_OTG_ENDPOINTLISTADDR                                /*   Next Asynchronous List Address     */
284
285 #define  USB_OTG_BURSTSIZE                      (&(usbs_imx_otg_base->burstsize))  /*   Programmable Burst Size                                         */
286 #define  USB_OTG_TXFILLTUNING           (&(usbs_imx_otg_base->txfilltuning)) /* Host TX Pre-Buffer Packet Tuning */
287 #define  USB_OTG_VIEWPORT                       (&(usbs_imx_otg_base->ulpiviewport)) /* ULPI Register                                                                           */
288 #define  USB_OTG_ENDPTNAK                       (&(usbs_imx_otg_base->endptnak))        /*Endpoint NAK                                                                                          */
289 #define  USB_OTG_ENDPTNAKEN                     (&(usbs_imx_otg_base->endptnaken)) /*Endpoint NAK Enable                                                                */
290 #define  USB_OTG_CONFIGFLAG                     (&(usbs_imx_otg_base->configflg))       /*   Configured Flag Register                           */
291 #define  USB_OTG_PORTSC1                        (&(usbs_imx_otg_base->portsc1))  /*   Port 0 Status/Control                                     */
292 #define  USB_OTG_OTGSC                          (&(usbs_imx_otg_base->otgsc))           /*   OTG Status and Control                                             */  
293 #define  USB_OTG_USBMODE                        (&(usbs_imx_otg_base->usbmode))         /*   USB Device Mode                                                                    */
294 #define  USB_OTG_ENDPTSETUPSTAT         (&(usbs_imx_otg_base->endptsetupstat)) /*   Endpoint Setup Status                               */
295 #define  USB_OTG_ENDPTPRIME                     (&(usbs_imx_otg_base->endptprime)) /*   Endpoint Initialization                                         */
296 #define  USB_OTG_ENDPTFLUSH                     (&(usbs_imx_otg_base->endptflush)) /*   Endpoint De-Initialize                                  */
297 #define  USB_OTG_ENDPTSTATUS            (&(usbs_imx_otg_base->endptstatus))/*   Endpoint Status                                                                         */
298 #define  USB_OTG_ENDPTCOMPLETE          (&(usbs_imx_otg_base->endptcomplete))   /*   Endpoint Complete                                          */
299 #define  USB_OTG_ENDPTCTRL0             (&(usbs_imx_otg_base->endptctrl[0]))            /*   Endpoint Control 0                                         */
300 #define  USB_OTG_ENDPTCTRL1                     (&(usbs_imx_otg_base->endptctrl[1]))            /*   Endpoint Control 1                                         */
301 #define  USB_OTG_ENDPTCTRL2                     (&(usbs_imx_otg_base->endptctrl[2]))            /*   Endpoint Control 2                                         */
302 #define  USB_OTG_ENDPTCTRL3                     (&(usbs_imx_otg_base->endptctrl[3]))            /*   Endpoint Control 3                                         */
303 #define  USB_OTG_ENDPTCTRL4                     (&(usbs_imx_otg_base->endptctrl[4]))            /*   Endpoint Control 4                                         */
304 #define  USB_OTG_ENDPTCTRL5                     (&(usbs_imx_otg_base->endptctrl[5]))            /*   Endpoint Control 5                                         */
305 #define  USB_OTG_ENDPTCTRL6                     (&(usbs_imx_otg_base->endptctrl[6]))            /*   Endpoint Control 6                                         */
306 #define  USB_OTG_ENDPTCTRL7                     (&(usbs_imx_otg_base->endptctrl[7]))            /*   Endpoint Control 7                                         */
307 // ****************************************************************************
308 // -----------------------USB Device Descriptors-------------------------------
309 // ****************************************************************************
310 /* USB Device Descriptor according to USB2.0 Specification */
311 static VOLATILE usb_device_descriptor g_usb_device_desc ={
312         USB_DEV_DESC_LEN,
313     USB_DEV_DESC_TYPE,             
314     USB_DEV_DESC_SPEC_LB,              
315     USB_DEV_DESC_SPEC_HB,        
316     USB_DEV_DESC_DEV_CLASS,          
317     USB_DEV_DESC_DEV_SUBCLASS,        
318     USB_DEV_DESC_DEV_PROTOCOL,         
319     USB_DEV_DESC_EP0_MAXPACKETSIZE,     
320     USB_DEV_DESC_VENDORID_LB,               
321     USB_DEV_DESC_VENDORID_HB,               
322     USB_DEV_DESC_PRODUCTID_LB,               
323     USB_DEV_DESC_PRODUCTID_HB,               
324     USB_DEV_DESC_DEV_RELEASE_NUM_LB,          
325     USB_DEV_DESC_DEV_RELEASE_NUM_HB,         
326     USB_DEV_DESC_DEV_STRING_IND_MANUFACTURE,
327     USB_DEV_DESC_DEV_STRING_IND_PRODUCT,  
328     USB_DEV_DESC_DEV_STRING_IND_SERIAL_NUM,
329     USB_DEV_DESC_DEV_NUM_CONFIGURATIONS
330 };
331
332
333 /* USB Config Descriptor according to USB2.0 Specification */
334 static VOLATILE usb_conf_desc g_usb_config_desc = {
335         { 
336         USB_DEV_CONFIG_DESC_LEN,   
337     USB_DEV_CONFIG_DESC_TYPE,   
338     USB_DEV_CONFIG_DESC_TTL_LEN_LB ,   
339     USB_DEV_CONFIG_DESC_TTL_LEN_HB ,   
340     USB_DEV_CONFIG_DESC_NUM_0F_INF,  
341     USB_DEV_CONFIG_DESC_CONFIG_VALUE ,  
342     USB_DEV_CONFIG_DESC_STRING_INDEX, 
343     USB_DEV_CONFIG_DESC_ATTRIBUTES,    
344         USB_DEV_CONFIG_DESC_MAX_POWER
345         },
346                 /* USB Interface Descriptor according to USB2.0 Specification */
347         {//09
348         USB_DEV_INF_DESC_LEN,  
349     USB_DEV_INF_DESC_TYPE,  
350     USB_DEV_INF_DESC_INF_INDEX, 
351     USB_DEV_INF_DESC_ALT_SETTING,
352     USB_DEV_INF_DESC_NUM_OF_EP,  /* NOTE : This should not be more than 2 */
353     #if defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
354         USB_DEV_INF_DESC_INF_CLASS_VENDOR,
355         USB_DEV_INF_DESC_INF_SUBCLASS_NS_BLANK,
356         USB_DEV_INF_DESC_INF_PROTOCOL,
357         #else
358         USB_DEV_INF_DESC_INF_CLASS_MSC, 
359     USB_DEV_INF_DESC_INF_SUBCLASS_MSC_SCSI,   
360     USB_DEV_INF_DESC_INF_PROTOCOL_MSC_BOT, 
361     #endif
362         USB_DEV_INF_DESC_STRING_INDEX
363         },
364                 /* USB Endpoint 1 Descriptors according to USB2.0 Specification, OUT */
365         {
366         {//18
367         USB_EP1_DESC_SIZE,
368     USB_EP1_DESC_TYPE,
369     USB_EP1_DESC_EP_ADDR,
370     USB_EP1_DESC_ATTRIBUTES, 
371     USB_EP1_DESC_MAX_PACKET_SIZE_HS_LB, 
372     USB_EP1_DESC_MAX_PACKET_SIZE_HS_HB, 
373         USB_EP1_DESC_INTERVAL
374         },
375                 /* USB Endpoint 2 Descriptors according to USB2.0 Specification, IN */
376         {//25
377         USB_EP2_DESC_SIZE, 
378     USB_EP2_DESC_TYPE,
379     USB_EP2_DESC_EP_ADDR,    
380     USB_EP2_DESC_ATTRIBUTES,  
381     USB_EP2_DESC_MAX_PACKET_SIZE_HS_LB,  
382     USB_EP2_DESC_MAX_PACKET_SIZE_HS_HB,  
383         USB_EP2_DESC_INTERVAL
384         }
385         }
386 };
387
388 /* USB String Descriptors 0, according to USB2.0 Specification */
389 static VOLATILE usb_str0_desc g_usb_otg_str0_desc ={
390     USB_STR0_DESC_SIZE,
391     USB_STR0_DESC_TYPE,
392     USB_LANGUAGE_ID_LB,
393     USB_LANGUAGE_ID_HB
394 };
395
396 /* 
397  STRING DESCRIPTOR
398  See table 9-15 in USB2.0 spec (www.usb.org)
399  iManufacturer
400 */
401 static VOLATILE usb_str1_desc g_usb_otg_string_desc1 ={
402         USB_STR1_DESC_SIZE,             /* bLength */
403         USB_STR1_DESC_TYPE,                     /* bDescriptorType */
404         {
405         'F', 0x00,                                                      /* bString */
406         'r', 0x00,
407         'e', 0x00,
408         'e', 0x00,
409         's', 0x00,
410         'c', 0x00,
411         'a', 0x00,
412         'l', 0x00,
413         'e', 0x00,
414         ' ', 0x00,
415         'S', 0x00,
416         'e', 0x00,
417         'm', 0x00,
418         'i', 0x00,
419         'C', 0x00,
420         'o', 0x00,
421         'n', 0x00,
422         'd', 0x00,
423         'u', 0x00,
424         'c', 0x00,
425         't', 0x00,
426         'o', 0x00,
427         'r', 0x00,
428         ' ', 0x00,
429         'I', 0x00,
430         'n', 0x00,
431         'c', 0x00,
432         '.', 0x00
433         }
434 };
435 #if defined(CYGHWR_USB_DEVS_MX37_OTG)
436 /*iProduct*/     
437 static VOLATILE usb_str2_desc g_usb_otg_string_desc2 = {
438         USB_STR2_DESC_SIZE_NS,          /* bLength */
439         USB_STR2_DESC_TYPE,                                             /* bDescriptorType */
440         {
441         'M', 0x00,                              /* bString */
442         'A', 0x00,              
443         'R', 0x00,                      
444         'L', 0x00,
445         'E', 0x00,      
446         'Y', 0x00,              
447         ' ', 0x00,      
448         'U', 0x00,              
449         'S', 0x00,                      
450         'B', 0x00,
451         ' ', 0x00,
452         'O', 0x00,
453         'T', 0x00,
454         'G', 0x00,
455         ' ', 0x00
456         }
457 };
458 //#if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
459 /* USB Serial Number Descriptor which is mandatory to Mass Storage Device */
460 static VOLATILE usb_str4_desc g_usb_serialnumber_desc = {
461                 USB_SN_DESC_LEN,
462                 USB_SN_DESC_TYPE,
463                 {
464                 '2',0x00,
465                 '0',0x00,
466                 '0',0x00,
467                 '8',0x00,
468                 '1',0x00,
469                 '8',0x00,
470                 '9',0x00,
471                 '8',0x00,
472                 '5',0x00,
473                 '0',0x00,
474                 '3',0x00,
475                 '7',0x00
476           }
477 };
478 //#endif
479 #endif
480
481 #if defined(CYGHWR_USB_DEVS_MX51_OTG)
482 static VOLATILE usb_str2_desc g_usb_otg_string_desc2 = {
483         USB_STR2_DESC_SIZE_NS,          /* bLength */
484         USB_STR2_DESC_TYPE,                                             /* bDescriptorType */
485         {
486         'E', 0x00,                              /* bString */
487         'l', 0x00,              
488         'v', 0x00,                      
489         'i', 0x00,
490         's', 0x00,      
491         ' ', 0x00,              
492         'U', 0x00,      
493         'S', 0x00,              
494         'B', 0x00,                      
495         ' ', 0x00,
496         'O', 0x00,
497         'T', 0x00,
498         'T', 0x00,
499         ' ', 0x00,
500         ' ', 0x00
501         }
502 };
503 //#if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
504 /* USB Serial Number Descriptor which is mandatory to Mass Storage Device */
505 static VOLATILE usb_str4_desc g_usb_serialnumber_desc = {
506                 USB_SN_DESC_LEN,
507                 USB_SN_DESC_TYPE,
508                 {
509                 '2',0x00,
510                 '0',0x00,
511                 '0',0x00,
512                 '8',0x00,
513                 '1',0x00,
514                 '8',0x00,
515                 '9',0x00,
516                 '8',0x00,
517                 '5',0x00,
518                 '0',0x00,
519                 '5',0x00,
520                 '1',0x00
521           }
522 };
523 //#endif
524 #endif
525
526 /* STRING DESCRIPTOR
527    See table 9-15 in USB2.0 spec (www.usb.org)
528    iSerialNumber */
529 static VOLATILE usb_str3_desc g_usb_otg_string_desc3 = {
530         USB_STR3_DESC_SIZE,                                     /* bLength */
531         USB_STR3_DESC_TYPE,                                     /* bDescriptorType */
532         {
533         'F', 0x00,                                                                      /* bString */
534         'r', 0x00,
535         'e', 0x00,
536         'e', 0x00,
537         's', 0x00,
538         'c', 0x00,
539         'a', 0x00,
540         'l', 0x00,
541         'e', 0x00,
542         ' ', 0x00,
543         'F', 0x00,
544         'l', 0x00,
545         'a', 0x00,
546         's', 0x00,
547         'h', 0x00
548         }
549 };       
550
551
552 // ****************************************************************************
553 // ----------------------------------------------------------------------------
554 // ****************************************************************************
555 // ----------------------------------------------------------------------------
556 // Static data. There is a data structure for each endpoint. The
557 // implementation is essentially a private class that inherits from
558 // common classes for control and data endpoints, but device drivers
559 // are supposed to be written in C so some ugliness is required.
560
561 // ----------------------------------------------------------------------------
562 // Endpoint 0 is always present, this module would not get compiled
563 // otherwise.
564 static void usbs_imx_otg_dev_ep0_start(usbs_control_endpoint*);
565 static void usbs_imx_otg_dev_poll(usbs_control_endpoint*);
566
567 typedef enum ep0_state {
568     EP0_STATE_IDLE      = 0,
569     EP0_STATE_IN        = 1,
570     EP0_STATE_OUT       = 2
571 } ep0_state;
572
573 typedef struct ep0_impl {
574     usbs_control_endpoint   common;                     //struct usbs_control_endpoint defined in usbs.h
575     ep0_state               ep_state;
576     int                     length;
577     int                     transmitted;
578 } ep0_impl;
579
580 static ep0_impl ep0 = {
581     common:
582     {
583         state:                  USBS_STATE_POWERED, // The hardware does not distinguish  between detached, attached and powered.
584         enumeration_data:       (usbs_enumeration_data*) 0,
585         start_fn:               &usbs_imx_otg_dev_ep0_start,
586         poll_fn:                &usbs_imx_otg_dev_poll,
587         interrupt_vector:       IMX_IRQ_USB_DEV_SERVICE_REQUEST,
588         control_buffer:         { 0, 0, 0, 0, 0, 0, 0, 0 },
589         state_change_fn:        (void (*)(usbs_control_endpoint*, void*, usbs_state_change, int)) 0,
590         state_change_data:      (void*) 0,
591         standard_control_fn:    (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
592         standard_control_data:  (void*) 0,
593         class_control_fn:       (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
594         class_control_data:     (void*) 0,
595         vendor_control_fn:      (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
596         vendor_control_data:    (void*) 0,
597         reserved_control_fn:    (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
598         reserved_control_data:  (void*) 0,
599         buffer:                 (unsigned char*) 0,
600         buffer_size:            0,
601         fill_buffer_fn:         (void (*)(usbs_control_endpoint*)) 0,
602         fill_data:              (void*) 0,
603         fill_index:             0,
604         complete_fn:            (usbs_control_return (*)(usbs_control_endpoint*, int)) 0
605     },
606     ep_state:           EP0_STATE_IDLE,
607     length:             0,
608     transmitted:        0
609 };
610
611 extern usbs_control_endpoint usbs_imx_otg_ep0 __attribute__((alias ("ep0")));
612
613 // Endpoint 1 is optional. If the application only involves control
614 // messages or only slave->host transfers then the endpoint 1
615 // support can be disabled.
616 //#ifdef CYGPKG_DEVS_USB_MX37_EP1
617
618 typedef struct ep1_impl {
619     usbs_rx_endpoint    common;                 //struct usbs_rx_endpoint defined in usbs.h
620     int                 fetched;
621     cyg_bool            using_buf_a;
622 } ep1_impl;
623
624 static void ep1_start_rx(usbs_rx_endpoint*);
625 static void ep1_set_halted(usbs_rx_endpoint*, cyg_bool);
626
627 static ep1_impl ep1 = {
628     common: {
629         start_rx_fn:        &ep1_start_rx,
630         set_halted_fn:      &ep1_set_halted,
631         complete_fn:        (void (*)(void*, int)) 0,
632         complete_data:      (void*) 0,
633         buffer:             (unsigned char*) 0,
634         buffer_size:        0,
635         halted:             0,
636     },
637     fetched:            0,
638     using_buf_a:        0
639 };
640
641 extern usbs_rx_endpoint usbs_imx_otg_ep1 __attribute__((alias ("ep1")));
642 //#endif
643
644 // Endpoint 2 is optional. If the application only involves control
645 // messages or only host->slave transfers then the endpoint 2 support
646 // can be disabled.
647 //#ifdef CYGPKG_DEVS_USB_MX37_EP2
648
649 typedef struct ep2_impl {
650     usbs_tx_endpoint        common;                     //struct usbs_tx_endpoint defined in usbs.h
651     int                     transmitted;
652     int                     pkt_size;
653 } ep2_impl;
654
655 static void ep2_start_tx(usbs_tx_endpoint*);
656 static void ep2_set_halted(usbs_tx_endpoint*, cyg_bool);
657
658 static ep2_impl ep2 = {
659     common: {
660         start_tx_fn:        &ep2_start_tx,
661         set_halted_fn:      &ep2_set_halted,
662         complete_fn:        (void (*)(void*, int)) 0,
663         complete_data:      (void*) 0,
664         buffer:             (const unsigned char*) 0,
665         buffer_size:        0,
666         halted:             0,
667     }, 
668     transmitted:        0,
669     pkt_size:           0
670 };
671
672 extern usbs_tx_endpoint usbs_imx_otg_ep2 __attribute__ ((alias ("ep2")));
673 //#endif
674
675 // ****************************************************************************
676 // -----------------------Static Functions Initialization----------------------
677 // ****************************************************************************
678 static void usbs_handle_get_descriptor(void);
679 static void usbs_handle_set_configuration(void);
680 static void usbs_handle_get_device_desc(void);
681 static void usbs_handle_get_config_desc(void);
682 static void usbs_handle_get_string_desc(void);
683 static void usbs_handle_get_configuration(void);
684 static void usbs_handle_set_address(void);
685
686 static void usbs_ep0in_fill_buffer(cyg_uint8 type, cyg_uint32 buffer_addrs);
687 static usb_status_t usbs_ep0_send_data(usb_buffer_descriptor_t* bd,cyg_uint8 zlt);
688 static usb_status_t usbs_ep0_receive_data(usb_buffer_descriptor_t* bd);
689
690 static void usbs_setup_queuehead(struct dqh_t* qhead);
691 static void usbs_setup_transdesc(struct dtd_t* td);
692 static void usbs_endpoint_stall(cyg_uint8 endpoint , cyg_uint8 direction);
693 static void usbs_status_phase(cyg_uint8 trans_type, cyg_uint8 direction);
694
695 static void usbs_imx_otg_dev_set_configuration(usb_end_pt_info_t* config_data);
696 static void usbs_imx_otg_dev_handle_bus_reset(void);
697 static void usbs_imx_otg_dev_handle_port_change(void);
698 static void usbs_imx_otg_hardware_init(void);
699
700 cyg_uint32 util_alloc_buffer(void);
701 void util_free_buffer(cyg_uint32 address);
702 void util_set_status_bulk_buffer(cyg_uint32 buffer_addr,int buffer_status);
703 // ****************************************************************************
704 // -----------------------Static Functions ------------------------------------
705 // ****************************************************************************
706 /*=============================================================================
707 FUNCTION:               usbs_setup_queuehead
708 DESCRIPTION:    This function is used to setup the dQH
709          ------------------------
710         |       EP0 IN  (64 bytes)       |
711         |                                |
712          ------------------------       dQH1
713         |       EP0 OUT (64 bytes)       |
714         |                                |
715          ------------------------       dQH0
716 ARGUMENTS PASSED:
717         cyg_uint32 dqh_base - Base Address of the dQH
718         cyg_uint8       zlt - zero lengh packet termination (enable - ZLT_ENABLE; disable - ZLT_DISABLE)
719         cyg_uint16 mps - Max packet length
720         cyg_uint8       ios - interrupt on Setup
721         cyg_uint32 next_link_ptr - Next Link Pointer, 
722         cyg_uint8       terminate - terminate - TERMINATE; not terminate - NOT_TERMINATE
723         cyg_uint16 total_bytes - Total Bytes to be transfered in this dQH
724         cyg_uint8       ioc - interrupt on complete, set - IOC_SET, not set - IOC_NOTSET
725         cyg_uint8       status - status 
726         cyg_uint32 buffer_ptr0 - Buffer Pointer page 0
727         cyg_uint16 current_offset - current offset
728         cyg_uint32 buffer_ptr1 - Buffer Pointer page 1
729         cyg_uint32 buffer_ptr2 - Buffer Pointer page 1
730         cyg_uint32 buffer_ptr3 - Buffer Pointer page 1
731         cyg_uint32 buffer_ptr4 - Buffer Pointer page 1
732           
733 RETURN VALUE:   None            
734 IMPORTANT NOTES:None            
735 =============================================================================*/
736 static void 
737 usbs_setup_queuehead(struct dqh_t* qhead)
738 {
739     volatile struct dqh_setup_t* dqh_word = (volatile struct dqh_setup_t*) qhead->dqh_base;
740
741     /*Bit31:30 Mult; Bit29 zlt; Bit26:16 mps; Bit15 ios */
742     dqh_word->dqh_word0 = (((cyg_uint32)(qhead->zlt) << 29)|((cyg_uint32)(qhead->mps) <<16) | ((cyg_uint32)(qhead->ios) <<15));
743
744     /*Current dTD Pointer => for hw use, not modified by DCD software */
745     dqh_word->dqh_word1 = 0x0;
746         
747     /*Next dTD Pointer */
748     dqh_word->dqh_word2 = (((qhead->next_link_ptr) & 0xFFFFFFE0) | qhead->terminate);
749         
750     /*Bit30:16 total_bytes; Bit15 ioc; Bit11:10 MultO; Bit7:0 status */ 
751     dqh_word->dqh_word3 = ((((cyg_uint32)(qhead->total_bytes) & 0x7FFF)  << 16) | ((cyg_uint32)(qhead->ioc) <<15) | (qhead->status));
752
753     /*Bit31:12 Buffer Pointer (Page 0) */
754     dqh_word->dqh_word4 = ((qhead->buffer_ptr0 & 0xFFFFF000) | (qhead->current_offset & 0xFFF));
755
756     /*Bit31:12 Buffer Pointer (Page 1) */
757     dqh_word->dqh_word5 = (qhead->buffer_ptr1 & 0xFFFFF000);
758         
759     /*Bit31:12 Buffer Pointer (Page 2) */
760     dqh_word->dqh_word6 = (qhead->buffer_ptr2 & 0xFFFFF000);
761
762     /*Bit31:12 Buffer Pointer (Page 3) */
763     dqh_word->dqh_word7 = (qhead->buffer_ptr3 & 0xFFFFF000);
764         
765     /*Bit31:12 Buffer Pointer (Page 4) */
766     dqh_word->dqh_word8 = (qhead->buffer_ptr4 & 0xFFFFF000);
767
768     /*Reserved */
769     dqh_word->dqh_word9 = 0;
770
771     /*Setup Buffer 0 */
772     dqh_word->dqh_word10 = 0;
773
774     /*Setup Buffer 1 */
775     dqh_word->dqh_word11 = 0;
776 }
777 /*=============================================================================
778 FUNCTION: usbs_setup_transdesc
779 DESCRIPTION: This function is used to setup the dTD
780 ARGUMENTS PASSED:
781         cyg_uint32 dtd_base - Base Address of the dTD
782         cyg_uint32 next_link_ptr - Next Link Pointer, 
783         cyg_uint8       terminate - terminate - TERMINATE; not terminate - NOT_TERMINATE
784         cyg_uint16 total_bytes - Total Bytes to be transfered in this dQH
785         cyg_uint8       ioc - interrupt on complete, set - IOC_SET, not set - IOC_NOTSET
786         cyg_uint8       Status - Status 
787         cyg_uint32 buffer_ptr0 - Buffer Pointer page 0
788         cyg_uint16 current_offset - current offset
789         cyg_uint32 buffer_ptr1 - Buffer Pointer page 1
790         cyg_uint32 buffer_ptr2 - Buffer Pointer page 1
791         cyg_uint32 buffer_ptr3 - Buffer Pointer page 1
792         cyg_uint32 buffer_ptr4 - Buffer Pointer page 1    
793 RETURN VALUE:   None            
794 IMPORTANT NOTES:None            
795 ==============================================================================*/
796 static void 
797 usbs_setup_transdesc(struct dtd_t* td)
798 {
799     volatile struct dtd_setup_t* dtd_word = (volatile struct dtd_setup_t *) td->dtd_base;
800
801     /* Bit31:5 Next Link Pointer ; Bit0 terminate */
802     dtd_word->dtd_word0 = ((td->next_link_ptr & 0xFFFFFFE0) | td->terminate);
803
804     /* Bit30:16 total_bytes, Bit15 ioc, Bit7:0 status */
805     dtd_word->dtd_word1 = ((((cyg_uint32)td->total_bytes & 0x7FFF) << 16)| ((cyg_uint32)td->ioc <<15) | (td->status));
806         
807     /* Bit31:12 Buffer Pointer Page 0 ; Bit11:0 Current Offset */
808     dtd_word->dtd_word2 = ((td->buffer_ptr0 & 0xFFFFF000) | (td->current_offset & 0xFFF));
809         
810     /* Bit31:12 Buffer Pointer Page 1 ; Bit10:0 Frame Number */
811     dtd_word->dtd_word3 = (td->buffer_ptr1 & 0xFFFFF000);
812
813     /* Bit31:12 Buffer Pointer Page 2 ; */
814     dtd_word->dtd_word4 = (td->buffer_ptr2 & 0xFFFFF000);
815
816     /* Bit31:12 Buffer Pointer Page 3 ; */
817     dtd_word->dtd_word5 = (td->buffer_ptr3 & 0xFFFFF000);
818
819     /* Bit31:12 Buffer Pointer Page 4 ; */
820     dtd_word->dtd_word6 = (td->buffer_ptr4 & 0xFFFFF000);
821
822 }
823
824 /*==================================================================================================
825 FUNCTION: util_alloc_buffer
826 DESCRIPTION:            This utility function allocate the free buffer available
827 ARGUMENTS PASSED:       None
828 RETURN VALUE:           cyg_uint32 address : address of the allocated buffer    
829 IMPORTANT NOTES:        If Buffer1 is FREE then return Buffer1 and mark this as Busy else check for buffer2 . If 
830         none of the buffer is free then return NULL.
831 ==================================================================================================*/
832 cyg_uint32 util_alloc_buffer(void)
833 {
834     cyg_uint32 buffer_addr = (cyg_uint32)NULL; //force type conversion for multiple NULL definitions
835     
836     /* Check if buffer1 is free then mark it busy and return address */ 
837     if (g_bulkbuffer_map.buffer1_status == BUFFER_FREE )
838     {
839         buffer_addr = g_bulkbuffer_map.buffer1_address;
840                 g_bulkbuffer_map.buffer1_status = BUFFER_IN_USE;
841     }
842     /* Check if buffer2 is free then mark it busy and return address */ 
843     else if(g_bulkbuffer_map.buffer2_status == BUFFER_FREE)
844     {
845         buffer_addr = g_bulkbuffer_map.buffer2_address;
846                 g_bulkbuffer_map.buffer2_status = BUFFER_IN_USE;
847     }
848     
849     return buffer_addr ;
850 }
851 /*==================================================================================================
852 FUNCTION:                       util_free_buffer
853 DESCRIPTION:            This function put the buffer in free state.
854 ARGUMENTS PASSED:       cyg_uint32 address : address of the buffer .    
855 RETURN VALUE:           None
856 IMPORTANT NOTES:        None
857                 
858 ==================================================================================================*/
859 void util_free_buffer(cyg_uint32 address)
860 {
861         if( address == g_bulkbuffer_map.buffer1_address )
862     {
863         g_bulkbuffer_map.buffer1_status = BUFFER_FREE;
864     }
865     else if ( address == g_bulkbuffer_map.buffer2_address )
866     {
867         g_bulkbuffer_map.buffer2_status = BUFFER_FREE;
868     }
869 }
870 /*==================================================================================================
871 FUNCTION:                       util_set_bulk_buffer_stat
872 DESCRIPTION:            This function change the bulk buffer status
873 ARGUMENTS PASSED:       cyg_uint32 buffer_addr: buffer base address
874                                         int buffer_status: new buffer_status
875 enum {
876         BUFFER_FREED,
877         BUFFER_RELEASED,
878         BUFFER_ALLOCATED
879 };
880 RETURN VALUE:           None
881 IMPORTANT NOTES:        None
882                 
883 ==================================================================================================*/
884 void util_set_status_bulk_buffer(cyg_uint32 buffer_addr,int buffer_status)
885 {
886         if( buffer_addr == (cyg_uint32)g_bulkbuffer_a.buffer)
887     {
888         g_bulkbuffer_a.stat = buffer_status;
889     }
890     else if ( buffer_addr == (cyg_uint32)g_bulkbuffer_b.buffer )
891     {
892         g_bulkbuffer_b.stat = buffer_status;
893     }
894         else
895                 return;
896 }
897 /*=============================================================================
898 FUNCTION:       usbs_endpoint_stall
899 DESCRIPTION: This function Send/Receive the STALL HANDSHAKE to  USB Host
900 ARGUMENTS PASSED:
901         cyg_uint8 endpoint  -   Endpoint Number .       
902         cyg_uint8 direction -   IN/OUT :  direction of EndPoint.
903 RETURN VALUE:   None
904 IMPORTANT NOTES:None            
905 ==============================================================================*/
906 static void
907 usbs_endpoint_stall(cyg_uint8 endpoint , cyg_uint8 direction)
908 {
909     if( direction == OUT )
910     { 
911         usbs_imx_otg_base->endptctrl[endpoint]|= STALL_RX;
912     }               
913     else 
914     {
915         usbs_imx_otg_base->endptctrl[endpoint] |= STALL_TX;
916     }
917
918         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - EP%d - %d stalled\n",endpoint,direction);
919 }
920
921 static void
922 usbs_endpoint_unstall(cyg_uint8 endpoint , cyg_uint8 direction)
923 {
924         if( direction == OUT )
925     { 
926         usbs_imx_otg_base->endptctrl[endpoint]&= ~STALL_RX;
927     }               
928     else 
929     {
930         usbs_imx_otg_base->endptctrl[endpoint]&= ~STALL_TX;
931     }
932 }
933
934 /*=============================================================================
935 FUNCTION:                       usbs_status_phase
936 DESCRIPTION:            This function Send/Receive the Status to/from Host.
937 ARGUMENTS PASSED:   cyg_uint8    direction              OUT     Receive Status Command From Host
938                                                                                         IN      Send Status Command to Host
939 RETURN VALUE:           None
940 IMPORTANT NOTES:        
941 ===============================================================================*/
942 static void 
943 usbs_status_phase(cyg_uint8 trans_type, cyg_uint8 direction)
944 {
945         usb_buffer_descriptor_t bd ;
946         
947     /* Buffer pointer is not used for EP0 */
948     bd.buffer = (cyg_uint32 *) 0xFFFFFFFF;
949     bd.size = 0x0;
950         
951     if(trans_type==CONTROL)
952     {
953         switch ( direction )
954         {
955                         case OUT :
956                         /*  Receive ZERO length Length Data */
957                         usbs_ep0_receive_data(&bd);
958                 break;
959                         case IN :
960                         /* Send ZERO length Length Data */
961                         usbs_ep0_send_data(&bd,0);
962                         break;
963         }
964     }
965     else if(trans_type==BULK)/*TODO*/
966     {
967         switch ( direction )
968         {
969                         case OUT :          
970                         /* Send ZERO length Length Data */
971                         //usbs_ep2_send_data(EP2,&bd,FALSE);
972                 break;
973                         case IN :
974                         /*  Receive ZERO length Length Data */
975                         //usbs_ep1_receive_data(EP1,&bd);
976                         break;
977         }
978     } 
979     
980 }
981 // ---------------------------------------------------------------------------
982 // The following static functions are for USB device enumeration processing
983 /*============================================================================
984 FUNCTION:                               usbs_handle_get_descriptor
985 DESCRIPTION:                    This function Handle the GET DESCRIPTOR request
986 ARGUMENTS PASSED:       None  
987 RETURN VALUE:                   None
988 IMPORTANT NOTES:        None            
989 ============================================================================*/
990 static void
991 usbs_handle_get_descriptor()
992 {
993         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get descriptor handler\n");
994         switch (g_usb_setup_data[WVALUE_HIGHBYTE])
995         {
996                 case DEVICE_DESC:       /* device descriptor*/
997                         usbs_handle_get_device_desc();  //Device will send the MPS to host
998                         break;
999                 case CONF_DESC:         /* configuration descriptor*/
1000                         usbs_handle_get_config_desc();  //Device will send the whole device descriptor to host
1001                 break;
1002                 case STRING_DESC:       /* string descriptor*/
1003                         usbs_handle_get_string_desc();
1004                 break;
1005                 case INTERFACE_DESC:
1006                 case ENDPOINT_DESC:
1007                 case DEVICE_QUALIFIER:
1008                 case OTHER_SPEED_CONF_DESC:
1009                 default:        /* Send STALL Handshake  */
1010                 usbs_endpoint_stall(EP0,IN);
1011                 break;
1012         }
1013
1014         
1015 }
1016 /*=============================================================================
1017 FUNCTION:                       usbs_handle_get_device_desc
1018 DESCRIPTION:            This function Handle the GET DEVICE DESCRIPTOR request
1019 ARGUMENTS PASSED:       None
1020 RETURN VALUE:           None
1021 IMPORTANT NOTES:        None            
1022 ==============================================================================*/
1023 static void 
1024 usbs_handle_get_device_desc(void)
1025 {
1026     usb_buffer_descriptor_t bd ;
1027     cyg_uint32  buffer_addrs;
1028     cyg_uint16  desc_length = 0x0;
1029     cyg_uint8   zlt = 0;//0 means false
1030
1031         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get device descriptor\n");
1032     
1033     /* get the buffer address for data transfer over EP0 */
1034     buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs;   //256bytes before the two Bulk buffers
1035         
1036     /* Fill the buffer with the descriptor data */
1037     usbs_ep0in_fill_buffer(FILL_DEVICE_DESC,buffer_addrs);
1038
1039     /* Get the length of descriptor requested */
1040     desc_length = g_usb_setup_data[WLENGTH_LOWBYTE];
1041     desc_length |= ( g_usb_setup_data[WLENGTH_HIGHBYTE] <<0x8);
1042
1043     /* If requested length of descriptor is lesser than actual length of descriptor then send 
1044      * requested length of descroptor only else send the actual length of descriptor*/
1045     if( g_usb_dev_state == USB_DEV_DEFAULT_STATE )
1046     {
1047         bd.size = MPS_8;
1048     }
1049     else 
1050     {
1051         bd.size = USB_DEV_DESC_LEN;
1052     }
1053
1054     /* Send descriptor - Data Phase*/
1055     usbs_ep0_send_data(&bd,zlt);        //zlt is false=>not zero length packet
1056                                                                 //send dev descriptor to host.
1057         
1058     /* Status Phase -- OUT */
1059     usbs_status_phase(CONTROL,OUT); //Get Zero-length data packet from Host, Device sends status: ACK(success), NAK(busy), or STALL(failed)
1060
1061                 
1062 }
1063 /*=============================================================================
1064 FUNCTION:               usbs_handle_get_config_desc
1065 DESCRIPTION:    This function Handle the GET CONFIGURATION DESCRIPTOR request
1066 ARGUMENTS PASSED:
1067 RETURN VALUE:   None
1068 IMPORTANT NOTES:None            
1069 =============================================================================*/
1070 static void 
1071 usbs_handle_get_config_desc(void)
1072 {
1073         usb_buffer_descriptor_t bd;
1074     cyg_uint32 buffer_addrs;
1075     cyg_uint16 desc_length_req = 0x0;
1076     cyg_uint16 desc_length = 0x0;
1077     int zlt = 0;
1078
1079         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get config descriptor\n");
1080     /* get the buffer address for data transfer over EP0 */
1081     buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs;
1082
1083         /* Fill the buffer with the descriptor data */
1084         usbs_ep0in_fill_buffer(FILL_CONF_DESC, buffer_addrs);
1085     
1086         /* total length of descriptor */
1087         desc_length = ((g_usb_desc.config_desc->usb_config_desc.total_length_lo) \
1088                                 | ( g_usb_desc.config_desc->usb_config_desc.total_length_hi << 0x8 ));
1089     /* Get the length of descriptor requested */
1090     desc_length_req = g_usb_setup_data[WLENGTH_LOWBYTE];
1091     desc_length_req |= ( g_usb_setup_data[WLENGTH_HIGHBYTE] <<0x8);
1092
1093
1094     /* If requested length of descriptor is lesser than actual length of descriotor then send 
1095      * requested length of descroptor only else send the actual length of descriptor*/
1096     if(desc_length_req <= desc_length)
1097     {
1098         bd.size = desc_length_req;
1099     }
1100     else
1101     {
1102         bd.size = desc_length;
1103
1104                 if ( bd.size > MPS_64)
1105                 {
1106                 zlt = 1;
1107                 }
1108     }
1109     usbs_ep0_send_data(&bd,zlt);        
1110         
1111     /* Status Phase -- OUT */
1112     usbs_status_phase(CONTROL,OUT); 
1113                 
1114 }
1115 /*=============================================================================
1116 FUNCTION:                       usbs_handle_get_string_desc
1117 DESCRIPTION:            This function Handle the GET STRING DESCRIPTOR request
1118 ARGUMENTS PASSED:       None
1119 RETURN VALUE:           None    
1120 IMPORTANT NOTES:        None            
1121 ==============================================================================*/
1122 static void 
1123 usbs_handle_get_string_desc(void)
1124 {
1125         usb_buffer_descriptor_t bd;
1126     cyg_uint32 buffer_addrs;
1127     cyg_uint16 desc_length_req = 0x0;
1128     cyg_uint16 length_of_desc = 0x0;
1129     int zlt = 0;
1130
1131         
1132     /* Get Buufer to fill the data to be received/transmitted.    */ 
1133     buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs;
1134            
1135     /* Get the length of descriptor requested */
1136     desc_length_req = g_usb_setup_data[WLENGTH_LOWBYTE];
1137     desc_length_req |= ( g_usb_setup_data[WLENGTH_HIGHBYTE] <<0x8);
1138
1139     switch (g_usb_setup_data[WVALUE_LOWBYTE])
1140     {
1141         case STR_DES0:
1142             usbs_ep0in_fill_buffer(FILL_STR_DES0,buffer_addrs);
1143             /* If requested length of descriptor is lesser than actual length of descriotor then send 
1144                      * requested length of descroptor only else send the actual length of descriptor*/
1145                 if(desc_length_req <= g_usb_desc.str_desc0->length )
1146                 {
1147                         bd.size = desc_length_req;
1148                 }
1149                 else
1150                 {
1151                                 bd.size = g_usb_desc.str_desc0->length;
1152                 if (  bd.size > MPS_64)
1153                         {
1154                         zlt = 1;
1155                         }
1156                 }
1157                 /* Data Phase -- IN */
1158                 usbs_ep0_send_data(&bd,zlt);            
1159                 /* Status Phase -- OUT */
1160                 usbs_status_phase(CONTROL,OUT);    
1161                         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get string descriptor 0\n");
1162                 break;
1163         
1164         case STR_DES1:          /*iManufacturer */
1165             usbs_ep0in_fill_buffer(FILL_STR_DES1,buffer_addrs);
1166                 /* If requested length of descriptor is lesser than actual length of descriotor then send 
1167                  * requested length of descroptor only else send the actual length of descriptor*/
1168                     if(desc_length_req <= g_usb_desc.str_desc1->length )
1169                     {
1170                     bd.size = desc_length_req;
1171                 }
1172                 else
1173                 {
1174                                 bd.size = g_usb_desc.str_desc1->length;
1175                 if (  bd.size > MPS_64) 
1176                                 {
1177                         zlt = 1;
1178                         }
1179                 }
1180                 /* Data Phase -- IN */
1181                 usbs_ep0_send_data(&bd,zlt);    
1182                     /* Status Phase -- OUT */
1183                     usbs_status_phase(CONTROL,OUT); 
1184                         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get string descriptor 1\n");
1185             break;
1186         
1187         case STR_DES2:          /*iProduct */
1188             usbs_ep0in_fill_buffer(FILL_STR_DES2,buffer_addrs );
1189                         length_of_desc = g_usb_desc.str_desc2->length; 
1190                     /* If requested length of descriptor is lesser than actual length of descriotor then send 
1191                 * requested length of descroptor only else send the actual length of descriptor*/
1192                     if(desc_length_req <= length_of_desc )
1193                     {
1194                     bd.size = desc_length_req;
1195                     }
1196                     else
1197                 {
1198                                 bd.size = length_of_desc;
1199                 if (  bd.size > MPS_64)
1200                     {
1201                             zlt = 1;
1202                         }
1203                     }
1204                     /* Data Phase -- IN */
1205                 usbs_ep0_send_data(&bd,zlt);    
1206                     /* Status Phase -- OUT */
1207                     usbs_status_phase(CONTROL,OUT);     
1208                         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get string descriptor 2\n");
1209                     break;
1210         
1211         case STR_DES3:  
1212                         /* send zero length data */
1213                         usbs_status_phase(CONTROL,IN);
1214                         /* Status Phase -- OUT */
1215             usbs_status_phase(CONTROL,OUT);
1216                         break;
1217         
1218         case STR_DES5:          /*iSerialNumber */
1219                         #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
1220             usbs_ep0in_fill_buffer(FILL_SN_DESC,buffer_addrs );
1221                     /* If requested length of descriptor is lesser than actual length of descriotor then send 
1222                         * requested length of descroptor only else send the actual length of descriptor*/
1223                     if(desc_length_req <= g_usb_desc.sn_desc->length )
1224                     {
1225                     bd.size = desc_length_req;
1226                     }
1227                     else
1228                     {
1229                                 bd.size = g_usb_desc.sn_desc->length;
1230                 if (  bd.size > MPS_64)
1231                         {
1232                             zlt = 1;
1233                         }
1234                     }
1235                 /* Data Phase -- IN */
1236                     usbs_ep0_send_data(&bd,zlt);        
1237                     /* Status Phase -- OUT */
1238                     usbs_status_phase(CONTROL,OUT); 
1239                         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get string descriptor - SN\n");
1240                     break;
1241                         #endif
1242                 case STR_DES4:          /*iSerialNumber */
1243                         usbs_ep0in_fill_buffer(FILL_STR_DES3,buffer_addrs );
1244                     /* If requested length of descriptor is lesser than actual length of descriotor then send 
1245                         * requested length of descroptor only else send the actual length of descriptor*/
1246                     if(desc_length_req <= g_usb_desc.str_desc3->length )
1247                     {
1248                     bd.size = desc_length_req;
1249                     }
1250                     else
1251                     {
1252                                 bd.size = g_usb_desc.str_desc3->length;
1253                 if (  bd.size > MPS_64)
1254                         {
1255                             zlt = 1;
1256                         }
1257                     }
1258                 /* Data Phase -- IN */
1259                     usbs_ep0_send_data(&bd,zlt);        
1260                     /* Status Phase -- OUT */
1261                     usbs_status_phase(CONTROL,OUT); 
1262                         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get string descriptor 3\n");
1263                     break;
1264                 default:
1265                 /* Send STALL Handshake  */
1266                     usbs_endpoint_stall(EP0,IN);
1267                         //USBDBGMSG("+USBDBGMSG:EP0 IN stalled at get string desc\n");
1268                     break;
1269     }
1270
1271                 
1272 }
1273
1274 /*=============================================================================
1275 FUNCTION:               usbs_handle_set_address
1276 DESCRIPTION:    This function Handle the SET ADDRESS Request from USB Host
1277 ARGUMENTS PASSED:       None
1278 RETURN VALUE:           None
1279 IMPORTANT NOTES:        
1280 ==============================================================================*/
1281 static void 
1282 usbs_handle_set_address(void)
1283 {
1284                 cyg_uint16 device_addrs;
1285
1286                 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set address handler\n");   
1287     /* Get the Device Address to be SET from the Setup Data  */
1288     device_addrs = g_usb_setup_data[WVALUE_LOWBYTE] + (g_usb_setup_data[WVALUE_HIGHBYTE]<<8);
1289        
1290     if  ((g_usb_setup_data[WINDEX_LOWBYTE] == 0) &&
1291                 (g_usb_setup_data[WINDEX_HIGHBYTE] == 0) &&
1292                 (g_usb_setup_data[WLENGTH_LOWBYTE] == 0) &&
1293                 (g_usb_setup_data[WLENGTH_HIGHBYTE] == 0) &&
1294                 (device_addrs <= USB_MAX_DEVICE_ADDR))
1295     { 
1296         switch(g_usb_dev_state)
1297                 {
1298                 case USB_DEV_DEFAULT_STATE :
1299                                 /* Send Ack to Host */
1300                                 usbs_status_phase(CONTROL,IN);
1301                                 if (device_addrs != USB_DEFAULT_ADDR)
1302                                 {
1303                                         /* Set the Device Address */
1304                         USBS_DEVICE_SET_ADDRESS(device_addrs);
1305                                         /* Change state to ADDRESSED STATE  */
1306                                         g_usb_dev_state  = USB_DEV_ADDRESSED_STATE;
1307                                 }
1308                         break;
1309                 
1310                         case USB_DEV_ADDRESSED_STATE :
1311                                 /* Send Ack to Host */
1312                                 usbs_status_phase(CONTROL,IN);
1313                                 if ( device_addrs == USB_DEFAULT_ADDR )
1314                                 {
1315                                 /* Set the Device Address */
1316                                 USBS_DEVICE_SET_ADDRESS(USB_DEFAULT_ADDR);
1317                                         /* Change state to ADDRESSED STATE  */
1318                                         g_usb_dev_state = USB_DEV_DEFAULT_STATE;    
1319                         }
1320                                 else
1321                                 {
1322                                         /* Set the Device Address */
1323                                         USBS_DEVICE_SET_ADDRESS(device_addrs);
1324                                 }
1325                                 break;
1326         
1327             case USB_DEV_CONFIGURED_STATE :
1328                         if ( device_addrs == USB_DEFAULT_ADDR)
1329                                 {
1330                                         /* Send Ack to Host */
1331                                         usbs_status_phase(CONTROL,IN);
1332                                         /* Set the Device Address */
1333                                         USBS_DEVICE_SET_ADDRESS(device_addrs);
1334                                         /* Change state to ADDRESSED STATE  */
1335                                         g_usb_dev_state = USB_DEV_DEFAULT_STATE;    
1336                                 }
1337                                 else
1338                                 {
1339                                         /* Send STALL Handshake  */ 
1340                                         usbs_endpoint_stall(EP0,IN);
1341                                 }
1342                         default :
1343                                 break;
1344                 }
1345     }
1346     else
1347     {
1348         /* Send STALL Handshake */
1349         usbs_endpoint_stall(EP0,IN);
1350     }
1351
1352                 
1353 }
1354 /*=============================================================================
1355 FUNCTION:                       usbs_handle_get_configuration
1356 DESCRIPTION:            This function Handle the GET CONFIGURATION request
1357 ARGUMENTS PASSED:       None  
1358 RETURN VALUE:           None    
1359 IMPORTANT NOTES:        None            
1360 =============================================================================*/
1361 static void 
1362 usbs_handle_get_configuration(void)
1363 {
1364         usb_buffer_descriptor_t bd;
1365         cyg_uint32 buffer_addrs;
1366     cyg_uint32* buffer_ptr;
1367  
1368     if((g_usb_setup_data[WINDEX_LOWBYTE] == 0) &&
1369         (g_usb_setup_data[WINDEX_HIGHBYTE] == 0) &&
1370         (g_usb_setup_data[WVALUE_LOWBYTE] == 0) &&
1371         (g_usb_setup_data[WVALUE_HIGHBYTE] == 0) &&
1372                 (g_usb_setup_data[WLENGTH_LOWBYTE] == LEN_OF_CONFIG_VALUE) &&
1373         (g_usb_setup_data[WLENGTH_HIGHBYTE] == 0)) 
1374     {
1375         switch(g_usb_dev_state)
1376                 {
1377                 case USB_DEV_DEFAULT_STATE :
1378                         /* Send STALL Handshake */
1379                         usbs_endpoint_stall(EP0,IN);
1380                                 break;
1381                 case USB_DEV_ADDRESSED_STATE:
1382                                 /* If the Device is in Address state then return 0x0 : See USB2.0 Spec */
1383                                 buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs;
1384                                 buffer_ptr = (cyg_uint32 *)buffer_addrs;
1385                                 *buffer_ptr = 0x0;
1386
1387                                 bd.buffer = buffer_ptr;
1388                                 bd.size=LEN_OF_CONFIG_VALUE;
1389
1390                                 usbs_ep0_send_data(&bd,0);
1391
1392                                 /* Receive Ack from Host*/
1393                                 usbs_status_phase(CONTROL,OUT);
1394                                 break;
1395
1396                         case USB_DEV_CONFIGURED_STATE:
1397                                 buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs;
1398                 buffer_ptr = (cyg_uint32 *)buffer_addrs;
1399
1400                                 *buffer_ptr = (cyg_uint32 )g_usb_desc.config_desc->usb_config_desc.configuration_id;
1401
1402                                 bd.buffer = buffer_ptr;
1403                                 bd.size=LEN_OF_CONFIG_VALUE;
1404
1405                                 usbs_ep0_send_data(&bd,0);
1406                 
1407                                 /* Receive Ack from Host*/
1408                                 usbs_status_phase(CONTROL,OUT);
1409                                 break;
1410
1411                         default:
1412                         /* Send STALL Handshake */
1413                         usbs_endpoint_stall(EP0,IN);
1414                 }
1415
1416     } 
1417
1418                 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get config handler\n");
1419 }
1420 /*=============================================================================
1421 FUNCTION:                       usbs_handle_set_configuration
1422 DESCRIPTION:            This function Handle the SET CONFIGURATION request
1423 ARGUMENTS PASSED:       None  
1424 RETURN VALUE:           None    
1425 IMPORTANT NOTES:        None            
1426 =============================================================================*/
1427 static void 
1428 usbs_handle_set_configuration(void)
1429 {
1430         usb_end_pt_info_t config_data ; 
1431     cyg_uint8 i;
1432
1433     switch (g_usb_dev_state)
1434     {
1435                 case USB_DEV_ADDRESSED_STATE :
1436                         if (g_usb_setup_data[WVALUE_LOWBYTE] == USB_DEV_VALUE_OF_UNCONFIG)
1437                         {       
1438                                 /* Send Ack to Host*/
1439                                 usbs_status_phase(CONTROL,IN);
1440                     }
1441             /* Check if the configuration value received request is same as in Config descriptor */
1442                     else if(g_usb_setup_data[WVALUE_LOWBYTE] == g_usb_desc.config_desc->usb_config_desc.configuration_id)
1443                     {
1444                                 /* Configure endpoints */
1445                                 for ( i = 0 ; i< g_number_of_endpoints ; i++)
1446                                 {
1447                                 config_data.end_pt_no           = g_end_pt_info[i].end_pt_no; 
1448                                 config_data.direction           = g_end_pt_info[i].direction;
1449                                 config_data.transfer_type       = g_end_pt_info[i].transfer_type;
1450                                 config_data.max_pkt_size        = g_end_pt_info[i].max_pkt_size;
1451                 
1452                                         usbs_imx_otg_dev_set_configuration(&config_data);
1453                                 }
1454
1455                                 /* Send Ack to Host*/
1456                                 usbs_status_phase(CONTROL,IN);
1457
1458                                 g_usb_dev_state = USB_DEV_CONFIGURED_STATE ;
1459                 }
1460                 else
1461                 {
1462                                 /* Invalid configuration value.  Send STALL Handshake */
1463                         usbs_endpoint_stall(EP0,IN);
1464                                 //USBDBGMSG("+USBDBGMSG:EP0 IN stalled at set conf in addr state\n");
1465                 }
1466                         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set conf@ADDRESSED_STATE\n");
1467                         break;  
1468                 case USB_DEV_CONFIGURED_STATE :
1469                 if(g_usb_setup_data[WVALUE_LOWBYTE] == USB_DEV_CONFIG_DESC_CONFIG_VALUE)
1470                 {
1471                                 /* Send Ack to Host*/
1472                                 usbs_status_phase(CONTROL,IN);
1473                 }
1474                 else if (g_usb_setup_data[WVALUE_LOWBYTE] == USB_DEV_VALUE_OF_UNCONFIG)
1475                 {       
1476                                 /* Send Ack to Host*/
1477                                 usbs_status_phase(CONTROL,IN);
1478
1479                                 /* Change USB State to Addressed State  */
1480                                 g_usb_dev_state = USB_DEV_ADDRESSED_STATE;
1481                 }
1482                         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set conf@CONFIGURED_STATE\n");
1483                         break;
1484                 default :
1485                 /* Send STALL Handshake */
1486                 usbs_endpoint_stall(EP0,IN);
1487                         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set conf@incorrect state\n");
1488                 break;  
1489     }
1490
1491         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set config handler\n");
1492 }
1493 /*=============================================================================
1494 FUNCTION:                       usbs_handle_msc_get_maxlun
1495 DESCRIPTION:            This function Handle the GET MAX LUN Mass Storage class
1496                                 specific request
1497 ARGUMENTS PASSED:       None  
1498 RETURN VALUE:           None    
1499 IMPORTANT NOTES:        None            
1500 =============================================================================*/
1501 static void 
1502 usbs_handle_msc_get_maxlun(void)
1503 {
1504         usb_buffer_descriptor_t bd ;
1505     cyg_uint32  buffer_addrs;
1506     cyg_uint16  desc_length = 0x0;
1507     cyg_uint8   zlt = 0;//0 means false
1508         cyg_uint8 Max_Lun=0;
1509         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: MASS - Get MAX LUN\n");
1510     
1511     /* get the buffer address for data transfer over EP0 */
1512     buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs;   //256bytes before the two Bulk buffers
1513
1514     /* Get the length of descriptor requested */
1515     desc_length = g_usb_setup_data[WLENGTH_LOWBYTE];
1516     desc_length |= ( g_usb_setup_data[WLENGTH_HIGHBYTE] <<0x8);
1517
1518     /* If requested length of descriptor is zero*/
1519         if(desc_length==0)
1520         {
1521                 /* Fill the buffer with the descriptor data */
1522                 *(cyg_uint8 *)buffer_addrs = 0;//Max_Lun;
1523                 bd.size = 0; 
1524         }
1525         else
1526         {
1527                 /* Fill the buffer with the descriptor data */
1528                 *(cyg_uint8 *)buffer_addrs = Max_Lun;
1529                 bd.size = desc_length;
1530         }
1531         
1532     /* Send descriptor - Data Phase*/
1533     usbs_ep0_send_data(&bd,zlt);        //zlt is false=>not zero length packet
1534                                                                 //send dev descriptor to host.
1535         
1536     /* Status Phase -- OUT */
1537     usbs_status_phase(CONTROL,OUT); //Get Zero-length data packet from Host, Device sends status: ACK(success), NAK(busy), or STALL(failed)
1538
1539                 
1540 }
1541 /*=============================================================================
1542 FUNCTION:               usbs_ep0in_fill_buffer
1543 DESCRIPTION:    This function is used to fill the corresponding 
1544                                 response for the data phase of SETUP Transfer
1545 ARGUMENTS PASSED:
1546                                 cyg_uint8 type: type of descriptor
1547                                 cyg_uint32 buffer_addrs - buffer pointer to be filled    
1548 RETURN VALUE:   None
1549 IMPORTANT NOTES:None
1550 =============================================================================*/
1551 static void 
1552 usbs_ep0in_fill_buffer(cyg_uint8 type, cyg_uint32 buffer_addrs)
1553 {
1554     const cyg_uint8 *data=0;
1555     cyg_uint32 *buffer_page = (cyg_uint32*)buffer_addrs;    
1556     int k = 0;
1557         //USBDBGMSG("+USBDBGMSG: enum - copy descriptor to buffer\n");
1558     switch (type)
1559     {
1560         case FILL_DEVICE_DESC:  /*5*32 bit */
1561                 data = (cyg_uint8 *)g_usb_desc.device_desc;
1562             break;
1563                 case FILL_CONF_DESC:            /*8*32 bit */
1564                     data = (cyg_uint8 *)g_usb_desc.config_desc;
1565                 break;  
1566                 case FILL_STR_DES0:             /*1*32 bit */
1567                 data = (cyg_uint8 *)g_usb_desc.str_desc0;
1568                 break;  
1569                 case FILL_STR_DES1:             /*7*32 bit */
1570                     data =(cyg_uint8 *)g_usb_desc.str_desc1; 
1571                 break;  
1572                 case FILL_STR_DES2:             /*7*32 bit */
1573                         data = (cyg_uint8 *)g_usb_desc.str_desc2;
1574                     break;      
1575                 case FILL_STR_DES3:             /*6*32 bit */
1576                     data = (cyg_uint8 *)g_usb_desc.str_desc3;
1577                 break;
1578                 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
1579                 case FILL_SN_DESC:
1580                         data = (cyg_uint8 *)g_usb_desc.sn_desc;
1581                         break;
1582                 #endif
1583     }
1584     
1585     for (k=0; k<(MPS_64/sizeof(cyg_uint32)); k++)
1586     {
1587         *buffer_page = data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24); 
1588                                  //USBDBGMSG("+USBDBGMSG: desc[k] = 0x%x\n",(*buffer_page));
1589          buffer_page++;
1590                                  data += 4;
1591                                 
1592     }
1593
1594                 
1595 }
1596
1597 /*=============================================================================
1598 FUNCTION:                       usbs_ep0_init_dqh
1599 DESCRIPTION:            This function is used to initialize the queue header of EP0
1600 ARGUMENTS PASSED:       NONE                             
1601 RETURN VALUE:           NONE
1602 IMPORTANT NOTES:        called by usbs_imx_otg_dev_ep0_init(),usbs_imx_otg_dev_handle_bus_reset()
1603 =============================================================================*/
1604 static void
1605 usbs_ep0_init_dqh(void)
1606 {
1607         struct dqh_t qhead;
1608         cyg_uint32 total_bytes;
1609         volatile cyg_uint32 * ep_q_hdr_base;
1610         cyg_int8 i;
1611         
1612         //clear queue header
1613         ep_q_hdr_base = ((volatile cyg_uint32 *)g_bulkbuffer_map.ep_dqh_base_addrs);
1614         /* Clear the dQH Memory */
1615     for ( i = 0; i < (SIZE_OF_QHD*g_max_ep_supported*2)/sizeof(cyg_uint32) ; i++)
1616     {
1617         *ep_q_hdr_base++ = 0;
1618     }
1619     
1620      /******************************************************************************
1621     / =================
1622     / dQH0 for EP0OUT
1623     / =================
1624     / Initialize device queue heads in system memory
1625     / 8 bytes for the 1st setup packet */
1626        
1627     total_bytes                                 = 0x8;
1628     qhead.dqh_base                              = USBS_EP_GET_dQH(EP0,OUT);
1629     qhead.zlt                                   = ZLT_DISABLE;
1630     qhead.mps                                   = MPS_64;
1631     qhead.ios                                   = IOS_SET;
1632     qhead.next_link_ptr = USBS_EP_GET_dTD(EP0,OUT);
1633     qhead.terminate             = NOT_TERMINATE;
1634     qhead.total_bytes   = total_bytes;
1635     qhead.ioc                                   = IOC_SET;
1636     qhead.status                                = NO_STATUS;
1637     qhead.buffer_ptr0   = 0;
1638     qhead.current_offset= 0;
1639     qhead.buffer_ptr1   = 0;
1640     qhead.buffer_ptr2   = 0;
1641     qhead.buffer_ptr3   = 0;
1642     qhead.buffer_ptr4   = 0;
1643     /* Set Device Queue Head */
1644     usbs_setup_queuehead(&qhead);
1645
1646     /* ==================
1647     END of dQH0 setup
1648     ====================*/
1649      /*=================
1650     dQH1 for EP0IN
1651     ================= */
1652
1653     total_bytes                 = 0x8;
1654     qhead.dqh_base              = USBS_EP_GET_dQH(EP0,IN);
1655     qhead.zlt                   = ZLT_DISABLE;
1656     qhead.mps                   = MPS_64;
1657     qhead.ios                   = IOS_SET;
1658     qhead.next_link_ptr = USBS_EP_GET_dTD(EP0,IN);
1659     qhead.terminate     = TERMINATE;
1660     qhead.total_bytes   = total_bytes;
1661     qhead.ioc                   = IOC_SET;
1662     qhead.status                = NO_STATUS;
1663     qhead.buffer_ptr0   = g_bulkbuffer_map.ep0_buffer_addrs;
1664     qhead.current_offset= (g_bulkbuffer_map.ep0_buffer_addrs & 0xFFF);
1665     qhead.buffer_ptr1   = 0;
1666     qhead.buffer_ptr2   = 0;
1667     qhead.buffer_ptr3   = 0;
1668     qhead.buffer_ptr4   = 0;
1669
1670     /* Set Device Queue Head */
1671     usbs_setup_queuehead(&qhead);
1672
1673     /* ==================
1674     /  END of dQH1 setup
1675     /  ================*/
1676 }
1677 /*=============================================================================
1678 FUNCTION:                       usbs_ep0_send_data 
1679 DESCRIPTION:            This function Send Data to host through EP0-IN Pipe.
1680 ARGUMENTS PASSED:
1681         usb_buffer_descriptor_t *bd : This is the pointer to the buffer descriptor. 
1682         cyg_uint8 zlt                           : Flag to decide if Zero Length Packet to be sent
1683 RETURN VALUE:
1684         USB_SUCCESS - The buffer was successfully processed by the USB device and 
1685                                         data sent to the Host.
1686         USB_FAILURE - Some failure occurred in transmitting the data.
1687 IMPORTANT NOTES:        None            
1688 =============================================================================*/
1689 static usb_status_t 
1690 usbs_ep0_send_data(usb_buffer_descriptor_t* bd,cyg_uint8 zlt)
1691 {
1692         struct dtd_t td;
1693     cyg_uint32 total_bytes ;
1694     cyg_uint32 dtd_address,dqh_address;
1695     
1696     usb_status_t status = USB_FAILURE;
1697
1698         /* Get Device Transfer Descriptor of the requested endpoint */
1699         dtd_address = USBS_EP_GET_dTD(EP0,IN);
1700     
1701         /* Get Device Queue head of the requested endpoint */
1702         dqh_address = USBS_EP_GET_dQH(EP0,IN);
1703
1704         /* Get Total Bytes to Be recieved */
1705         total_bytes = bd->size;
1706
1707         /* Setup Transfer Descriptor for EP0 IN*/
1708         td.dtd_base             = dtd_address; 
1709         td.next_link_ptr        = 0;
1710         td.terminate            = TERMINATE;
1711         td.total_bytes          = total_bytes;
1712         td.ioc                          = IOC_SET;
1713         td.status                       = ACTIVE;
1714         td.buffer_ptr0          = g_bulkbuffer_map.ep0_buffer_addrs;
1715         td.current_offset       = (g_bulkbuffer_map.ep0_buffer_addrs & 0xFFF);
1716         td.buffer_ptr1          = 0;
1717         td.buffer_ptr2          = 0;
1718         td.buffer_ptr3          = 0;
1719         td.buffer_ptr4          = 0;
1720                
1721         /* Set the transfer descriptor */       
1722         usbs_setup_transdesc(&td);
1723            
1724         /* Enable ZLT when data size is in multiple of Maximum Packet Size  */
1725         if(zlt)
1726         {
1727                 /* set ZLT enable */
1728                 (*(volatile cyg_uint32*)(dqh_address)) &= ~0x20000000;
1729         }
1730             
1731         /* 1. write dQH next ptr and dQH terminate bit to 0  */
1732         *(volatile cyg_uint32*)(dqh_address+0x8)= (dtd_address); 
1733             
1734         /* 2. clear active & halt bit in dQH */
1735         *(volatile cyg_uint32*)(dqh_address+0xC) &= ~0xFF;
1736            
1737         /* 3. prime endpoint by writing '1' in ENDPTPRIME */
1738         usbs_imx_otg_base->endptprime |= BIT16;
1739     
1740         /* wait for complete set and clear */
1741         while (!(usbs_imx_otg_base->endptcomplete & EPIN_COMPLETE));
1742         
1743         usbs_imx_otg_base->endptcomplete = EPIN_COMPLETE;
1744         
1745         status = USB_SUCCESS;
1746
1747         return status;
1748 }
1749 /*=============================================================================
1750 FUNCTION: usbs_ep0_recevie_data
1751 DESCRIPTION:    This function Handle the Status Token (IN/OUT) from USB Host
1752 ARGUMENTS PASSED:
1753         usb_buffer_descriptor_t *bd : This is the pointer to the buffer descriptor. 
1754 RETURN VALUE:
1755         USB_SUCCESS -   : The buffer was successfully processed by the USB device and 
1756                                                         data is received from the host.
1757         USB_FAILURE -   : Some failure occurred in receiving the data.
1758         USB_INVALID -   : If the endpoint is invalid.
1759 IMPORTANT NOTES:None            
1760 =============================================================================*/
1761 static usb_status_t usbs_ep0_receive_data(usb_buffer_descriptor_t* bd)
1762 {
1763                 struct dtd_t td;
1764     usb_status_t status = USB_FAILURE;
1765     cyg_uint32 total_bytes;
1766     cyg_uint32 dtd_address;
1767     cyg_uint32 dqh_address;
1768
1769                 /* Get Device Device Queue Head of the requested endpoint */
1770     dqh_address = USBS_EP_GET_dQH(EP0, OUT);
1771         
1772                 /* Get Device Transfer Descriptor of the requested endpoint */
1773     dtd_address = USBS_EP_GET_dTD(EP0, OUT);
1774
1775                 /* Get the total bytes to be received   */
1776                 total_bytes             = bd->size; 
1777                 
1778                 td.dtd_base                     = dtd_address;
1779                 td.next_link_ptr        = dtd_address + 0x20;
1780                 td.terminate            = TERMINATE;
1781                 td.total_bytes          = total_bytes;
1782                 td.ioc                          = IOC_SET;
1783                 td.status                       = ACTIVE;
1784                 td.buffer_ptr0          = g_bulkbuffer_map.ep0_buffer_addrs;
1785                 td.current_offset       = (g_bulkbuffer_map.ep0_buffer_addrs & 0xFFF);
1786                 td.buffer_ptr1          = 0;
1787                 td.buffer_ptr2          = 0;
1788                 td.buffer_ptr3          = 0;
1789                 td.buffer_ptr4          = 0;
1790                 
1791         /* Set the Transfer Descriptor  */
1792         usbs_setup_transdesc(&td);
1793
1794         /* 1. write dQH next ptr and dQH terminate bit to 0 */
1795         *(volatile cyg_uint32*)(dqh_address+0x8)= dtd_address;
1796             
1797         /* 2. clear active & halt bit in dQH */
1798         *(volatile cyg_uint32*)(dqh_address+0xC) &= ~0xFF;
1799             
1800         /* 3. prime endpoint by writing '1' in ENDPTPRIME */
1801         usbs_imx_otg_base->endptprime |= (  EPOUT_PRIME << EP0 );
1802
1803         /* 4. Wait for the Complete Status */
1804         while (!((usbs_imx_otg_base->endptprime) & ( EPOUT_COMPLETE << EP0)));
1805             
1806         /*clear the complete status */
1807         usbs_imx_otg_base->endptprime = (EPOUT_COMPLETE << EP0);
1808    
1809         status = USB_SUCCESS;
1810
1811         return status;
1812 }
1813 // ****************************************************************************
1814 // -----------------------Endpoint 0 Functions---------------------------------
1815 // ****************************************************************************
1816 /*=============================================================================
1817 // This is where all the hard work happens. It is a very large routine
1818 // for a DSR, but in practice nearly all of it is nested if's and very
1819 // little code actually gets executed. Note that there may be
1820 // invocations of callback functions and the driver has no control
1821 // over how much time those will take, but those callbacks should be
1822 // simple.
1823 // so far, ep0 DSR works only during enumeration here.
1824 =============================================================================*/
1825 static void
1826 usbs_imx_otg_dev_ep0_dsr(void)
1827 {
1828         usb_buffer_descriptor_t bd ;
1829         usb_status_t status = USB_FAILURE;
1830         volatile struct dqh_setup_t * dqh_word ;
1831         cyg_uint32 dqh_address;
1832         cyg_uint32 temp;
1833         
1834         //USBDBGMSG("+USBDBGMSG: enter ep0 dsr.\n");
1835         /* 1. Receive Setup Data*/
1836         bd.buffer = (cyg_uint32 *)g_usb_setup_data;
1837         bd.size   = 0;
1838         
1839         /* Get the Device Queue Head Address for EP0 OUT   */ 
1840         dqh_address = USBS_EP_GET_dQH(EP0,OUT);
1841         dqh_word = (volatile struct dqh_setup_t*)dqh_address;
1842   
1843         /* write '1' to clear corresponding bit in ENDPTSETUPSTAT */
1844         temp = usbs_imx_otg_base->endptsetupstat;
1845         usbs_imx_otg_base->endptsetupstat = temp;           
1846
1847 //      if(usbs_imx_otg_base->endptsetupstat & BIT0)
1848 //              usbs_imx_otg_base->endptsetupstat = BIT0;           
1849         
1850         do{
1851             /* write '1' to Setup Tripwire (SUTW) in USBCMD register */
1852             usbs_imx_otg_base->usbcmd |= BIT13;
1853                 
1854             /* Copy the SetupBuffer into local software byte array */
1855             temp  = (dqh_word->dqh_word10);
1856
1857           *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )(temp & 0x000000FF);
1858                 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1859                 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )((temp & 0x0000FF00)>>8);
1860                 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1861                 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )((temp & 0x00FF0000)>>16);
1862                 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1863                 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )((temp & 0xFF000000)>>24);
1864                 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1865           
1866                 temp  = (dqh_word->dqh_word11);
1867                 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )(temp & 0x000000FF);
1868                 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1869                 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )((temp & 0x0000FF00)>>8);
1870                 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1871                 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )((temp & 0x00FF0000)>>16);
1872                 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1873                 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )((temp & 0xFF000000)>>24);
1874                 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1875         }while (!(usbs_imx_otg_base->usbcmd & BIT13));  
1876         
1877         /* Write '0' to clear SUTW in USBCMD register */
1878         usbs_imx_otg_base->usbcmd &= ~BIT13;
1879         status = USB_SUCCESS;
1880
1881         #if 0
1882         USBDBGMSG("+USBDBGMSG: setup packet:(LSB)");
1883         for(temp=0;temp<8;temp++)
1884         {
1885                 USBDBGMSG("%02X",g_usb_setup_data[temp]);
1886         }
1887         USBDBGMSG("(MSB)\n");
1888         #endif
1889         
1890         /* 2. Process Setup Data*/
1891         /* switch construct to handle different request*/
1892         /* Parser the Setup Request Type */
1893         switch (g_usb_setup_data[BREQUEST])             
1894         { 
1895                 case USB_GET_DESCRIPTOR:
1896                         /* Handle the GET DESCRIPTOR Request */
1897                         usbs_handle_get_descriptor();
1898             break;
1899         
1900                 case USB_SET_ADDRESS:
1901                         /* Handle the SET ADDRESS Request */
1902                         usbs_handle_set_address();
1903                         break;
1904             
1905                 case USB_SET_CONFIGURATION:
1906                         /* Handle the SET CONFIGURATION Request */
1907                         if ((g_usb_setup_data[WINDEX_LOWBYTE] == 0)     &&
1908                                 (g_usb_setup_data[WINDEX_HIGHBYTE] == 0)&&
1909                                 (g_usb_setup_data[WLENGTH_LOWBYTE] == 0)&&
1910                                 (g_usb_setup_data[WLENGTH_HIGHBYTE] == 0)&&
1911                                 (g_usb_setup_data[WVALUE_HIGHBYTE] == 0)) 
1912                         {
1913                                 usbs_handle_set_configuration();
1914                         }
1915                         else
1916                         {
1917                                 /* Send STALL Handshake   */
1918                                 usbs_endpoint_stall(EP0,IN);
1919                                 //USBDBGMSG("+USBDBGMSG:EP0 IN stalled at set conf in ep0 dsr\n");
1920                 }
1921                 break;
1922             
1923                 case USB_GET_CONFIGURATION:
1924                         /* GET CONFIGURATION request handler */
1925                         usbs_handle_get_configuration();
1926                         break;
1927                 case USB_MSC_GET_MAX_LUN:
1928                         usbs_handle_msc_get_maxlun();
1929                         break;
1930                 case USB_MSC_BOT_RESET:
1931                         
1932                 default:
1933                         /* Send STALL Handshake   */
1934                 usbs_endpoint_stall(EP0,IN);                    
1935                         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG:EP0 IN stalled in ep0 dsr\n");
1936                         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG:Setup Request Type 0x%02x,0x%02X\n",g_usb_setup_data[BMREQUESTTYPE],g_usb_setup_data[BREQUEST]);
1937                 break;
1938         }
1939         
1940         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: ep0 dsr\n");
1941 }
1942 /*=============================================================================
1943 // Endpoint 0 initialization.
1944 // Control Endpoint, bi-direction
1945 // This may get called during system start-up or following a reset
1946 // from the host.
1947 =============================================================================*/
1948 static void
1949 usbs_imx_otg_dev_ep0_init(void)
1950 {
1951         /*initialize Endpoint 0 Queue Header*/
1952         usbs_ep0_init_dqh();
1953
1954         {
1955                 /*fill the structure for ep0*/
1956                 if ((EP0_STATE_IDLE != ep0.ep_state) &&
1957        ((usbs_control_return (*)(usbs_control_endpoint*, int)) 0 != ep0.common.complete_fn)) 
1958     {
1959                 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
1960            (*ep0.common.complete_fn)(&ep0.common, -EPIPE);
1961                 #endif
1962     }
1963     ep0.common.state            = USBS_STATE_POWERED;
1964     memset(ep0.common.control_buffer, 0, 8);
1965     ep0.common.buffer           = (unsigned char*) 0;
1966     ep0.common.buffer_size      = 0;
1967     ep0.common.fill_buffer_fn   = (void (*)(usbs_control_endpoint*)) 0;
1968     ep0.common.fill_data        = (void*) 0;
1969     ep0.common.fill_index       = 0;
1970     ep0.common.complete_fn      = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;
1971     ep0.ep_state                = EP0_STATE_IDLE;
1972     ep0.length                  = 0;
1973     ep0.transmitted             = 0;
1974         }
1975 }
1976 // ----------------------------------------------------------------------------
1977 /*=============================================================================
1978 // The start function is called by higher-level code when things have
1979 // been set up, i.e. the enumeration data is available, appropriate
1980 // handlers have been installed for the different types of control
1981 // messages, and communication with the host is allowed to start. The
1982 // next event that should happen is a reset operation from the host,
1983 // so all other interrupts should be blocked. However it is likely
1984 // that the hardware will detect a suspend state before the reset
1985 // arrives, and hence the reset will act as a resume as well as a
1986 // reset.
1987 =============================================================================*/
1988 static void
1989 usbs_imx_otg_dev_ep0_start(usbs_control_endpoint* endpoint)
1990 {
1991         cyg_uint32 temp;
1992         
1993         CYG_ASSERT( endpoint == &ep0.common, "USB startup involves the wrong endpoint");
1994         
1995         /*clear all interrupt status bits*/
1996         temp = usbs_imx_otg_base->usbsts;
1997         usbs_imx_otg_base->usbsts = temp;               //clear all the previous interrupts
1998         
1999         /*enable all the sub-interrupt sources for USB device*/
2000         USBS_IMX_OTG_INTR_UNMASK(IMX_USB_INTR_DEV_PCE|IMX_USB_INTR_DEV_RESET|IMX_USB_INTR_DEV_USBINT);
2001         
2002         /*set Run/Stop bit to Run Mode*/
2003         usbs_imx_otg_base->usbcmd |= BIT0;      
2004
2005         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: mx37 ep0 start.\n");
2006 }
2007 // ****************************************************************************
2008 // -----------------------Endpoint 1 Functions---------------------------------
2009 // ****************************************************************************
2010 /*=============================================================================
2011 // Complete a transfer. This takes care of invoking the completion
2012 // callback and resetting the buffer.
2013 =============================================================================*/
2014 static void
2015 ep1_rx_complete(int result)
2016 {
2017         //cyg_uint32 total_bytes;
2018         cyg_uint32 dtd_address;
2019         cyg_uint32 dqh_address;
2020         cyg_uint32 received_buffer_addrs = 0x0;
2021         cyg_uint32 received_data_length = 0x0;
2022         cyg_uint32* temp = 0x0;    
2023
2024         int i;
2025         
2026         if(g_usb_dev_state != USB_DEV_CONFIGURED_STATE) 
2027                 return; //EP1 only receives data when the USB device has been configured
2028         
2029         if(ep1.common.buffer == NULL)
2030         {
2031                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: NULL buffer \n");
2032                 return; //there is not a buffer used to store the data from host
2033         }       
2034         
2035         /* Get Device Device Queue Head of the out endpoint */
2036         dqh_address = USBS_EP_GET_dQH(EP1,OUT);
2037         
2038         /* Get Device Transfer Descriptor of the out endpoint */
2039         dtd_address = USBS_EP_GET_dTD(EP1,OUT);
2040         
2041         /*clear the complete status */
2042         usbs_imx_otg_base->endptcomplete |= (EPOUT_COMPLETE << EP1);
2043
2044         //received_buffer_addrs = (*((unsigned int *)dtd_address + 2)) & 0xFFFFF000;
2045         received_buffer_addrs = (cyg_uint32)ep1.common.buffer;
2046         USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: received_buffer_addrs 0x%08X \n",received_buffer_addrs);
2047         if( received_buffer_addrs == 0)
2048         {
2049                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: NULL rx buffer \n");
2050                 return;
2051         }
2052                 
2053         /* calculate the received data length using number of bytes left in TD */
2054         temp =  (cyg_uint32 *)dtd_address;
2055         temp++;                 //pointer to total bytes in dtd, second work in dTD
2056         received_data_length = (ep1.common.buffer_size - (((*temp) >> 16 )&0x7FFF));    //recevied data length <= BULK_TD_BUFFER_TOTAL_SIZE
2057         USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: received length %d \n",received_data_length);
2058         #if 0
2059         /* Check if the received packet is SCSI WRITE, if yes, assign the TD buffer offset
2060            is zero, otherwise, one. This is a bug in MX37 USB OTG */
2061         if((received_data_length==31)&&(*(destination_ptr+0xF)==0x2A))//WRITE10 received
2062         {
2063                 g_bulk_out_transdesc_buffer_offset = 0;
2064                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_start_rx - set offset to zero \n");
2065         }
2066
2067         else if((g_bulk_out_sector_number_is_one == 1)&&(received_data_length!=31)) //last bulk out data sector
2068                 g_bulk_out_transdesc_buffer_offset = 1;
2069         #endif
2070         
2071         /* tell ep1 how many bytes data is received*/
2072         ep1.fetched     = received_data_length; 
2073         
2074         if(ep1.fetched) 
2075         {
2076                 if(ep1.fetched == 31)
2077                         g_received_data_type = MASS_STORAGE_CBW_TYPE;
2078                 else 
2079                         g_received_data_type = MASS_STORAGE_DATA_TYPE;
2080                 ep1.common.complete_data    = (void*)(ep1.common.buffer);
2081
2082                 #if 0
2083                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: \n");
2084                 USBDBGMSG(DEBUG_TRANS,"----Dump Bulk-Out Recevied Data----\n");
2085                 for(i=0;i<32;i++)
2086                 {
2087                         USBDBGMSG(DEBUG_TRANS,"%02X ", *((cyg_uint8 *)(ep1.common.complete_data)+i));
2088                 }
2089                 USBDBGMSG(DEBUG_TRANS,"\n");
2090                 #endif
2091                 //USB_IMX_SET_TD_OFFSET(g_td_buffer_offset, 0);
2092             ep1.common.buffer      = (unsigned char*) 0;
2093         ep1.common.buffer_size = 0;
2094                 ep1_start_rx((usbs_rx_endpoint *)(&(ep1.common))); //prevent to receive more CBW before processing done
2095         }
2096         
2097     #if 0
2098         if(ep1.fetched == 31)
2099         {
2100                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete - recevied data: \n");
2101                 for(i=0;i<32;i++)
2102                 {
2103                         USBDBGMSG(DEBUG_TRANS,"%02X ", *((cyg_uint8 *)(ep1.common.complete_data)+i));
2104                 }
2105                 USBDBGMSG(DEBUG_TRANS,"\n");
2106
2107                 for(i=0;i<32;i++)
2108                 {
2109                         USBDBGMSG(DEBUG_TRANS,"%02X ", *((cyg_uint8 *)received_buffer_addrs+i));
2110                 }
2111                 USBDBGMSG(DEBUG_TRANS,"\n");
2112         }
2113         #endif
2114         
2115         
2116 }
2117 /*=============================================================================
2118 // Start to receive data from host. This functionality is overloaded to cope with
2119 // waiting for stalls to complete.
2120 // The transfer descriptor is prepared 
2121 =============================================================================*/
2122 static void
2123 ep1_start_rx(usbs_rx_endpoint* endpoint)
2124 {
2125         struct dtd_t td;
2126         cyg_uint32 total_bytes;
2127         cyg_uint32 dtd_address;
2128         cyg_uint32 dqh_address;
2129     cyg_uint32 buffer_addrs_page0;
2130
2131         if(g_usb_dev_state != USB_DEV_CONFIGURED_STATE) 
2132                 return; //EP1 only receives data when the USB device has been configured
2133         #if 0   //don't check to prevent EP1 from receiving data before processing the previous.
2134         if(endpoint->buffer == NULL)
2135         {
2136                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_start_rx: NULL buffer \n");
2137                 return; //there is not a buffer used to store the data from host
2138         }
2139         #endif
2140         /* Get Device Device Queue Head of the out endpoint */
2141         dqh_address = USBS_EP_GET_dQH(EP1,OUT);
2142         
2143         /* Get Device Transfer Descriptor of the out endpoint */
2144         dtd_address = USBS_EP_GET_dTD(EP1,OUT);
2145
2146         /* ==Prepare TD for next bulk out transfer== */
2147         /* get the dTD buffer pointer */
2148         buffer_addrs_page0 = (cyg_uint32)(endpoint->buffer);
2149         
2150         /* Get the total bytes to be received   */
2151         total_bytes = endpoint->buffer_size;
2152         
2153         /* OUT setup dTD */
2154         td.dtd_base             = dtd_address;  
2155         td.next_link_ptr        = dtd_address + 0x20;
2156         td.terminate            = TERMINATE;
2157         td.total_bytes          = total_bytes;
2158         td.ioc                          = IOC_SET;
2159         td.status                       = ACTIVE;
2160         td.buffer_ptr0          = buffer_addrs_page0 ; 
2161         td.current_offset       = ( buffer_addrs_page0 & 0xFFF ) + g_td_buffer_offset; 
2162         td.buffer_ptr1          = 0;
2163         td.buffer_ptr2          = 0;
2164         td.buffer_ptr3          = 0;
2165         td.buffer_ptr4          = 0;
2166
2167         /* re-define the buffer page pointers based on the total_bytes*/
2168         if(total_bytes > BULK_TD_BUFFER_PAGE_SIZE)
2169                 td.buffer_ptr1          = (td.buffer_ptr0 + BULK_TD_BUFFER_PAGE_SIZE);
2170         if(total_bytes > BULK_TD_BUFFER_PAGE_SIZE*2)
2171                 td.buffer_ptr2          = (td.buffer_ptr1 + BULK_TD_BUFFER_PAGE_SIZE);
2172         if(total_bytes > BULK_TD_BUFFER_PAGE_SIZE*3)
2173                 td.buffer_ptr3          = (td.buffer_ptr2 + BULK_TD_BUFFER_PAGE_SIZE);
2174             
2175         /* Set the Transfer Descriptor  */
2176         usbs_setup_transdesc(&td);
2177
2178         /* 1. write dQH next ptr and dQH terminate bit to 0 */
2179         *(volatile cyg_uint32 *)(dqh_address+0x8)= dtd_address;
2180             
2181         /* 2. clear active & halt bit in dQH */
2182         *(volatile cyg_uint32 *)(dqh_address+0xC) &= ~0xFF;
2183
2184         /* 3. prime endpoint by writing '1' in ENDPTPRIME 
2185                 prime bulk out endpoint after sending the CSW of last command
2186         */
2187         //usbs_imx_otg_base->endptprime |= ( EPOUT_PRIME << EP1 );
2188
2189 }
2190 /*=============================================================================
2191 // The exported interface to halt the EP1
2192 =============================================================================*/
2193 static void
2194 ep1_set_halted(usbs_rx_endpoint* endpoint, cyg_bool new_value)
2195 {
2196         if (ep1.common.halted == new_value) {
2197         return;
2198     }
2199     if (new_value) {
2200         // The endpoint should be stalled. There is a potential race
2201         // condition here with the current transfer and DSR invocation.
2202         // Updating the stalled flag means that the DSR will do nothing.
2203                 usbs_endpoint_stall(EP1,OUT);
2204                 ep1.common.halted = 1;
2205     } 
2206         else {
2207         // Take care of the hardware so that a new transfer is allowed. 
2208         usbs_endpoint_unstall(EP1,OUT);
2209         ep1.common.halted = 0;
2210     }
2211
2212 }
2213 /*=============================================================================
2214 // The DSR is invoked following an interrupt. According to the docs an
2215 // endpoint 1 interrupt can only happen if the receive-packet-complete
2216 // bit is set.
2217 // [Note] EP1 DSR is only used to receive the command block wrapper from host
2218 // to USB mass storage device
2219 =============================================================================*/
2220
2221 static void
2222 usbs_imx_otg_dev_ep1_dsr(void)
2223 {
2224         int result = 0; //contains the actual recevied data length from bulk-out endpoint
2225         g_received_data_type = 0;//MASS_STORAGE_CBW_TYPE
2226         
2227         if(ep1.common.buffer)//buffer of TD is not null, then receive
2228         {
2229                 ep1_rx_complete(result);
2230         }
2231         //USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1 dsr - result = %d\n",result);
2232         //recevie mass storage device CBW
2233         
2234         if((ep1.fetched == 31)&&(g_received_data_type == MASS_STORAGE_CBW_TYPE))
2235         {
2236                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1 dsr - CBW received\n");
2237                 //post the semaphore of MSC command handler thread
2238                 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2239                 cyg_semaphore_post(&usbs_msc_sem);
2240                 #endif
2241                 ep1.fetched = 0;
2242         }
2243         else
2244                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1 dsr - received %d byte\n",ep1.fetched);
2245         
2246 }
2247
2248 /*=============================================================================
2249 // Endpoint 1 initialization.
2250 // Bulk-OUT Endpoint
2251 // This may get called during system start-up or following a reset
2252 // from the host.
2253 =============================================================================*/
2254 static void
2255 usbs_imx_otg_dev_ep1_init(void)
2256 {
2257         //at present, ep1.common.buffer is NULL. The buffer should be initialized 
2258         //by upper layer caller.
2259         /*buffer is assigned in MSC initialization*/
2260         
2261         // Endpoints should never be halted during a start-up.
2262     ep1.common.halted      = 0; //false =0, true =1
2263         ep1.common.complete_fn = ep1_rx_complete;
2264     // If there has been a reset and there was a receive in progress,
2265     // abort it. This also takes care of sorting out the endpoint
2266     // fields ready for the next rx.
2267     ep1_rx_complete(-EPIPE);
2268 }
2269
2270 // ****************************************************************************
2271 // -----------------------Endpoint 2 Functions---------------------------------
2272 // ****************************************************************************
2273 /*=============================================================================
2274 // A utility routine for completing a transfer. This takes care of the
2275 // callback as well as resetting the buffer.
2276 =============================================================================*/
2277 static void
2278 ep2_tx_complete(int result)
2279 {
2280     void (*complete_fn)(void*, int)  = ep2.common.complete_fn;
2281     void* complete_data = ep2.common.complete_data;
2282     
2283     ep2.common.buffer           = (unsigned char*) 0;
2284     ep2.common.buffer_size      = 0;
2285     ep2.common.complete_fn      = (void (*)(void*, int)) 0;
2286     ep2.common.complete_data    = (void*) 0;
2287
2288     if ((void (*)(void*, int))0 != complete_fn) {
2289         (*complete_fn)(complete_data, result);
2290     }
2291 }
2292
2293 /*=============================================================================
2294 // The exported interface to start to transmit data to Host
2295 =============================================================================*/
2296 static void
2297 ep2_start_tx(usbs_tx_endpoint* endpoint)
2298 {
2299         int timeout = 400;
2300         struct dtd_t td;
2301     cyg_uint32 total_bytes ;
2302     cyg_uint32 dtd_address,dqh_address;
2303     cyg_uint32 buffer_addrs_page0;
2304     cyg_uint32 size = 0x0;
2305
2306         /* Get Device Transfer Descriptor of the requested endpoint */
2307         dtd_address = USBS_EP_GET_dTD(EP2,IN);
2308     
2309         /* Get Device Queue head of the requested endpoint */
2310         dqh_address = USBS_EP_GET_dQH(EP2,IN);  
2311         
2312         /* allocate memory for data transfer */
2313         buffer_addrs_page0 = endpoint->buffer;
2314
2315         if(buffer_addrs_page0 == 0)
2316         {
2317                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep2_start_tx: NULL tx buffer \n");
2318                 return;
2319         }
2320
2321         total_bytes = (cyg_uint32)(endpoint->buffer_size);
2322         size = (total_bytes < BULK_TD_BUFFER_TOTAL_SIZE )?total_bytes:(BULK_TD_BUFFER_TOTAL_SIZE);
2323             
2324         td.dtd_base             = dtd_address; 
2325         td.next_link_ptr        = dtd_address + 0x20 ;
2326         td.terminate            = TERMINATE;
2327         td.total_bytes          = size;
2328         td.ioc                          = IOC_SET;
2329         td.status                       = ACTIVE;
2330         td.buffer_ptr0          = buffer_addrs_page0 ;
2331         td.current_offset       = (buffer_addrs_page0 & 0xFFF)+ g_td_buffer_offset; 
2332         td.buffer_ptr1          = 0;
2333         td.buffer_ptr2          = 0;
2334         td.buffer_ptr3          = 0;
2335         td.buffer_ptr4          = 0;
2336
2337         /* re-define the buffer page pointers based on the total_bytes*/
2338         if(size > BULK_TD_BUFFER_PAGE_SIZE)
2339                 td.buffer_ptr1          = (td.buffer_ptr0 + BULK_TD_BUFFER_PAGE_SIZE);
2340         if(size > BULK_TD_BUFFER_PAGE_SIZE*2)
2341                 td.buffer_ptr2          = (td.buffer_ptr1 + BULK_TD_BUFFER_PAGE_SIZE);
2342         if(size > BULK_TD_BUFFER_PAGE_SIZE*3)
2343                 td.buffer_ptr3          = (td.buffer_ptr2 + BULK_TD_BUFFER_PAGE_SIZE);
2344
2345         /* Set the Transfer Descriptor  */ 
2346         usbs_setup_transdesc(&td);
2347
2348         /* 1. write dQH next ptr and dQH terminate bit to 0  */
2349         *(volatile cyg_uint32 *)(dqh_address+0x8)= (dtd_address); 
2350         
2351         /* 2. clear active & halt bit in dQH */
2352         *(volatile cyg_uint32 *)(dqh_address+0xC) &= ~0xFF;
2353
2354         /* 3. prime endpoint by writing '1' in ENDPTPRIME */
2355         usbs_imx_otg_base->endptprime = ( EPIN_PRIME << EP2 );
2356         
2357         /* wait for complete set and clear */
2358         while (!((usbs_imx_otg_base->endptcomplete) & (EPIN_COMPLETE<<EP2)));
2359         
2360         usbs_imx_otg_base->endptcomplete |= (EPIN_COMPLETE << EP2);
2361
2362         ep2.transmitted = size;
2363
2364         ep2_tx_complete(-EPIPE);
2365         
2366         USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep2 tx done\n");// ep2.transmitted);
2367         
2368 }
2369 /*=============================================================================
2370 // The exported interface to halt the EP2
2371 =============================================================================*/
2372 static void
2373 ep2_set_halted(usbs_tx_endpoint* endpoint, cyg_bool new_value)
2374 {
2375         if (ep2.common.halted == new_value) {
2376         return;
2377     }
2378     if (new_value) {
2379         // The endpoint should be stalled. There is a potential race
2380         // condition here with the current transfer and DSR invocation.
2381         // Updating the stalled flag means that the DSR will do nothing.
2382                 usbs_endpoint_stall(EP2,IN);
2383                 ep2.common.halted = 1;
2384     } 
2385         else {
2386         // Take care of the hardware so that a new transfer is allowed. 
2387         usbs_endpoint_unstall(EP2,IN);
2388         ep2.common.halted = 0;
2389     }
2390 }
2391 /*=============================================================================
2392 // The dsr will be invoked when the transmit-packet-complete bit is
2393 // set. Typically this happens when a packet has been completed
2394 =============================================================================*/
2395
2396 static void
2397 usbs_imx_otg_dev_ep2_dsr(void)
2398 {
2399         USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep2 dsr\n");
2400         /* EP2 DSR will be called as soon as a transfer complete to clear status*/
2401         usbs_imx_otg_base->endptcomplete |= (EPIN_COMPLETE << EP2);
2402
2403         
2404         if(ep2.common.buffer_size==0)
2405         {
2406                 ep2_tx_complete(-EPIPE);
2407                 ep2.transmitted = 0;    //clear the field to wait for the next transmit
2408         }
2409         
2410 }
2411
2412 /*=============================================================================
2413 // Endpoint 2 initialization.
2414 // Bulk-IN Endpoint
2415 // This may be called during system start-up or following a reset
2416 // from the host.
2417 =============================================================================*/
2418 static void
2419 usbs_imx_otg_dev_ep2_init(void)
2420 {
2421         //at initialization, ep2.common.buffer is NULL. The buffer should be initialized 
2422         //by upper layer caller.
2423
2424         // Endpoints should never be halted after a reset
2425     ep2.common.halted   = false;
2426
2427     // If there has been a reset and there was a receive in progress,
2428     // abort it. This also takes care of clearing the endpoint
2429     // structure fields.
2430     ep2_tx_complete(-EPIPE);
2431 }
2432
2433 // ****************************************************************************
2434 // -----------------------MX37 USB Device Driver API Functions-----------------
2435 // ****************************************************************************
2436
2437 /*=============================================================================
2438 // The DSR. This can be invoked directly by poll(), or via the usual
2439 // interrupt subsystem. It acts as per the current value of
2440 // g_isr_status_bits. If another interrupt goes off while this
2441 // DSR is running, there will be another invocation of the DSR and
2442 // the status bits will be updated.
2443 =============================================================================*/
2444 static void
2445 usbs_imx_otg_dev_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
2446 {
2447     int status = 0;
2448     cyg_uint32 temp;
2449     CYG_ASSERT(MX51_IRQ_USB_SERVICE_REQUEST == vector, "USB DSR should only be invoked for USB interrupts" );
2450     CYG_ASSERT(0 == data, "The i.MX37 USB DSR needs no global data pointer");
2451         //USBDBGMSG("+USBDBGMSG: enter mx37 dsr\n");
2452     // There is no atomic swap support, so interrupts have to be
2453     // blocked. It might be possible to do this via the USBS_CONTROL
2454     // register, but at the risk of messing up the status register
2455     // if another interrupt comes in. Blocking interrupts at the
2456     // processor level is less intrusive on the USB code.
2457     //cyg_drv_isr_lock();
2458     status = g_isr_status_bits;
2459     g_isr_status_bits = 0;
2460     //cyg_drv_isr_unlock();
2461                 
2462     // Reset is special, since it invalidates everything else.
2463     // If the reset is still ongoing then do not attempt any
2464     // further processing, there will just be another interrupt.
2465     // Otherwise handle_reset() does the hard work. Unmasking
2466     // the interrupt means that another interrupt will occur
2467     // immediately if reset is still asserted, i.e. no threads
2468     // will run, but there is no easy way of triggering action
2469     // at the end of reset.
2470     if (status & IMX_USB_STS_RESET) 
2471     {
2472         int new_status = usbs_imx_otg_base->usbsts; 
2473         if (0 == (new_status & IMX_USB_STS_RESET)) 
2474         {
2475                         usbs_imx_otg_dev_handle_bus_reset();
2476                         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: !!USB BUS RESET\n");
2477         } 
2478                 
2479         // This unmask is likely to cause another interrupt immediately
2480         #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2481         cyg_interrupt_unmask(MX51_IRQ_USB_SERVICE_REQUEST);
2482                 #endif
2483     } 
2484         else if(status & IMX_USB_STS_USBINT)
2485         {
2486                 
2487                 if(usbs_imx_otg_base->endptsetupstat & BIT0)
2488         {// if Setup Packet arrived                     
2489                 usbs_imx_otg_dev_ep0_dsr();
2490         }
2491
2492                 else if((usbs_imx_otg_base->endptcomplete) & ( EPIN_COMPLETE << EP2))   
2493         {//     EP2 Queue Header buffer completes sending data
2494                 //complete bit is cleared in ep2_start_tx
2495         }
2496                 
2497                 
2498                 else if((usbs_imx_otg_base->endptcomplete) & ( EPOUT_COMPLETE << EP1))
2499         {// EP1 Queue Header buffer get data            
2500                         usbs_imx_otg_dev_ep1_dsr();
2501                         
2502         }
2503
2504                 else if((usbs_imx_otg_base->endptcomplete) & ( EPOUT_COMPLETE << EP0))
2505                 {
2506                         //usbs_imx_otg_dev_ep0_dsr();
2507                         usbs_imx_otg_base->endptcomplete = ( EPOUT_COMPLETE << EP0);
2508                 }
2509         else
2510         {//do nothing, only for constructure integrity
2511                         temp = usbs_imx_otg_base->endptcomplete;
2512                         usbs_imx_otg_base->endptcomplete = temp;
2513                         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: usbsts int - unknown.\n");
2514                 }
2515
2516                 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2517                 // This unmask is likely to cause another interrupt immediately
2518                 cyg_interrupt_unmask(MX51_IRQ_USB_SERVICE_REQUEST);
2519                 #endif
2520         }
2521     else 
2522     {
2523         #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2524                 // This unmask is likely to cause another interrupt immediately
2525         cyg_interrupt_unmask(MX51_IRQ_USB_SERVICE_REQUEST);
2526                 #endif
2527     }   
2528
2529                 
2530 }
2531 /*=============================================================================
2532 // The DSR thread
2533 =============================================================================*/
2534 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2535 #define CYGNUM_DEVS_USB_OTG_DEV_THREAD_STACK_SIZE       1024
2536 #define CYGNUM_DEVS_USB_OTG_DEV_THREAD_PRIORITY 29
2537 static unsigned char usbs_imx_otg_dev_thread_stack[CYGNUM_DEVS_USB_OTG_DEV_THREAD_STACK_SIZE];
2538 static cyg_thread    usbs_imx_otg_dev_thread;
2539 static cyg_handle_t  usbs_imx_otg_dev_thread_handle;
2540 static cyg_sem_t     usbs_imx_otg_dev_sem;
2541
2542
2543 static void
2544 usbs_imx_otg_dev_thread_fn(cyg_addrword_t param)
2545 {
2546         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: usb driver thread\n");
2547         for (;;) {
2548         cyg_semaphore_wait(&usbs_imx_otg_dev_sem);
2549                 usbs_imx_otg_dev_dsr(IMX_IRQ_USB_DEV_SERVICE_REQUEST, 0, 0);
2550     }
2551     CYG_UNUSED_PARAM(cyg_addrword_t, param);
2552 }
2553
2554 static void
2555 usbs_imx_otg_dev_thread_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
2556 {
2557     CYG_ASSERT( 0 != isr_status_bits, "DSR's should only be scheduled when there is work to do");
2558     cyg_semaphore_post(&usbs_imx_otg_dev_sem);
2559
2560         
2561     CYG_UNUSED_PARAM(cyg_vector_t, vector);
2562     CYG_UNUSED_PARAM(cyg_ucount32, count);
2563     CYG_UNUSED_PARAM(cyg_addrword_t, data);
2564 }
2565 #endif
2566 /*=============================================================================
2567 // The interrupt handler. This does as little as possible.
2568 =============================================================================*/
2569 static cyg_uint32
2570 usbs_imx_otg_dev_isr(cyg_vector_t vector, cyg_addrword_t data)
2571 {
2572         cyg_uint32 old_status_bits = g_isr_status_bits;
2573         cyg_uint32 status_bits;
2574
2575     CYG_ASSERT(IMX_IRQ_USB_DEV_SERVICE_REQUEST == vector, "USB ISR should only be invoked for USB interrupts" );
2576     CYG_ASSERT(0 == data, "The MX51 USB ISR needs no global data pointer" );
2577
2578         //USBDBGMSG("+USBDBGMSG: enter mx51 isr\n");
2579     // Read the current status. Reset is special, it means that the
2580     // whole chip has been reset apart from the one bit in the status
2581     // register. Nothing should be done about this until the DSR sets
2582     // the endpoints back to a consistent state and re-enables
2583     // interrupts in the control register.
2584     status_bits         = usbs_imx_otg_base->usbsts;
2585         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: usb intr 0x%08X\n",status_bits);
2586     if (status_bits & IMX_USB_STS_RESET) 
2587     {
2588         
2589         g_isr_status_bits |= IMX_USB_STS_RESET;
2590         usbs_imx_otg_base->usbsts |= IMX_USB_STS_RESET;
2591         cyg_interrupt_mask(IMX_IRQ_USB_DEV_SERVICE_REQUEST);
2592     } 
2593         else if(status_bits & IMX_USB_STS_USBINT)
2594         {
2595                 g_isr_status_bits |= IMX_USB_STS_USBINT;
2596         usbs_imx_otg_base->usbsts |= IMX_USB_STS_USBINT;
2597         cyg_interrupt_mask(IMX_IRQ_USB_DEV_SERVICE_REQUEST);
2598         }
2599     else 
2600     {
2601         usbs_imx_otg_base->usbsts  = status_bits;       //clear the status bit of USBSTS
2602         g_isr_status_bits &= ~status_bits;
2603         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: unknown usb intr\n");
2604         }
2605
2606     // Now keep the rest of the system happy.
2607     cyg_interrupt_acknowledge(vector);                  //reenable the USB interrupt
2608     return (old_status_bits != g_isr_status_bits) ? CYG_ISR_CALL_DSR : CYG_ISR_HANDLED;
2609 }
2610 /*=============================================================================
2611 // Polling support. This acts mostly like the interrupt handler: it
2612 // sets the isr status bits and causes the dsr to run. Reset has to be
2613 // handled specially: polling does nothing as long as reset is asserted.
2614 =============================================================================*/
2615 static void
2616 usbs_imx_otg_dev_poll(usbs_control_endpoint* endpoint)
2617 {
2618         CYG_ASSERT( endpoint == &ep0.common, "USB poll involves the wrong endpoint");
2619     
2620     if (g_isr_status_bits & IMX_USB_STS_RESET) 
2621     {
2622         // Reset was detected the last time poll() was invoked. If
2623         // reset is still active, do nothing. Once the reset has
2624         // completed things can continue.
2625         if (0 == (IMX_USB_STS_RESET & usbs_imx_otg_base->usbsts)) 
2626         {
2627             g_isr_status_bits = 0;
2628             usbs_imx_otg_dev_handle_bus_reset();
2629         }
2630     } 
2631     else 
2632     {
2633         g_isr_status_bits = usbs_imx_otg_base->usbsts;
2634         if (IMX_USB_STS_PTCHANGE & g_isr_status_bits) 
2635         {
2636             //process Port Change Detect
2637             usbs_imx_otg_dev_handle_port_change();
2638         } 
2639         else if (IMX_USB_STS_USBINT & g_isr_status_bits)
2640         {
2641             usbs_imx_otg_dev_dsr(IMX_IRQ_USB_DEV_SERVICE_REQUEST, 0, (cyg_addrword_t) 0);
2642         }
2643         else
2644         {
2645                 usbs_imx_otg_base->usbsts = g_isr_status_bits;  //clear the don't-care status
2646         }
2647     }
2648 }
2649 /*=============================================================================
2650 // Perform reset operations on all endpoints that have been
2651 // configured in. It is convenient to keep this in a separate
2652 // routine to allow for polling, where manipulating the
2653 // interrupt controller mask is a bad idea.
2654 =============================================================================*/
2655 static void
2656 usbs_imx_otg_dev_handle_bus_reset(void)
2657 {
2658         cyg_uint32 temp;
2659         
2660         usbs_imx_otg_base->usbcmd &= ~BIT0; //detach device from bus temprorarily
2661         usbs_imx_otg_base->usbsts |= BIT6;      //clear reset bit in USBSTS
2662
2663         //temp = usbs_imx_otg_base->usbsts;
2664         //usbs_imx_otg_base->usbsts = temp;
2665   
2666         /*1. Reading and writing back the ENDPTSETUPSTAT register
2667       clears the setup token semaphores */
2668         temp = usbs_imx_otg_base->endptsetupstat;
2669         usbs_imx_otg_base->endptsetupstat = temp;
2670
2671         /*2. Reading and writing back the ENDPTCOMPLETE register
2672       clears the endpoint complete status bits */
2673         temp = usbs_imx_otg_base->endptcomplete;
2674         usbs_imx_otg_base->endptcomplete = temp;
2675         
2676         /*3. Cancel all primed status by waiting until all bits in ENDPTPRIME are 0
2677        and then write 0xFFFFFFFF to ENDPTFLUSH */
2678         while(usbs_imx_otg_base->endptprime);   
2679         usbs_imx_otg_base->endptflush = 0xFFFFFFFF;     
2680
2681
2682         /*4. Initialize EP0 Queue Head again*/
2683         usbs_ep0_init_dqh();
2684         
2685         usbs_imx_otg_base->endptlistaddr = g_bulkbuffer_map.ep_dqh_base_addrs; 
2686      
2687         usbs_imx_otg_base->usbcmd |= BIT0; //re-attach device to the bus
2688
2689         g_usb_dev_state = USB_DEV_DEFAULT_STATE;
2690
2691         
2692 }
2693 /*=============================================================================
2694 // Perform port change operations on all endpoints that have been
2695 // configured in. It is convenient to keep this in a separate
2696 // routine to allow for polling, where manipulating the
2697 // interrupt controller mask is a bad idea.
2698 =============================================================================*/
2699 static void
2700 usbs_imx_otg_dev_handle_port_change(void)
2701 {
2702         /*Port Change happens when USB device enters/exits FS or HS mode
2703         When exiting from FS or HS due to Bus reset or DCSuspend, the notification
2704         mechanisms are Reset Received and DCSuspend.
2705         This function only processes the port change on entering FS or HS
2706         Don't enable Port Change Detect interrupt, it's no sense for operation.*/
2707         usbs_imx_otg_base->usbsts |= IMX_USB_STS_PTCHANGE;      //clear Port change status
2708
2709 }
2710
2711 // ****************************************************************************
2712 // ----------------------------------------------------------------------------
2713 // ****************************************************************************
2714 /*=============================================================================
2715 FUNCTION: usbs_imx_otg_dev_set_configuration
2716 DESCRIPTION:            This function Handle the SET CONFIGRATION Request.
2717 ARGUMENTS PASSED:       usb_end_pt_info_t* config_data;
2718 RETURN VALUE:           None    
2719 IMPORTANT NOTES:        None            
2720 =============================================================================*/
2721 static void
2722 usbs_imx_otg_dev_set_configuration(usb_end_pt_info_t* config_data)
2723 {
2724     struct dtd_t td;
2725     cyg_uint32 total_bytes = 0x0;
2726     cyg_uint32 buffer_addrs_page0 = 0;
2727     cyg_uint32 dqh_address = 0;
2728     cyg_uint32 dtd_address = 0;
2729     cyg_uint8  endpt_num,direction;
2730     
2731     struct dqh_t qhead;
2732
2733         
2734     /* get endpoint number to be configured and its direction */
2735     endpt_num= config_data->end_pt_no; 
2736     direction= config_data->direction;
2737     USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: set config - ep%d\n",endpt_num);
2738     /* Check if the endpoint number and direction is withing the permitted range or not */
2739     if (( endpt_num != EP0 ) && (endpt_num <= ( g_max_ep_supported - 1)) && 
2740                     ( direction == OUT || direction == IN))
2741     {
2742                 /* get the device q head and deice TD */
2743                 dqh_address = USBS_EP_GET_dQH(endpt_num,direction); 
2744                 dtd_address = USBS_EP_GET_dTD(endpt_num,direction);
2745
2746                 if ( direction ==  OUT )
2747                 {
2748                 total_bytes = BULK_BUFFER_SIZE ;
2749                 
2750                 qhead.dqh_base          = dqh_address;
2751                 qhead.zlt                       = ZLT_DISABLE;
2752                 qhead.mps                       = config_data->max_pkt_size;
2753                 qhead.ios                       = IOS_SET;
2754                 qhead.next_link_ptr     = dtd_address ;
2755                 qhead.terminate         = TERMINATE;
2756                 qhead.total_bytes       = total_bytes;
2757                 qhead.ioc                       = IOC_SET;
2758                 qhead.status            = NO_STATUS;
2759                 qhead.buffer_ptr0       = 0;
2760                 qhead.current_offset= 0;
2761                 qhead.buffer_ptr1       = 0;
2762                 qhead.buffer_ptr2       = 0;
2763                 qhead.buffer_ptr3       = 0;
2764                 qhead.buffer_ptr4       = 0;
2765
2766                 usbs_setup_queuehead(&qhead);
2767                 
2768                 /* Endpoint 1 : MPS = 64, OUT (Rx endpoint) */
2769                 usbs_imx_otg_base->endptctrl[endpt_num] = 0x00080048;
2770                 /* Enable EP1 OUT */
2771                 usbs_imx_otg_base->endptctrl[endpt_num] |= EPOUT_ENABLE;
2772                 
2773                 /* allocate buffer for receiving data */
2774                 /* free the usb buffer after re-enumeration*/
2775                 //g_bulkbuffer_map.buffer1_status = BUFFER_FREE;
2776                 //g_bulkbuffer_map.buffer2_status = BUFFER_FREE;
2777                 g_bulkbuffer_a.stat = BUFFER_FREED;
2778                 g_bulkbuffer_b.stat = BUFFER_FREED;     
2779                 
2780             //buffer_addrs_page0 = util_alloc_buffer();
2781             ep1.common.buffer      = g_bulkbuffer_a.buffer;
2782                 ep1.common.buffer_size = total_bytes;
2783                 g_bulkbuffer_a.stat = BUFFER_ALLOCATED;
2784                 buffer_addrs_page0 = (cyg_uint32)(ep1.common.buffer);
2785                 
2786                 
2787                 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: set config - ep1 dtd buffer 0x%08X\n",buffer_addrs_page0);
2788                 
2789                 /* OUT setup dTD */
2790                 td.dtd_base                     = dtd_address;
2791                 td.next_link_ptr        = dtd_address + 0x20;
2792                 td.terminate            = TERMINATE;
2793                 td.total_bytes          = total_bytes;
2794                 td.ioc                          = IOC_SET;
2795                 td.status                       = ACTIVE;
2796                 td.buffer_ptr0          = buffer_addrs_page0;
2797                 td.current_offset       = (buffer_addrs_page0 & 0xFFF) + g_td_buffer_offset;
2798                 td.buffer_ptr1          = 0x0;
2799                 td.buffer_ptr2          = 0x0;
2800                 td.buffer_ptr3          = 0x0;
2801                 td.buffer_ptr4          = 0x0;
2802             
2803                 /* Set the Transfer Descriptor  */
2804                 usbs_setup_transdesc(&td);
2805
2806                 /* 1. write dQH next ptr and dQH terminate bit to 0 */
2807                 *(volatile cyg_uint32*)(dqh_address+0x8)= dtd_address; 
2808             
2809                 /* 2. clear active & halt bit in dQH */
2810                 *(volatile cyg_uint32*)(dqh_address+0xC) &= ~0xFF;
2811         
2812                 /* 3. prime endpoint by writing '1' in ENDPTPRIME */
2813                 usbs_imx_otg_base->endptprime |= (  EPOUT_PRIME << endpt_num );
2814                 /* Endpoint Configured for output */
2815                 g_out_endpoint= endpt_num;
2816
2817                 
2818             }
2819
2820                 else
2821                 {
2822                 total_bytes = 0x4 ;
2823                 
2824                 qhead.dqh_base          = USBS_EP_GET_dQH(endpt_num,direction);
2825                 qhead.zlt                       = ZLT_DISABLE;
2826                 qhead.mps                       = config_data->max_pkt_size;
2827                 qhead.ios                       = IOS_SET;
2828                 qhead.next_link_ptr     = USBS_EP_GET_dQH(endpt_num,direction);
2829                 qhead.terminate         = TERMINATE;
2830                 qhead.total_bytes       = total_bytes;
2831                 qhead.ioc                       = IOC_SET;
2832                 qhead.status            = NO_STATUS;
2833                 qhead.buffer_ptr0       = 0;
2834                 qhead.current_offset= 0;
2835                 qhead.buffer_ptr1       = 0;
2836                 qhead.buffer_ptr2       = 0;
2837                 qhead.buffer_ptr3       = 0;
2838                 qhead.buffer_ptr4       = 0;
2839
2840                 usbs_setup_queuehead(&qhead);
2841                     
2842                 /* Endpoint Configured for Input */
2843                 g_in_endpoint= endpt_num;
2844     
2845                 /* Endpoint 2: MPS = 64, IN (Tx endpoint) */
2846                 usbs_imx_otg_base->endptctrl[endpt_num] = 0x00480008;
2847
2848                 /* Enable EP2 IN */
2849                 usbs_imx_otg_base->endptctrl[endpt_num] |= EPIN_ENABLE;
2850     
2851                 /* 3. prime endpoint by writing '1' in ENDPTPRIME */
2852                 usbs_imx_otg_base->endptprime |= (EPIN_PRIME << g_in_endpoint);
2853                 
2854             }
2855     }
2856     else 
2857     {
2858         /* TODO: error handling TBD */
2859     }    
2860
2861 }
2862
2863 static void usbs_imx_otg_config_utmi_clock(void)
2864 {
2865         #if defined(CYGHWR_USB_DEVS_MX37_OTG)
2866         USB_MX37_SET_PHY_CLK_24MHZ();
2867         #endif
2868
2869         #if defined(CYGHWR_USB_DEVS_MX51_OTG)
2870         cyg_uint32 temp;
2871         /*Configure USB_PHYCLOCK_ROOT source as 24MHz OSC*/ 
2872         CCM_CSCMR1_REGVAL = CCM_CSCMR1_REGVAL & (~CSCMR1_USBOH3_PHY_CLK_SEL_VALUE); //configure USB CRM
2873         /*Configure plldivvalue of USB_PHY_CTRL_1_REG for 24 Mhz*/         
2874         temp  = *(volatile cyg_uint32 *)USB_PHY_CTRL_1_REG;        
2875         temp &= ~USB_PHY_CTRL_PLLDIVVALUE_MASK;        
2876         temp |= USB_PHY_CTRL_PLLDIVVALUE_24_MHZ;                
2877         *(volatile cyg_uint32 *)USB_PHY_CTRL_1_REG = temp;
2878         #endif
2879 }
2880
2881 /*=============================================================================
2882 // The USB OTG hardware relevant initialization.
2883 =============================================================================*/
2884 static void
2885 usbs_imx_otg_hardware_init(void)
2886 {
2887         cyg_uint32 temp;
2888         cyg_uint32 timeout = 0x1D0000;
2889         usb_plat_config_data_t config_data_ptr; 
2890         cyg_uint8 i;
2891         
2892         /*Enable USB Internal PHY Clock as 24MHz on-board Ocsillator*/
2893         usbs_imx_otg_config_utmi_clock();
2894         
2895         {/*Setup USB Buffer Map*/
2896     config_data_ptr.buffer_address = (cyg_uint32)usb_buffer;
2897     config_data_ptr.buffer_size  = BUFFER_SIZE;
2898     
2899     /* Base address of the buffer allocated to IP Layer */
2900     g_bulkbuffer_address_base =  config_data_ptr.buffer_address;
2901     
2902     /* length of the buffer */
2903     g_bulkbuffer_length = config_data_ptr.buffer_size;   
2904     
2905     /* Maximum Number of EPs to be confiured */
2906     g_max_ep_supported = (( g_bulkbuffer_length - TOTAL_DATA_BUFFER_SIZE)/(BUFFER_USED_PER_EP)); //=(2048-1088)/256~=3.75->3
2907     
2908     /* Base of queue Head Pointer */
2909     g_bulkbuffer_map.ep_dqh_base_addrs = g_bulkbuffer_address_base; 
2910     
2911     /* Total size of qhead */
2912     temp = (SIZE_OF_QHD * (g_max_ep_supported * 2));    //total size of QH is 384byte
2913
2914     /* Base Address of dTDs */
2915     g_bulkbuffer_map.ep_dtd_base_addrs = (g_bulkbuffer_map.ep_dqh_base_addrs + temp);
2916   
2917     /* Total size of transfer descriptor */ 
2918     temp =  ((dTD_SIZE_EPIN * g_max_ep_supported) + (dTD_SIZE_EPOUT * g_max_ep_supported )); //total size of TD is 384 byte
2919     
2920     /* Base Address of EP0 Buffer */
2921     g_bulkbuffer_map.ep0_buffer_addrs = (g_bulkbuffer_map.ep_dtd_base_addrs + temp  );  //256byte
2922     
2923     /*Bulk Buffer Areas, 512byte per buffer*/
2924         /*Actually, the dual 512 byte bulk buffers are not used, because two larger 16kB bulk buffers are used*/
2925     /* transfer buffer 1 */     
2926     g_bulkbuffer_map.buffer1_address=(g_bulkbuffer_address_base + g_bulkbuffer_length -(BULK_BUFFER_SIZE*NUM_OF_BULK_BUFFER));
2927     g_bulkbuffer_map.buffer1_status  = BUFFER_FREE;
2928
2929     /* transfer buffer 2 */
2930     g_bulkbuffer_map.buffer2_address = g_bulkbuffer_map.buffer1_address + BULK_BUFFER_SIZE;
2931     g_bulkbuffer_map.buffer2_status  = BUFFER_FREE;
2932         }
2933         
2934         {/*Set USB OTG at device only mode*/
2935                 usbs_imx_otg_base->usbmode = 0x2;                                       //set OTG as a device controller
2936                 temp = 0xA5A55A5A;
2937                 while (!(usbs_imx_otg_base->usbmode == 0x2))
2938                 {
2939                         if(temp != (usbs_imx_otg_base->usbmode))
2940                         {
2941                                 temp = (usbs_imx_otg_base->usbmode);
2942                                 USBDBGMSG(DEBUG_BASIC,"usbmode is 0x%08X\n",temp);
2943                         }
2944                         timeout--;
2945                         if(timeout==0) break;
2946                 }               //check that device controller was configured to device mode only
2947         }
2948
2949         {
2950                 usbs_imx_otg_base->endptlistaddr = g_bulkbuffer_map.ep_dqh_base_addrs; // Configure ENDPOINTLISTADDR Pointer
2951                 usbs_imx_otg_base->otgsc |= BIT3;                                       // Set OTG termination, controls the pulldown on DM
2952                 usbs_imx_otg_base->endptnak = 0x00010001;                       // Enable Endpoint NAK
2953                 usbs_imx_otg_base->usbmode |= BIT3;                             // Disable Setup Lockout by writing '1' to SLOM in USBMODE
2954                 //usbs_imx_otg_base->usbcmd |= BIT0;                            // Set Run/Stop bit to Run Mode, make USB run in usbs_imx_otg_dev_ep0_start()
2955         }
2956         
2957         {
2958                 /* set it to be utmi interface */
2959                 temp  = usbs_imx_otg_base->portsc1;
2960                 temp &= ~USB_OTG_TRANS_MASK;
2961                 temp |= USB_OTG_TRANS_UTMI;
2962                 temp &= ~USB_OTG_FS_ONLY;                                                               //enable high speed
2963                 temp |= USB_OTG_TRANS_WIDTH;
2964
2965                 usbs_imx_otg_base->portsc1 = temp;
2966         }
2967
2968         {// The USB OTG transaction relevant initialization.
2969                 /* Select the common descriptors , these descriptor are independent of speed and security mode */ 
2970                 g_usb_desc.device_desc  = &g_usb_device_desc ;
2971                 g_usb_desc.config_desc  = &g_usb_config_desc;
2972                 g_usb_desc.sn_desc              = &g_usb_serialnumber_desc;
2973                 g_usb_desc.str_desc0    = &g_usb_otg_str0_desc;         //language desc
2974                 g_usb_desc.str_desc1    = &g_usb_otg_string_desc1;      //Manufacturer desc
2975                 g_usb_desc.str_desc2    = &g_usb_otg_string_desc2;      //USB Name Desc
2976                 g_usb_desc.str_desc3    = &g_usb_otg_string_desc3;      //Device Name Desc
2977         
2978                 /* Get Number of Endpoints supported from Configuration Descriptor*/
2979                 g_number_of_endpoints = g_usb_desc.config_desc->usb_interface_desc.number_endpoints;
2980    
2981                 /* Store the Endpoint specific information in local variable structure to this Layer */
2982                 for ( i = 0 ; i< g_number_of_endpoints ; i++)
2983                 {
2984                         g_end_pt_info[i].end_pt_no = ((g_usb_desc.config_desc->usb_endpoint_desc[i].endpoint) & ENDPT_NUMBER_MASK);
2985                         g_end_pt_info[i].direction = (((g_usb_desc.config_desc->usb_endpoint_desc[i].endpoint) & ENDPT_DIR_MASK )>>ENDPT_DIR_SHIFT);
2986                         g_end_pt_info[i].transfer_type = (g_usb_desc.config_desc->usb_endpoint_desc[i].attributes & ENDPT_TRNS_TYPE_MASK);
2987                         g_end_pt_info[i].max_pkt_size = ((g_usb_desc.config_desc->usb_endpoint_desc[i].max_packet_lo)   \
2988                                                                                 | (( g_usb_desc.config_desc->usb_endpoint_desc[i].max_packet_hi ) << 8 ));
2989                 }
2990         
2991                 g_usb_dev_state = USB_DEV_DEFAULT_STATE;
2992         }
2993 }
2994 // ****************************************************************************
2995 // ----------------------------------------------------------------------------
2996 // ****************************************************************************
2997 /*=============================================================================
2998 // Initialization i.MX37(Marley) USB OTG Hardware
2999 // This function is the only extern function of this device driver, and it 
3000 // registers the driver ISR and DSRs to the kernel. 
3001 =============================================================================*/
3002 void
3003 usbs_imx_otg_device_init(void)  //works like usb port open when 
3004 {       
3005         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: USB Device Driver Start Initializing...\n");
3006         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: USB OTG REG BASE@0x%08X\n",USB_BASE_ADDRESS);
3007         g_usb_setup_data = ep0.common.control_buffer;
3008         
3009         g_td_buffer_offset = 0;
3010         #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
3011         USB_IMX_SET_TD_OFFSET(g_td_buffer_offset,1);
3012         #endif
3013
3014         /*ping-pang buffer A*/
3015         g_bulkbuffer_a.buffer = bulk_buffer;
3016         g_bulkbuffer_a.stat   = BUFFER_FREED;
3017         
3018         /*ping-pang buffer B*/
3019         g_bulkbuffer_b.buffer = bulk_buffer + BULK_TD_BUFFER_TOTAL_SIZE;
3020         g_bulkbuffer_b.stat   = BUFFER_FREED;
3021         
3022         usbs_imx_otg_hardware_init();   
3023         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: Usb Hardware Initialize Complete.\n");
3024         usbs_imx_otg_dev_ep0_init();
3025         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: Usb Ep0 Initialize Complete.\n");
3026         usbs_imx_otg_dev_ep1_init();
3027         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: Usb Ep1 Initialize Complete.\n");
3028         usbs_imx_otg_dev_ep2_init();
3029         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: Usb Ep2 Initialize Complete.\n"); 
3030
3031         #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
3032         cyg_semaphore_init(&usbs_imx_otg_dev_sem, 0);
3033     cyg_thread_create(CYGNUM_DEVS_USB_OTG_DEV_THREAD_PRIORITY,
3034                       &usbs_imx_otg_dev_thread_fn,
3035                       0,
3036                       "i.MX37/51 USB Device",
3037                       usbs_imx_otg_dev_thread_stack,
3038                       CYGNUM_DEVS_USB_OTG_DEV_THREAD_STACK_SIZE,
3039                       &usbs_imx_otg_dev_thread_handle,
3040                       &usbs_imx_otg_dev_thread
3041         );
3042     cyg_thread_resume(usbs_imx_otg_dev_thread_handle);
3043         // It is also possible and desirable to install the interrupt
3044         // handler here, even though there will be no interrupts for a
3045         // while yet.
3046         cyg_interrupt_create(IMX_IRQ_USB_DEV_SERVICE_REQUEST,
3047                              IMX_IRQ_USB_DEV_PRIORITY,        // priority
3048                              0,         // data
3049                              &usbs_imx_otg_dev_isr,                             
3050                                                          &usbs_imx_otg_dev_thread_dsr,
3051                              &g_usbs_dev_intr_handle,
3052                              &g_usbs_dev_intr_data);
3053         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: cyg_interrupt_create@vector %d.\n",IMX_IRQ_USB_DEV_SERVICE_REQUEST);
3054         cyg_interrupt_attach(g_usbs_dev_intr_handle);           //fill interrupt handler table for USB 
3055         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: cyg_interrupt_attach.\n");
3056         cyg_interrupt_unmask(IMX_IRQ_USB_DEV_SERVICE_REQUEST);  //enable USB interrrupt
3057         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: cyg_interrupt_unmask.\n");
3058         #endif
3059         ep0.common.start_fn(&(ep0.common));
3060
3061 }
3062
3063 void 
3064 usbs_imx_otg_device_deinit(void) //works like usb port close
3065 {
3066         usbs_imx_otg_base->usbcmd &= (~BIT0);                           // Set Run/Stop bit to Stop Mode
3067         g_usb_dev_state = USB_DEV_DUMMY_STATE;
3068 }
3069
3070 #if defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
3071
3072 static cyg_uint32 get_free_bulk_buffer(void)
3073 {
3074         cyg_uint32 buff_addr = 0;
3075         int i = 0;
3076         while(buff_addr == 0)
3077         {
3078                 if(g_bulkbuffer_a.stat == BUFFER_FREED)
3079                 {
3080                         buff_addr = (cyg_uint32)(g_bulkbuffer_a.buffer);
3081                         break;
3082                 }
3083                 else if(g_bulkbuffer_b.stat == BUFFER_FREED)
3084                 {
3085                         buff_addr = (cyg_uint32)(g_bulkbuffer_b.buffer);
3086                         break;
3087                 }
3088                 /*
3089                 else
3090                 {
3091                         i++;
3092                         if(i==0xD0000) 
3093                         {
3094                                 diag_printf("no bulk buffer free\n");
3095                                 break;
3096                         }
3097                         
3098                 }
3099                 */
3100         }
3101         return buff_addr;
3102 }
3103
3104 cyg_bool set_status_bulk_buffer(cyg_uint32 buff_addr, int buff_stat)
3105 {
3106         cyg_bool ret = true;
3107         if(buff_addr == (cyg_uint32)(g_bulkbuffer_a.buffer))
3108                 g_bulkbuffer_a.stat = buff_stat;
3109         else if (buff_addr == (cyg_uint32)(g_bulkbuffer_b.buffer))
3110                 g_bulkbuffer_b.stat = buff_stat;
3111         else
3112                 ret = false;
3113
3114         return ret;
3115 }
3116 static usb_status_t usb_bulk_receive_data(usb_buffer_descriptor_t * bd)
3117 {
3118         usb_status_t status;
3119         int res;
3120
3121         /* Check if Bus Reset Received */
3122     if((usbs_imx_otg_base->usbsts) & IMX_USB_STS_RESET)
3123     {
3124         /* Handle Bus Reset */
3125         usbs_imx_otg_dev_handle_bus_reset(); 
3126     }   
3127     /* Check if Reset is already received and Setup Token Received */
3128     if((usbs_imx_otg_base->endptsetupstat) & BIT0)
3129     {
3130                 /* Handle Setup Token */
3131         usbs_imx_otg_dev_ep0_dsr();
3132     }
3133         
3134         if((usbs_imx_otg_base->endptcomplete) & ( EPOUT_COMPLETE << EP1))
3135         {
3136                 ep1_rx_complete(res);
3137                 if(ep1.common.complete_data)
3138                 {
3139                         bd->bytes_transfered = ep1.fetched;
3140                         memcpy(bd->buffer,ep1.common.complete_data,ep1.fetched);
3141                         ep1.fetched = 0;
3142                         //D("+USBDBGMSG:bd->bytes_transfered %d\n",bd->bytes_transfered);
3143                         set_status_bulk_buffer((cyg_uint32)(ep1.common.complete_data), BUFFER_FREED);
3144                         ep1.common.buffer = (unsigned char *)get_free_bulk_buffer();
3145                         ep1.common.buffer_size = BULK_TD_BUFFER_TOTAL_SIZE;
3146                         ep1_start_rx(&(ep1.common));
3147                         usbs_imx_otg_base->endptprime |= ( EPOUT_PRIME << EP1 );//prime ep1 td
3148                         status = USB_SUCCESS;
3149                 }
3150
3151                 else
3152                         status = USB_FAILURE;
3153         }
3154         return status;
3155 }
3156
3157 static usb_status_t usb_bulk_transmit_data(usb_buffer_descriptor_t * bd)
3158 {
3159         //usb_state_t status;
3160
3161         while(bd->size)
3162         {
3163                 ep2.common.buffer = (unsigned char *)get_free_bulk_buffer();
3164                 set_status_bulk_buffer((cyg_uint32)(ep2.common.buffer), BUFFER_ALLOCATED);
3165                 ep2.common.buffer_size = (BULK_TD_BUFFER_TOTAL_SIZE<(bd->size))?BULK_TD_BUFFER_TOTAL_SIZE:(bd->size);
3166                 memcpy((ep2.common.buffer),(bd->buffer),(ep2.common.buffer_size));
3167                 ep2_start_tx(&(ep2.common));
3168
3169                 bd->size -= (ep2.common.buffer_size);
3170         }
3171
3172         return USB_SUCCESS;
3173 }
3174 static cyg_uint32 usb_rx_processing(cyg_uint8* read_ptr, usb_status_t* status, cyg_uint32 data_length)
3175 {
3176         cyg_uint32 bytes_received = 0;
3177     if ( (status != NULL) && (read_ptr != NULL) )
3178     {
3179         usb_status_t trans_status = USB_FAILURE;
3180
3181         usb_buffer_descriptor_t  buf_desc;
3182
3183         /* Prepare the buffer descriptor for USB transfer */
3184         //(cyg_uint8*)(buf_desc.buffer) = read_ptr;
3185                 buf_desc.buffer = (void *)read_ptr;
3186         while(data_length != 0)
3187         { 
3188             buf_desc.size = data_length;
3189             buf_desc.bytes_transfered = 0;
3190
3191             /* Receive data from USB */
3192             trans_status = (usb_status_t )usb_bulk_receive_data(&buf_desc);
3193             if(trans_status == USB_SUCCESS)
3194             {
3195                 data_length -= buf_desc.bytes_transfered;
3196                 bytes_received += buf_desc.bytes_transfered;
3197                 //(cyg_uint8*)
3198                                 (buf_desc.buffer) += buf_desc.bytes_transfered;
3199             }
3200             else
3201             {
3202                 *status = USB_FAILURE;
3203             }
3204
3205                         g_timeout_value++;
3206                         if(g_timeout_value%0x1000000==0) D("C");
3207                         if(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT) return 0;
3208         }
3209     }
3210    
3211     return ( bytes_received );
3212 }
3213 static usb_status_t usb_tx_processing(cyg_uint8* write_ptr, cyg_uint32 data_len)
3214 {
3215     usb_status_t trans_status = USB_FAILURE;
3216
3217     /* Prepare the buffer descriptor for USB transfer */
3218     usb_buffer_descriptor_t  buf_desc;
3219
3220     /* Prepare transfer buffer descriptor*/ 
3221     buf_desc.buffer = (void *)write_ptr;
3222     buf_desc.size = data_len;
3223     buf_desc.bytes_transfered = 0;
3224
3225     /* Send data over USB */
3226     trans_status = usb_bulk_transmit_data(&buf_desc);
3227
3228         return trans_status;
3229 }
3230 static cyg_bool pl_get_command(void)
3231 {
3232         cyg_uint8 i = 0;
3233         usb_status_t status;
3234     cyg_uint32 bytes_recvd = 0;
3235     cyg_uint8 start_command = 0xFF;
3236
3237     while(start_command == 0xFF)
3238     {
3239                 //g_timeout_value++;
3240                 //if(g_timeout_value%1000==0) D("C");
3241                 //D("%d\n",g_timeout_value);
3242                 bytes_recvd = usb_rx_processing(sdp_payload_data, &status, SDP_CMD_MAX_LEN);
3243         start_command = pl_command_start();             
3244                 if(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT) return false;
3245     }
3246         //D("+USBDBGMSG: start_command = 0x%02X\n",start_command);
3247     if(start_command == 0xF0)
3248     {
3249         //copy rest of the bytes
3250         for(i=1; i < SDP_CMD_MAX_LEN; i++)
3251         {
3252             sdp_command[i] = sdp_payload_data[i-1];
3253         }
3254     }
3255     else 
3256     {
3257         //copy starting bytes
3258         for(i=0; i < (SDP_CMD_MAX_LEN - start_command) ; i++)
3259         {
3260             sdp_command[i] = sdp_payload_data[i + start_command];
3261         }
3262
3263         if(start_command != 0)
3264         {
3265             //receive rest of the bytes
3266             bytes_recvd = usb_rx_processing(sdp_payload_data, &status, start_command);
3267         
3268             if(bytes_recvd == start_command)
3269             {
3270                 for(i=0; i <start_command; i++)
3271                 {
3272                     sdp_command[SDP_CMD_MAX_LEN - start_command + i] = sdp_payload_data[i];
3273                 }
3274             }
3275         }
3276     }
3277
3278     return true;
3279 }
3280 static cyg_uint8 pl_command_start(void)
3281 {
3282         cyg_uint8 i=0;
3283     static cyg_uint8 last_byte = 0;
3284    
3285     if(last_byte != 0x0)
3286     {
3287         if(last_byte == sdp_payload_data[0])
3288         {
3289             sdp_command[0] = last_byte;
3290             last_byte = sdp_payload_data[SDP_CMD_MAX_LEN -1];
3291             return 0xF0;
3292         }
3293     }
3294
3295     for(i=0; i < SDP_CMD_MAX_LEN -1; i++)
3296     {
3297         if((sdp_payload_data[i] == 0x01) && (sdp_payload_data[i+1] == 0x01) ||
3298            (sdp_payload_data[i] == 0x02) && (sdp_payload_data[i+1] == 0x02) ||
3299            (sdp_payload_data[i] == 0x03) && (sdp_payload_data[i+1] == 0x03) ||
3300            (sdp_payload_data[i] == 0x04) && (sdp_payload_data[i+1] == 0x04) ||
3301            (sdp_payload_data[i] == 0x05) && (sdp_payload_data[i+1] == 0x05) ||
3302            (sdp_payload_data[i] == 0x06) && (sdp_payload_data[i+1] == 0x06) ||
3303            (sdp_payload_data[i] == 0x07) && (sdp_payload_data[i+1] == 0x07) ||
3304            (sdp_payload_data[i] == 0x08) && (sdp_payload_data[i+1] == 0x08) ||
3305            (sdp_payload_data[i] == 0x09) && (sdp_payload_data[i+1] == 0x09) ||
3306            (sdp_payload_data[i] == 0x0A) && (sdp_payload_data[i+1] == 0x0A)) 
3307          {
3308              return i;
3309          }
3310     }
3311
3312     //handle last byte
3313     last_byte = sdp_payload_data[SDP_CMD_MAX_LEN -1];
3314     if(!(last_byte == 0x1 || last_byte == 0x2 || last_byte == 0x3 || last_byte == 0x4 ||
3315        last_byte == 0x5 || last_byte == 0x6 || last_byte == 0x7 || last_byte == 0x8 || last_byte == 0x8 ||
3316        last_byte == 0x9))
3317     {
3318         last_byte = 0;
3319     }
3320     
3321     return 0xFF;
3322 }
3323 static cyg_uint8 pl_handle_command(cyg_uint8 g_error_status)
3324 {
3325         cyg_uint16 Header = 0;
3326     cyg_uint32 Address = 0;
3327     cyg_uint32 ByteCount = 0;
3328     cyg_uint32 g_error_statusAck = 0;
3329     cyg_uint8 status = 0;
3330         //int i;
3331     /* Command Packet Format: Header(2)+Address(4)+Format(1)+ByteCount(4)+Data(4)+Execute(1) */
3332     Header = ((sdp_command[0]<<8) | (sdp_command[1]));
3333     Address = ((sdp_command[2]<<24) | (sdp_command[3]<<16) | (sdp_command[4] << 8) | (sdp_command[5]));
3334     ByteCount = ((sdp_command[7]<<24) | (sdp_command[8]<<16) | (sdp_command[9] << 8) | (sdp_command[10]));
3335
3336     /* Save g_error_status ack */
3337     g_error_statusAck = (cyg_uint32)((g_error_status<<24) | (g_error_status <<16) | (g_error_status<<8) | (g_error_status));
3338         //D("+USBDBGMSG: Command Header 0x%04X\n",Header);
3339     switch (Header)
3340     {
3341         case WRITE_FILE:
3342                         //D("+USBDBGMSG: usb download file to address 0x%08X, length %d\n",usb_download_address,ByteCount);
3343             pl_handle_write_file(usb_download_address, ByteCount);      
3344             //pl_handle_write_file(Address, ByteCount);
3345                         //if(g_load_cycle==0) usb_download_address=Address;
3346                         //g_load_cycle ++;
3347                         usb_download_address += ByteCount;
3348                         usb_download_length +=ByteCount;
3349                         D(".");
3350                         if(ByteCount<BULK_TD_BUFFER_TOTAL_SIZE) 
3351                         {
3352                                 status = COMPLETE;
3353                         }
3354             break;
3355         case ERROR_STATUS_HEADER:
3356             pl_command_ack(g_error_statusAck);
3357                         status = COMPLETE;
3358             break;
3359                 case READ_FILE:
3360         case WRITE_HEADER:
3361         case READ_HEADER:
3362         default:
3363             break;
3364     }
3365
3366     return status;
3367
3368 }
3369 static void pl_handle_write_file(cyg_uint32 address, cyg_uint32 total_bytes)
3370 {
3371         usb_status_t status;    
3372     usb_rx_processing((cyg_uint8*)address, &status, total_bytes);
3373 }
3374
3375 static void pl_command_ack(cyg_uint32 ack)
3376 {
3377     usb_tx_processing((cyg_uint8*)&ack, SDP_CMD_ACK_LEN);
3378 }       
3379
3380 void 
3381 usbs_imx_otg_download(unsigned char * buffer, unsigned int length)
3382 {
3383         cyg_bool bytes_recvd = false;
3384         //D("+usbdownload: enter usbs_imx_otg_download\n");
3385         //D("+USBDBGMSG: re-enumerate USB device\n");
3386         /*enumeration*/
3387         /*TODO*/
3388         while(g_usb_dev_state!=USB_DEV_CONFIGURED_STATE)
3389         {
3390                 
3391                 /* Check if Bus Reset Received */
3392         if((usbs_imx_otg_base->usbsts) & IMX_USB_STS_RESET)
3393         {
3394             /* Handle Bus Reset */
3395                 usbs_imx_otg_dev_handle_bus_reset(); 
3396         }       
3397         /* Check if Reset is already received and Setup Token Received */
3398         if((g_usb_dev_state != USB_DEV_DUMMY_STATE) && (usbs_imx_otg_base->endptsetupstat & BIT0))
3399         {
3400                 /* Handle Setup Token */
3401                 usbs_imx_otg_dev_ep0_dsr();
3402         }               
3403         }
3404
3405         if(g_usb_dev_state==USB_DEV_CONFIGURED_STATE)
3406         {
3407                 //D("+USBDBGMSG: enumeration done\n");
3408                 /*file download*/
3409                 D("USB file download start\n");
3410                 g_timeout_value = 0;
3411                 usb_download_length = 0;
3412                 //usb_download_address = 0;
3413                 //g_load_cycle = 0;
3414                 while(1)
3415                 {
3416                         
3417                         bytes_recvd = pl_get_command();
3418                 if(bytes_recvd == true)
3419                 {
3420                 g_usb_download_state = pl_handle_command(g_error_status);  
3421                 } 
3422         
3423                         if((g_usb_download_state==COMPLETE)||(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT)) 
3424                                 break;
3425                         
3426                 }
3427                 diag_printf("\n");
3428                 if(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT) //timeout value
3429                         D("USB download timeout to wait none file to download\n");
3430                 else
3431                 {
3432                         D("USB file download complete\n");
3433                         //D("+usbdownload: image base 0x%08X, length %d\n",usb_download_address,usb_download_length);
3434                 }
3435                 
3436         }
3437 }
3438 #endif
3439
3440 //EOF