Merge pull request #93 from zyp/master
[fw/stlink] / example / stm32f4 / STM32_USB_HOST_Library / Class / MSC / src / usbh_msc_scsi.c
1 /**
2   ******************************************************************************
3   * @file    usbh_msc_scsi.c 
4   * @author  MCD Application Team
5   * @version V2.0.0
6   * @date    22-July-2011
7   * @brief   This file implements the SCSI commands
8   ******************************************************************************
9   * @attention
10   *
11   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
14   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17   *
18   * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
19   ******************************************************************************
20   */ 
21
22 /* Includes ------------------------------------------------------------------*/
23 #include "usbh_msc_core.h"
24 #include "usbh_msc_scsi.h"
25 #include "usbh_msc_bot.h"
26 #include "usbh_ioreq.h"
27 #include "usbh_def.h"
28
29
30 /** @addtogroup USBH_LIB
31   * @{
32   */
33
34 /** @addtogroup USBH_CLASS
35   * @{
36   */
37
38 /** @addtogroup USBH_MSC_CLASS
39   * @{
40   */
41   
42 /** @defgroup USBH_MSC_SCSI 
43   * @brief    This file includes the mass storage related functions
44   * @{
45   */ 
46
47
48 /** @defgroup USBH_MSC_SCSI_Private_TypesDefinitions
49   * @{
50   */ 
51
52 MassStorageParameter_TypeDef USBH_MSC_Param; 
53 /**
54   * @}
55   */ 
56
57 /** @defgroup USBH_MSC_SCSI_Private_Defines
58   * @{
59   */ 
60 /**
61   * @}
62   */ 
63
64 /** @defgroup USBH_MSC_SCSI_Private_Macros
65   * @{
66   */ 
67 /**
68   * @}
69   */ 
70
71
72 /** @defgroup USBH_MSC_SCSI_Private_Variables
73   * @{
74   */ 
75   
76 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
77   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
78     #pragma data_alignment=4   
79   #endif
80 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
81 __ALIGN_BEGIN uint8_t USBH_DataInBuffer[512] __ALIGN_END ;
82
83 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
84   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
85     #pragma data_alignment=4   
86   #endif
87 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
88 __ALIGN_BEGIN uint8_t USBH_DataOutBuffer[512] __ALIGN_END ;
89 /**
90   * @}
91   */ 
92
93
94 /** @defgroup USBH_MSC_SCSI_Private_FunctionPrototypes
95   * @{
96   */ 
97 /**
98   * @}
99   */ 
100
101
102 /** @defgroup USBH_MSC_SCSI_Exported_Variables
103   * @{
104   */ 
105
106 /**
107   * @}
108   */ 
109
110
111 /** @defgroup USBH_MSC_SCSI_Private_Functions
112   * @{
113   */ 
114
115
116
117
118 /**
119   * @brief  USBH_MSC_TestUnitReady 
120   *         Issues 'Test unit ready' command to the device. Once the response  
121   *         received, it updates the status to upper layer.
122   * @param  None
123   * @retval Status
124   */
125 uint8_t USBH_MSC_TestUnitReady (USB_OTG_CORE_HANDLE *pdev)
126 {
127   uint8_t index;
128   USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
129   
130   if(HCD_IsDeviceConnected(pdev))
131   {  
132     switch(USBH_MSC_BOTXferParam.CmdStateMachine)
133     {
134     case CMD_SEND_STATE:  
135       /*Prepare the CBW and relevent field*/
136       USBH_MSC_CBWData.field.CBWTransferLength = 0;       /* No Data Transfer */
137       USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT;
138       USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH_TEST_UNIT_READY;
139       USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray;
140       USBH_MSC_BOTXferParam.DataLength = USBH_MSC_CSW_MAX_LENGTH;
141       USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_TEST_UNIT_READY;
142       
143       for(index = CBW_CB_LENGTH; index != 0; index--)
144       {
145         USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
146       }
147       
148       USBH_MSC_CBWData.field.CBWCB[0]  = OPCODE_TEST_UNIT_READY; 
149       USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
150       /* Start the transfer, then let the state 
151       machine magage the other transactions */
152       USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
153       USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
154       USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
155       
156       status = USBH_MSC_BUSY; 
157       break;
158       
159     case CMD_WAIT_STATUS: 
160       if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
161       { 
162         /* Commands successfully sent and Response Received  */       
163         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
164        
165         status = USBH_MSC_OK;      
166       }
167       else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
168       {
169         /* Failure Mode */
170         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
171         status = USBH_MSC_FAIL;
172       }
173       
174       else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
175       {
176         /* Failure Mode */
177         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
178         status = USBH_MSC_PHASE_ERROR;    
179       }  
180       break;
181       
182     default:
183       break;
184     }
185   }
186   return status;
187 }
188
189
190 /**
191   * @brief  USBH_MSC_ReadCapacity10  
192   *         Issue the read capacity command to the device. Once the response 
193   *         received, it updates the status to upper layer
194   * @param  None
195   * @retval Status
196   */
197 uint8_t USBH_MSC_ReadCapacity10(USB_OTG_CORE_HANDLE *pdev)
198 {
199   uint8_t index;
200   USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
201   
202   if(HCD_IsDeviceConnected(pdev))
203   {  
204     switch(USBH_MSC_BOTXferParam.CmdStateMachine)
205     {
206     case CMD_SEND_STATE:
207       /*Prepare the CBW and relevent field*/
208       USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_READ_CAPACITY10;
209       USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
210       USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
211       
212       USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer;
213       USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_READ_CAPACITY10;
214       
215       for(index = CBW_CB_LENGTH; index != 0; index--)
216       {
217         USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
218       }    
219       
220       USBH_MSC_CBWData.field.CBWCB[0]  = OPCODE_READ_CAPACITY10; 
221       USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
222       
223       /* Start the transfer, then let the state machine manage the other 
224                                                                 transactions */
225       USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
226       USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
227       USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
228       
229       status = USBH_MSC_BUSY;
230       break;
231       
232     case CMD_WAIT_STATUS:
233       if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
234       {
235         /*assign the capacity*/
236         (((uint8_t*)&USBH_MSC_Param.MSCapacity )[3]) = USBH_DataInBuffer[0];
237         (((uint8_t*)&USBH_MSC_Param.MSCapacity )[2]) = USBH_DataInBuffer[1];
238         (((uint8_t*)&USBH_MSC_Param.MSCapacity )[1]) = USBH_DataInBuffer[2];
239         (((uint8_t*)&USBH_MSC_Param.MSCapacity )[0]) = USBH_DataInBuffer[3];
240         
241         /*assign the page length*/
242         (((uint8_t*)&USBH_MSC_Param.MSPageLength )[1]) = USBH_DataInBuffer[6];
243         (((uint8_t*)&USBH_MSC_Param.MSPageLength )[0]) = USBH_DataInBuffer[7];
244         
245         /* Commands successfully sent and Response Received  */       
246         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
247         status = USBH_MSC_OK;      
248       }
249       else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
250       {
251         /* Failure Mode */
252         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
253         status = USBH_MSC_FAIL;
254       }  
255       else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
256       {
257         /* Failure Mode */
258         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
259         status = USBH_MSC_PHASE_ERROR;    
260       } 
261       else
262       {
263         /* Wait for the Commands to get Completed */
264         /* NO Change in state Machine */
265       }
266       break;
267       
268     default:
269       break;
270     }
271   }
272   return status;
273 }
274
275
276 /**
277   * @brief  USBH_MSC_ModeSense6  
278   *         Issue the Mode Sense6 Command to the device. This function is used 
279   *          for reading the WriteProtect Status of the Mass-Storage device. 
280   * @param  None
281   * @retval Status
282   */
283 uint8_t USBH_MSC_ModeSense6(USB_OTG_CORE_HANDLE *pdev)
284 {
285   uint8_t index;
286   USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
287   
288   if(HCD_IsDeviceConnected(pdev))
289   {  
290     switch(USBH_MSC_BOTXferParam.CmdStateMachine)
291     {
292     case CMD_SEND_STATE:
293       /*Prepare the CBW and relevent field*/
294       USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_MODE_SENSE6;
295       USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
296       USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
297       
298       USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer;
299       USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_MODE_SENSE6;
300       
301       for(index = CBW_CB_LENGTH; index != 0; index--)
302       {
303         USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
304       }    
305       
306       USBH_MSC_CBWData.field.CBWCB[0]  = OPCODE_MODE_SENSE6; 
307       USBH_MSC_CBWData.field.CBWCB[2]  = MODE_SENSE_PAGE_CONTROL_FIELD | \
308                                          MODE_SENSE_PAGE_CODE;
309                                            
310       USBH_MSC_CBWData.field.CBWCB[4]  = XFER_LEN_MODE_SENSE6;
311                                                                                       
312       USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
313       
314       /* Start the transfer, then let the state machine manage the other 
315                                                                 transactions */
316       USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
317       USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
318       USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
319       
320       status = USBH_MSC_BUSY;
321       break;
322       
323     case CMD_WAIT_STATUS:
324       if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
325       {
326         /* Assign the Write Protect status */
327         /* If WriteProtect = 0, Writing is allowed 
328            If WriteProtect != 0, Disk is Write Protected */
329         if ( USBH_DataInBuffer[2] & MASK_MODE_SENSE_WRITE_PROTECT)
330         {
331           USBH_MSC_Param.MSWriteProtect   = DISK_WRITE_PROTECTED;
332         }
333         else
334         {
335           USBH_MSC_Param.MSWriteProtect   = 0;
336         }
337         
338         /* Commands successfully sent and Response Received  */       
339         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
340         status = USBH_MSC_OK;      
341       }
342       else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
343       {
344         /* Failure Mode */
345         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
346         status = USBH_MSC_FAIL;
347       }
348       else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
349       {
350         /* Failure Mode */
351         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
352         status = USBH_MSC_PHASE_ERROR;    
353       }
354       else
355       {
356         /* Wait for the Commands to get Completed */
357         /* NO Change in state Machine */
358       }
359       break;
360       
361     default:
362       break;
363     }
364   }
365   return status;
366 }
367
368 /**
369   * @brief  USBH_MSC_RequestSense  
370   *         Issues the Request Sense command to the device. Once the response 
371   *         received, it updates the status to upper layer
372   * @param  None
373   * @retval Status
374   */
375 uint8_t USBH_MSC_RequestSense(USB_OTG_CORE_HANDLE *pdev)
376 {
377   USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
378   
379   uint8_t index;
380   
381   
382   if(HCD_IsDeviceConnected(pdev))
383   {  
384     switch(USBH_MSC_BOTXferParam.CmdStateMachine)
385     {
386     case CMD_SEND_STATE:
387       
388       /*Prepare the CBW and relevent field*/
389       USBH_MSC_CBWData.field.CBWTransferLength = \
390                                                 ALLOCATION_LENGTH_REQUEST_SENSE;
391       USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
392       USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
393       
394       USBH_MSC_BOTXferParam.pRxTxBuff = USBH_DataInBuffer;
395       USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_BOTXferParam.MSCStateCurrent;
396       USBH_MSC_BOTXferParam.MSCStateCurrent = USBH_MSC_REQUEST_SENSE;
397       
398
399       for(index = CBW_CB_LENGTH; index != 0; index--)
400       {
401         USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
402       }    
403       
404       USBH_MSC_CBWData.field.CBWCB[0]  = OPCODE_REQUEST_SENSE; 
405       USBH_MSC_CBWData.field.CBWCB[1]  = DESC_REQUEST_SENSE;
406       USBH_MSC_CBWData.field.CBWCB[4]  = ALLOCATION_LENGTH_REQUEST_SENSE;
407       
408       USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
409       /* Start the transfer, then let the state machine magage 
410       the other transactions */
411       USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
412       USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
413       USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
414       
415       status = USBH_MSC_BUSY;
416       
417       break;
418       
419     case CMD_WAIT_STATUS:
420       
421       if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
422       {
423         /* Get Sense data*/
424         (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[3]) = USBH_DataInBuffer[0];
425         (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[2]) = USBH_DataInBuffer[1];
426         (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[1]) = USBH_DataInBuffer[2];
427         (((uint8_t*)&USBH_MSC_Param.MSSenseKey )[0]) = USBH_DataInBuffer[3];
428         
429         /* Commands successfully sent and Response Received  */       
430         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
431         status = USBH_MSC_OK;      
432       }
433       else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
434       {
435         /* Failure Mode */
436         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
437         status = USBH_MSC_FAIL;
438       }
439       
440       else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
441       {
442         /* Failure Mode */
443         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
444         status = USBH_MSC_PHASE_ERROR;    
445       }
446       
447       else
448       {
449         /* Wait for the Commands to get Completed */
450         /* NO Change in state Machine */
451       }
452       break;
453       
454     default:
455       break;
456     }
457   }
458   return status;
459 }
460
461
462 /**
463   * @brief  USBH_MSC_Write10 
464   *         Issue the write command to the device. Once the response received, 
465   *         it updates the status to upper layer
466   * @param  dataBuffer : DataBuffer contains the data to write
467   * @param  address : Address to which the data will be written
468   * @param  nbOfbytes : NbOfbytes to be written
469   * @retval Status
470   */
471 uint8_t USBH_MSC_Write10(USB_OTG_CORE_HANDLE *pdev, 
472                          uint8_t *dataBuffer,
473                          uint32_t address,
474                          uint32_t nbOfbytes)
475 {
476   uint8_t index;
477   USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
478   uint16_t nbOfPages;
479   
480   if(HCD_IsDeviceConnected(pdev))
481   {  
482     switch(USBH_MSC_BOTXferParam.CmdStateMachine)
483     {
484     case CMD_SEND_STATE:   
485       USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes;
486       USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT;
487       USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
488       USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer;
489       
490       
491       for(index = CBW_CB_LENGTH; index != 0; index--)  
492       {
493         USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
494       }
495       
496       USBH_MSC_CBWData.field.CBWCB[0]  = OPCODE_WRITE10; 
497       
498       /*logical block address*/
499       USBH_MSC_CBWData.field.CBWCB[2]  = (((uint8_t*)&address)[3]) ;
500       USBH_MSC_CBWData.field.CBWCB[3]  = (((uint8_t*)&address)[2]);
501       USBH_MSC_CBWData.field.CBWCB[4]  = (((uint8_t*)&address)[1]);
502       USBH_MSC_CBWData.field.CBWCB[5]  = (((uint8_t*)&address)[0]);
503       
504       /*USBH_MSC_PAGE_LENGTH = 512*/
505       nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH; 
506       
507       /*Tranfer length */
508       USBH_MSC_CBWData.field.CBWCB[7]  = (((uint8_t *)&nbOfPages)[1]) ; 
509       USBH_MSC_CBWData.field.CBWCB[8]  = (((uint8_t *)&nbOfPages)[0]) ; 
510       
511       USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
512       /* Start the transfer, then let the state machine 
513       magage the other transactions */
514       USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
515       USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
516       USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
517       
518       status = USBH_MSC_BUSY;
519       
520       break;
521       
522     case CMD_WAIT_STATUS:
523       if(USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK)
524       { 
525         /* Commands successfully sent and Response Received  */       
526         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
527         status = USBH_MSC_OK;      
528       }
529       else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL )
530       {
531         /* Failure Mode */
532         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
533       }
534       
535       else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
536       {
537         /* Failure Mode */
538         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
539         status = USBH_MSC_PHASE_ERROR;    
540       }
541       break;
542       
543     default:
544       break;
545     }
546   }
547   return status;
548 }
549
550 /**
551   * @brief  USBH_MSC_Read10 
552   *         Issue the read command to the device. Once the response received, 
553   *         it updates the status to upper layer
554   * @param  dataBuffer : DataBuffer will contain the data to be read
555   * @param  address : Address from which the data will be read
556   * @param  nbOfbytes : NbOfbytes to be read
557   * @retval Status
558   */
559 uint8_t USBH_MSC_Read10(USB_OTG_CORE_HANDLE *pdev,
560                         uint8_t *dataBuffer,
561                         uint32_t address,
562                         uint32_t nbOfbytes)
563 {
564   uint8_t index;
565   static USBH_MSC_Status_TypeDef status = USBH_MSC_BUSY;
566   uint16_t nbOfPages;
567   status = USBH_MSC_BUSY;
568   
569   if(HCD_IsDeviceConnected(pdev))
570   {
571     switch(USBH_MSC_BOTXferParam.CmdStateMachine)
572     {
573     case CMD_SEND_STATE:
574       /*Prepare the CBW and relevent field*/
575       USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes;
576       USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN;
577       USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH;
578       
579       USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer;
580       
581       for(index = CBW_CB_LENGTH; index != 0; index--)
582       {
583         USBH_MSC_CBWData.field.CBWCB[index] = 0x00;
584       }
585       
586       USBH_MSC_CBWData.field.CBWCB[0]  = OPCODE_READ10; 
587       
588       /*logical block address*/
589       
590       USBH_MSC_CBWData.field.CBWCB[2]  = (((uint8_t*)&address)[3]);
591       USBH_MSC_CBWData.field.CBWCB[3]  = (((uint8_t*)&address)[2]);
592       USBH_MSC_CBWData.field.CBWCB[4]  = (((uint8_t*)&address)[1]);
593       USBH_MSC_CBWData.field.CBWCB[5]  = (((uint8_t*)&address)[0]);
594       
595       /*USBH_MSC_PAGE_LENGTH = 512*/
596       nbOfPages = nbOfbytes/ USBH_MSC_PAGE_LENGTH;  
597       
598       /*Tranfer length */
599       USBH_MSC_CBWData.field.CBWCB[7]  = (((uint8_t *)&nbOfPages)[1]) ; 
600       USBH_MSC_CBWData.field.CBWCB[8]  = (((uint8_t *)&nbOfPages)[0]) ; 
601       
602       
603       USBH_MSC_BOTXferParam.BOTState = USBH_MSC_SEND_CBW;
604       /* Start the transfer, then let the state machine 
605       magage the other transactions */
606       USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_USB_TRANSFERS;
607       USBH_MSC_BOTXferParam.BOTXferStatus = USBH_MSC_BUSY;
608       USBH_MSC_BOTXferParam.CmdStateMachine = CMD_WAIT_STATUS;
609       
610       status = USBH_MSC_BUSY;
611       
612       break;
613       
614     case CMD_WAIT_STATUS:
615       
616       if((USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_OK) && \
617         (HCD_IsDeviceConnected(pdev)))
618       { 
619         /* Commands successfully sent and Response Received  */       
620         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
621         status = USBH_MSC_OK;      
622       }
623       else if (( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_FAIL ) && \
624         (HCD_IsDeviceConnected(pdev)))
625       {
626         /* Failure Mode */
627         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
628       }
629       
630       else if ( USBH_MSC_BOTXferParam.BOTXferStatus == USBH_MSC_PHASE_ERROR )
631       {
632         /* Failure Mode */
633         USBH_MSC_BOTXferParam.CmdStateMachine = CMD_SEND_STATE;
634         status = USBH_MSC_PHASE_ERROR;    
635       }
636       else
637       {
638         /* Wait for the Commands to get Completed */
639         /* NO Change in state Machine */
640       }
641       break;
642       
643     default:
644       break;
645     }
646   }
647   return status;
648 }
649
650
651 /**
652   * @}
653   */ 
654
655 /**
656   * @}
657   */ 
658
659 /**
660   * @}
661   */
662
663 /**
664   * @}
665   */ 
666
667 /**
668   * @}
669   */
670
671 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
672
673
674