is just added to File System Lib used by our students

Dependents:   FileSystem_POPS

Committer:
bouaziz
Date:
Sun Nov 10 20:59:07 2013 +0000
Revision:
0:7c305139fb85
Very difficult to find lib for USB mass storage access.; This one works fine after few modif.; This is identified POPS because is used by our undergraduate students Polytech Paris Sud Orsay  engineer School;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bouaziz 0:7c305139fb85 1 /*
bouaziz 0:7c305139fb85 2 **************************************************************************************************************
bouaziz 0:7c305139fb85 3 * NXP USB Host Stack
bouaziz 0:7c305139fb85 4 *
bouaziz 0:7c305139fb85 5 * (c) Copyright 2008, NXP SemiConductors
bouaziz 0:7c305139fb85 6 * (c) Copyright 2008, OnChip Technologies LLC
bouaziz 0:7c305139fb85 7 * All Rights Reserved
bouaziz 0:7c305139fb85 8 *
bouaziz 0:7c305139fb85 9 * www.nxp.com
bouaziz 0:7c305139fb85 10 * www.onchiptech.com
bouaziz 0:7c305139fb85 11 *
bouaziz 0:7c305139fb85 12 * File : usbhost_ms.c
bouaziz 0:7c305139fb85 13 * Programmer(s) : Ravikanth.P
bouaziz 0:7c305139fb85 14 * Version :
bouaziz 0:7c305139fb85 15 *
bouaziz 0:7c305139fb85 16 **************************************************************************************************************
bouaziz 0:7c305139fb85 17 */
bouaziz 0:7c305139fb85 18
bouaziz 0:7c305139fb85 19 /*
bouaziz 0:7c305139fb85 20 **************************************************************************************************************
bouaziz 0:7c305139fb85 21 * INCLUDE HEADER FILES
bouaziz 0:7c305139fb85 22 **************************************************************************************************************
bouaziz 0:7c305139fb85 23 */
bouaziz 0:7c305139fb85 24
bouaziz 0:7c305139fb85 25 #include "usbhost_ms.h"
bouaziz 0:7c305139fb85 26
bouaziz 0:7c305139fb85 27 /*
bouaziz 0:7c305139fb85 28 **************************************************************************************************************
bouaziz 0:7c305139fb85 29 * GLOBAL VARIABLES
bouaziz 0:7c305139fb85 30 **************************************************************************************************************
bouaziz 0:7c305139fb85 31 */
bouaziz 0:7c305139fb85 32
bouaziz 0:7c305139fb85 33 USB_INT32U MS_BlkSize;
bouaziz 0:7c305139fb85 34
bouaziz 0:7c305139fb85 35 /*
bouaziz 0:7c305139fb85 36 **************************************************************************************************************
bouaziz 0:7c305139fb85 37 * INITIALIZE MASS STORAGE INTERFACE
bouaziz 0:7c305139fb85 38 *
bouaziz 0:7c305139fb85 39 * Description: This function initializes the mass storage interface
bouaziz 0:7c305139fb85 40 *
bouaziz 0:7c305139fb85 41 * Arguments : None
bouaziz 0:7c305139fb85 42 *
bouaziz 0:7c305139fb85 43 * Returns : OK if Success
bouaziz 0:7c305139fb85 44 * ERR_INVALID_BOOTSIG if Failed
bouaziz 0:7c305139fb85 45 *
bouaziz 0:7c305139fb85 46 **************************************************************************************************************
bouaziz 0:7c305139fb85 47 */
bouaziz 0:7c305139fb85 48
bouaziz 0:7c305139fb85 49 USB_INT32S MS_Init (USB_INT32U *blkSize, USB_INT32U *numBlks, USB_INT08U *inquiryResult)
bouaziz 0:7c305139fb85 50 {
bouaziz 0:7c305139fb85 51 USB_INT08U retry;
bouaziz 0:7c305139fb85 52 USB_INT32S rc;
bouaziz 0:7c305139fb85 53
bouaziz 0:7c305139fb85 54 MS_GetMaxLUN(); /* Get maximum logical unit number */
bouaziz 0:7c305139fb85 55 retry = 80;
bouaziz 0:7c305139fb85 56 while(retry) {
bouaziz 0:7c305139fb85 57 rc = MS_TestUnitReady(); /* Test whether the unit is ready */
bouaziz 0:7c305139fb85 58 if (rc == OK) {
bouaziz 0:7c305139fb85 59 break;
bouaziz 0:7c305139fb85 60 }
bouaziz 0:7c305139fb85 61 MS_GetSenseInfo(); /* Get sense information */
bouaziz 0:7c305139fb85 62 retry--;
bouaziz 0:7c305139fb85 63 }
bouaziz 0:7c305139fb85 64 if (rc != OK) {
bouaziz 0:7c305139fb85 65 PRINT_Err(rc);
bouaziz 0:7c305139fb85 66 return (rc);
bouaziz 0:7c305139fb85 67 }
bouaziz 0:7c305139fb85 68 rc = MS_ReadCapacity(numBlks, blkSize); /* Read capacity of the disk */
bouaziz 0:7c305139fb85 69 MS_BlkSize = *blkSize; // Set global
bouaziz 0:7c305139fb85 70 rc = MS_Inquire (inquiryResult);
bouaziz 0:7c305139fb85 71 return (rc);
bouaziz 0:7c305139fb85 72 }
bouaziz 0:7c305139fb85 73 /*
bouaziz 0:7c305139fb85 74 **************************************************************************************************************
bouaziz 0:7c305139fb85 75 * PARSE THE CONFIGURATION
bouaziz 0:7c305139fb85 76 *
bouaziz 0:7c305139fb85 77 * Description: This function is used to parse the configuration
bouaziz 0:7c305139fb85 78 *
bouaziz 0:7c305139fb85 79 * Arguments : None
bouaziz 0:7c305139fb85 80 *
bouaziz 0:7c305139fb85 81 * Returns : OK if Success
bouaziz 0:7c305139fb85 82 * ERR_INVALID_BOOTSIG if Failed
bouaziz 0:7c305139fb85 83 *
bouaziz 0:7c305139fb85 84 **************************************************************************************************************
bouaziz 0:7c305139fb85 85 */
bouaziz 0:7c305139fb85 86
bouaziz 0:7c305139fb85 87 USB_INT32S MS_ParseConfiguration (void)
bouaziz 0:7c305139fb85 88 {
bouaziz 0:7c305139fb85 89 volatile USB_INT08U *desc_ptr;
bouaziz 0:7c305139fb85 90 USB_INT08U ms_int_found;
bouaziz 0:7c305139fb85 91
bouaziz 0:7c305139fb85 92
bouaziz 0:7c305139fb85 93 desc_ptr = TDBuffer;
bouaziz 0:7c305139fb85 94 ms_int_found = 0;
bouaziz 0:7c305139fb85 95
bouaziz 0:7c305139fb85 96 if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION) {
bouaziz 0:7c305139fb85 97 return (ERR_BAD_CONFIGURATION);
bouaziz 0:7c305139fb85 98 }
bouaziz 0:7c305139fb85 99 desc_ptr += desc_ptr[0];
bouaziz 0:7c305139fb85 100
bouaziz 0:7c305139fb85 101 while (desc_ptr != TDBuffer + ReadLE16U(&TDBuffer[2])) {
bouaziz 0:7c305139fb85 102
bouaziz 0:7c305139fb85 103 switch (desc_ptr[1]) {
bouaziz 0:7c305139fb85 104
bouaziz 0:7c305139fb85 105 case USB_DESCRIPTOR_TYPE_INTERFACE: /* If it is an interface descriptor */
bouaziz 0:7c305139fb85 106 if (desc_ptr[5] == MASS_STORAGE_CLASS && /* check if the class is mass storage */
bouaziz 0:7c305139fb85 107 desc_ptr[6] == MASS_STORAGE_SUBCLASS_SCSI && /* check if the subclass is SCSI */
bouaziz 0:7c305139fb85 108 desc_ptr[7] == MASS_STORAGE_PROTOCOL_BO) { /* check if the protocol is Bulk only */
bouaziz 0:7c305139fb85 109 ms_int_found = 1;
bouaziz 0:7c305139fb85 110 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
bouaziz 0:7c305139fb85 111 }
bouaziz 0:7c305139fb85 112 break;
bouaziz 0:7c305139fb85 113
bouaziz 0:7c305139fb85 114 case USB_DESCRIPTOR_TYPE_ENDPOINT: /* If it is an endpoint descriptor */
bouaziz 0:7c305139fb85 115 if ((desc_ptr[3] & 0x03) == 0x02) { /* If it is Bulk endpoint */
bouaziz 0:7c305139fb85 116 if (desc_ptr[2] & 0x80) { /* If it is In endpoint */
bouaziz 0:7c305139fb85 117 EDBulkIn->Control = 1 | /* USB address */
bouaziz 0:7c305139fb85 118 ((desc_ptr[2] & 0x7F) << 7) | /* Endpoint address */
bouaziz 0:7c305139fb85 119 (2 << 11) | /* direction */
bouaziz 0:7c305139fb85 120 (ReadLE16U(&desc_ptr[4]) << 16); /* MaxPkt Size */
bouaziz 0:7c305139fb85 121 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
bouaziz 0:7c305139fb85 122 } else { /* If it is Out endpoint */
bouaziz 0:7c305139fb85 123 EDBulkOut->Control = 1 | /* USB address */
bouaziz 0:7c305139fb85 124 ((desc_ptr[2] & 0x7F) << 7) | /* Endpoint address */
bouaziz 0:7c305139fb85 125 (1 << 11) | /* direction */
bouaziz 0:7c305139fb85 126 (ReadLE16U(&desc_ptr[4]) << 16); /* MaxPkt Size */
bouaziz 0:7c305139fb85 127 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
bouaziz 0:7c305139fb85 128 }
bouaziz 0:7c305139fb85 129 } else { /* If it is not bulk end point */
bouaziz 0:7c305139fb85 130 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
bouaziz 0:7c305139fb85 131 }
bouaziz 0:7c305139fb85 132 break;
bouaziz 0:7c305139fb85 133
bouaziz 0:7c305139fb85 134 default: /* If the descriptor is neither interface nor endpoint */
bouaziz 0:7c305139fb85 135 desc_ptr += desc_ptr[0]; /* Move to next descriptor start */
bouaziz 0:7c305139fb85 136 break;
bouaziz 0:7c305139fb85 137 }
bouaziz 0:7c305139fb85 138 }
bouaziz 0:7c305139fb85 139 if (ms_int_found) {
bouaziz 0:7c305139fb85 140 PRINT_Log("Mass Storage device connected\r\n");
bouaziz 0:7c305139fb85 141 return (OK);
bouaziz 0:7c305139fb85 142 } else {
bouaziz 0:7c305139fb85 143 PRINT_Log("Not a Mass Storage device\r\n");
bouaziz 0:7c305139fb85 144 return (ERR_NO_MS_INTERFACE);
bouaziz 0:7c305139fb85 145 }
bouaziz 0:7c305139fb85 146 }
bouaziz 0:7c305139fb85 147
bouaziz 0:7c305139fb85 148 /*
bouaziz 0:7c305139fb85 149 **************************************************************************************************************
bouaziz 0:7c305139fb85 150 * GET MAXIMUM LOGICAL UNIT
bouaziz 0:7c305139fb85 151 *
bouaziz 0:7c305139fb85 152 * Description: This function returns the maximum logical unit from the device
bouaziz 0:7c305139fb85 153 *
bouaziz 0:7c305139fb85 154 * Arguments : None
bouaziz 0:7c305139fb85 155 *
bouaziz 0:7c305139fb85 156 * Returns : OK if Success
bouaziz 0:7c305139fb85 157 * ERR_INVALID_BOOTSIG if Failed
bouaziz 0:7c305139fb85 158 *
bouaziz 0:7c305139fb85 159 **************************************************************************************************************
bouaziz 0:7c305139fb85 160 */
bouaziz 0:7c305139fb85 161
bouaziz 0:7c305139fb85 162 USB_INT32S MS_GetMaxLUN (void)
bouaziz 0:7c305139fb85 163 {
bouaziz 0:7c305139fb85 164 USB_INT32S rc;
bouaziz 0:7c305139fb85 165
bouaziz 0:7c305139fb85 166
bouaziz 0:7c305139fb85 167 rc = Host_CtrlRecv(USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE,
bouaziz 0:7c305139fb85 168 MS_GET_MAX_LUN_REQ,
bouaziz 0:7c305139fb85 169 0,
bouaziz 0:7c305139fb85 170 0,
bouaziz 0:7c305139fb85 171 1,
bouaziz 0:7c305139fb85 172 TDBuffer);
bouaziz 0:7c305139fb85 173 return (rc);
bouaziz 0:7c305139fb85 174 }
bouaziz 0:7c305139fb85 175
bouaziz 0:7c305139fb85 176 /*
bouaziz 0:7c305139fb85 177 **************************************************************************************************************
bouaziz 0:7c305139fb85 178 * GET SENSE INFORMATION
bouaziz 0:7c305139fb85 179 *
bouaziz 0:7c305139fb85 180 * Description: This function is used to get sense information from the device
bouaziz 0:7c305139fb85 181 *
bouaziz 0:7c305139fb85 182 * Arguments : None
bouaziz 0:7c305139fb85 183 *
bouaziz 0:7c305139fb85 184 * Returns : OK if Success
bouaziz 0:7c305139fb85 185 * ERROR if Failed
bouaziz 0:7c305139fb85 186 *
bouaziz 0:7c305139fb85 187 **************************************************************************************************************
bouaziz 0:7c305139fb85 188 */
bouaziz 0:7c305139fb85 189
bouaziz 0:7c305139fb85 190 USB_INT32S MS_GetSenseInfo (void)
bouaziz 0:7c305139fb85 191 {
bouaziz 0:7c305139fb85 192 USB_INT32S rc;
bouaziz 0:7c305139fb85 193
bouaziz 0:7c305139fb85 194
bouaziz 0:7c305139fb85 195 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_REQUEST_SENSE, 6);
bouaziz 0:7c305139fb85 196 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
bouaziz 0:7c305139fb85 197 if (rc == OK) {
bouaziz 0:7c305139fb85 198 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, 18);
bouaziz 0:7c305139fb85 199 if (rc == OK) {
bouaziz 0:7c305139fb85 200 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
bouaziz 0:7c305139fb85 201 if (rc == OK) {
bouaziz 0:7c305139fb85 202 if (TDBuffer[12] != 0) {
bouaziz 0:7c305139fb85 203 rc = ERR_MS_CMD_FAILED;
bouaziz 0:7c305139fb85 204 }
bouaziz 0:7c305139fb85 205 }
bouaziz 0:7c305139fb85 206 }
bouaziz 0:7c305139fb85 207 }
bouaziz 0:7c305139fb85 208 return (rc);
bouaziz 0:7c305139fb85 209 }
bouaziz 0:7c305139fb85 210
bouaziz 0:7c305139fb85 211 /*
bouaziz 0:7c305139fb85 212 **************************************************************************************************************
bouaziz 0:7c305139fb85 213 * TEST UNIT READY
bouaziz 0:7c305139fb85 214 *
bouaziz 0:7c305139fb85 215 * Description: This function is used to test whether the unit is ready or not
bouaziz 0:7c305139fb85 216 *
bouaziz 0:7c305139fb85 217 * Arguments : None
bouaziz 0:7c305139fb85 218 *
bouaziz 0:7c305139fb85 219 * Returns : OK if Success
bouaziz 0:7c305139fb85 220 * ERROR if Failed
bouaziz 0:7c305139fb85 221 *
bouaziz 0:7c305139fb85 222 **************************************************************************************************************
bouaziz 0:7c305139fb85 223 */
bouaziz 0:7c305139fb85 224
bouaziz 0:7c305139fb85 225 USB_INT32S MS_TestUnitReady (void)
bouaziz 0:7c305139fb85 226 {
bouaziz 0:7c305139fb85 227 USB_INT32S rc;
bouaziz 0:7c305139fb85 228
bouaziz 0:7c305139fb85 229
bouaziz 0:7c305139fb85 230 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_NONE, SCSI_CMD_TEST_UNIT_READY, 6);
bouaziz 0:7c305139fb85 231 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
bouaziz 0:7c305139fb85 232 if (rc == OK) {
bouaziz 0:7c305139fb85 233 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
bouaziz 0:7c305139fb85 234 if (rc == OK) {
bouaziz 0:7c305139fb85 235 if (TDBuffer[12] != 0) {
bouaziz 0:7c305139fb85 236 rc = ERR_MS_CMD_FAILED;
bouaziz 0:7c305139fb85 237 }
bouaziz 0:7c305139fb85 238 }
bouaziz 0:7c305139fb85 239 }
bouaziz 0:7c305139fb85 240 return (rc);
bouaziz 0:7c305139fb85 241 }
bouaziz 0:7c305139fb85 242
bouaziz 0:7c305139fb85 243 /*
bouaziz 0:7c305139fb85 244 **************************************************************************************************************
bouaziz 0:7c305139fb85 245 * READ CAPACITY
bouaziz 0:7c305139fb85 246 *
bouaziz 0:7c305139fb85 247 * Description: This function is used to read the capacity of the mass storage device
bouaziz 0:7c305139fb85 248 *
bouaziz 0:7c305139fb85 249 * Arguments : None
bouaziz 0:7c305139fb85 250 *
bouaziz 0:7c305139fb85 251 * Returns : OK if Success
bouaziz 0:7c305139fb85 252 * ERROR if Failed
bouaziz 0:7c305139fb85 253 *
bouaziz 0:7c305139fb85 254 **************************************************************************************************************
bouaziz 0:7c305139fb85 255 */
bouaziz 0:7c305139fb85 256
bouaziz 0:7c305139fb85 257 USB_INT32S MS_ReadCapacity (USB_INT32U *numBlks, USB_INT32U *blkSize)
bouaziz 0:7c305139fb85 258 {
bouaziz 0:7c305139fb85 259 USB_INT32S rc;
bouaziz 0:7c305139fb85 260
bouaziz 0:7c305139fb85 261
bouaziz 0:7c305139fb85 262 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_READ_CAPACITY, 10);
bouaziz 0:7c305139fb85 263 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
bouaziz 0:7c305139fb85 264 if (rc == OK) {
bouaziz 0:7c305139fb85 265 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, 8);
bouaziz 0:7c305139fb85 266 if (rc == OK) {
bouaziz 0:7c305139fb85 267 if (numBlks)
bouaziz 0:7c305139fb85 268 *numBlks = ReadBE32U(&TDBuffer[0]);
bouaziz 0:7c305139fb85 269 if (blkSize)
bouaziz 0:7c305139fb85 270 *blkSize = ReadBE32U(&TDBuffer[4]);
bouaziz 0:7c305139fb85 271 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
bouaziz 0:7c305139fb85 272 if (rc == OK) {
bouaziz 0:7c305139fb85 273 if (TDBuffer[12] != 0) {
bouaziz 0:7c305139fb85 274 rc = ERR_MS_CMD_FAILED;
bouaziz 0:7c305139fb85 275 }
bouaziz 0:7c305139fb85 276 }
bouaziz 0:7c305139fb85 277 }
bouaziz 0:7c305139fb85 278 }
bouaziz 0:7c305139fb85 279 return (rc);
bouaziz 0:7c305139fb85 280 }
bouaziz 0:7c305139fb85 281
bouaziz 0:7c305139fb85 282
bouaziz 0:7c305139fb85 283
bouaziz 0:7c305139fb85 284 USB_INT32S MS_Inquire (USB_INT08U *response)
bouaziz 0:7c305139fb85 285 {
bouaziz 0:7c305139fb85 286 USB_INT32S rc;
bouaziz 0:7c305139fb85 287 USB_INT32U i;
bouaziz 0:7c305139fb85 288
bouaziz 0:7c305139fb85 289 Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_INQUIRY, 6);
bouaziz 0:7c305139fb85 290 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
bouaziz 0:7c305139fb85 291 if (rc == OK) {
bouaziz 0:7c305139fb85 292 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, INQUIRY_LENGTH);
bouaziz 0:7c305139fb85 293 if (rc == OK) {
bouaziz 0:7c305139fb85 294 if (response) {
bouaziz 0:7c305139fb85 295 for ( i = 0; i < INQUIRY_LENGTH; i++ )
bouaziz 0:7c305139fb85 296 *response++ = *TDBuffer++;
bouaziz 0:7c305139fb85 297 #if 0
bouaziz 0:7c305139fb85 298 MemCpy (response, TDBuffer, INQUIRY_LENGTH);
bouaziz 0:7c305139fb85 299 StrNullTrailingSpace (response->vendorID, SCSI_INQUIRY_VENDORCHARS);
bouaziz 0:7c305139fb85 300 StrNullTrailingSpace (response->productID, SCSI_INQUIRY_PRODUCTCHARS);
bouaziz 0:7c305139fb85 301 StrNullTrailingSpace (response->productRev, SCSI_INQUIRY_REVCHARS);
bouaziz 0:7c305139fb85 302 #endif
bouaziz 0:7c305139fb85 303 }
bouaziz 0:7c305139fb85 304 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
bouaziz 0:7c305139fb85 305 if (rc == OK) {
bouaziz 0:7c305139fb85 306 if (TDBuffer[12] != 0) { // bCSWStatus byte
bouaziz 0:7c305139fb85 307 rc = ERR_MS_CMD_FAILED;
bouaziz 0:7c305139fb85 308 }
bouaziz 0:7c305139fb85 309 }
bouaziz 0:7c305139fb85 310 }
bouaziz 0:7c305139fb85 311 }
bouaziz 0:7c305139fb85 312 return (rc);
bouaziz 0:7c305139fb85 313 }
bouaziz 0:7c305139fb85 314
bouaziz 0:7c305139fb85 315 /*
bouaziz 0:7c305139fb85 316 **************************************************************************************************************
bouaziz 0:7c305139fb85 317 * RECEIVE THE BULK DATA
bouaziz 0:7c305139fb85 318 *
bouaziz 0:7c305139fb85 319 * Description: This function is used to receive the bulk data
bouaziz 0:7c305139fb85 320 *
bouaziz 0:7c305139fb85 321 * Arguments : None
bouaziz 0:7c305139fb85 322 *
bouaziz 0:7c305139fb85 323 * Returns : OK if Success
bouaziz 0:7c305139fb85 324 * ERR_INVALID_BOOTSIG if Failed
bouaziz 0:7c305139fb85 325 *
bouaziz 0:7c305139fb85 326 **************************************************************************************************************
bouaziz 0:7c305139fb85 327 */
bouaziz 0:7c305139fb85 328
bouaziz 0:7c305139fb85 329 USB_INT32S MS_BulkRecv ( USB_INT32U block_number,
bouaziz 0:7c305139fb85 330 USB_INT16U num_blocks,
bouaziz 0:7c305139fb85 331 volatile USB_INT08U *user_buffer)
bouaziz 0:7c305139fb85 332 {
bouaziz 0:7c305139fb85 333 USB_INT32S rc;
bouaziz 0:7c305139fb85 334 int i;
bouaziz 0:7c305139fb85 335 volatile USB_INT08U *c = user_buffer;
bouaziz 0:7c305139fb85 336 for (i=0;i<MS_BlkSize*num_blocks;i++)
bouaziz 0:7c305139fb85 337 *c++ = 0;
bouaziz 0:7c305139fb85 338
bouaziz 0:7c305139fb85 339
bouaziz 0:7c305139fb85 340 Fill_MSCommand(block_number, MS_BlkSize, num_blocks, MS_DATA_DIR_IN, SCSI_CMD_READ_10, 10);
bouaziz 0:7c305139fb85 341
bouaziz 0:7c305139fb85 342 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
bouaziz 0:7c305139fb85 343 if (rc == OK) {
bouaziz 0:7c305139fb85 344 rc = Host_ProcessTD(EDBulkIn, TD_IN, user_buffer, MS_BlkSize * num_blocks);
bouaziz 0:7c305139fb85 345 if (rc == OK) {
bouaziz 0:7c305139fb85 346 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
bouaziz 0:7c305139fb85 347 if (rc == OK) {
bouaziz 0:7c305139fb85 348 if (TDBuffer[12] != 0) {
bouaziz 0:7c305139fb85 349 rc = ERR_MS_CMD_FAILED;
bouaziz 0:7c305139fb85 350 }
bouaziz 0:7c305139fb85 351 }
bouaziz 0:7c305139fb85 352 }
bouaziz 0:7c305139fb85 353 }
bouaziz 0:7c305139fb85 354 return (rc);
bouaziz 0:7c305139fb85 355 }
bouaziz 0:7c305139fb85 356
bouaziz 0:7c305139fb85 357 /*
bouaziz 0:7c305139fb85 358 **************************************************************************************************************
bouaziz 0:7c305139fb85 359 * SEND BULK DATA
bouaziz 0:7c305139fb85 360 *
bouaziz 0:7c305139fb85 361 * Description: This function is used to send the bulk data
bouaziz 0:7c305139fb85 362 *
bouaziz 0:7c305139fb85 363 * Arguments : None
bouaziz 0:7c305139fb85 364 *
bouaziz 0:7c305139fb85 365 * Returns : OK if Success
bouaziz 0:7c305139fb85 366 * ERR_INVALID_BOOTSIG if Failed
bouaziz 0:7c305139fb85 367 *
bouaziz 0:7c305139fb85 368 **************************************************************************************************************
bouaziz 0:7c305139fb85 369 */
bouaziz 0:7c305139fb85 370
bouaziz 0:7c305139fb85 371 USB_INT32S MS_BulkSend ( USB_INT32U block_number,
bouaziz 0:7c305139fb85 372 USB_INT16U num_blocks,
bouaziz 0:7c305139fb85 373 volatile USB_INT08U *user_buffer)
bouaziz 0:7c305139fb85 374 {
bouaziz 0:7c305139fb85 375 USB_INT32S rc;
bouaziz 0:7c305139fb85 376
bouaziz 0:7c305139fb85 377
bouaziz 0:7c305139fb85 378 Fill_MSCommand(block_number, MS_BlkSize, num_blocks, MS_DATA_DIR_OUT, SCSI_CMD_WRITE_10, 10);
bouaziz 0:7c305139fb85 379
bouaziz 0:7c305139fb85 380 rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
bouaziz 0:7c305139fb85 381 if (rc == OK) {
bouaziz 0:7c305139fb85 382 rc = Host_ProcessTD(EDBulkOut, TD_OUT, user_buffer, MS_BlkSize * num_blocks);
bouaziz 0:7c305139fb85 383 if (rc == OK) {
bouaziz 0:7c305139fb85 384 rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
bouaziz 0:7c305139fb85 385 if (rc == OK) {
bouaziz 0:7c305139fb85 386 if (TDBuffer[12] != 0) {
bouaziz 0:7c305139fb85 387 rc = ERR_MS_CMD_FAILED;
bouaziz 0:7c305139fb85 388 }
bouaziz 0:7c305139fb85 389 }
bouaziz 0:7c305139fb85 390 }
bouaziz 0:7c305139fb85 391 }
bouaziz 0:7c305139fb85 392 return (rc);
bouaziz 0:7c305139fb85 393 }
bouaziz 0:7c305139fb85 394
bouaziz 0:7c305139fb85 395 /*
bouaziz 0:7c305139fb85 396 **************************************************************************************************************
bouaziz 0:7c305139fb85 397 * FILL MASS STORAGE COMMAND
bouaziz 0:7c305139fb85 398 *
bouaziz 0:7c305139fb85 399 * Description: This function is used to fill the mass storage command
bouaziz 0:7c305139fb85 400 *
bouaziz 0:7c305139fb85 401 * Arguments : None
bouaziz 0:7c305139fb85 402 *
bouaziz 0:7c305139fb85 403 * Returns : OK if Success
bouaziz 0:7c305139fb85 404 * ERR_INVALID_BOOTSIG if Failed
bouaziz 0:7c305139fb85 405 *
bouaziz 0:7c305139fb85 406 **************************************************************************************************************
bouaziz 0:7c305139fb85 407 */
bouaziz 0:7c305139fb85 408
bouaziz 0:7c305139fb85 409 void Fill_MSCommand (USB_INT32U block_number,
bouaziz 0:7c305139fb85 410 USB_INT32U block_size,
bouaziz 0:7c305139fb85 411 USB_INT16U num_blocks,
bouaziz 0:7c305139fb85 412 MS_DATA_DIR direction,
bouaziz 0:7c305139fb85 413 USB_INT08U scsi_cmd,
bouaziz 0:7c305139fb85 414 USB_INT08U scsi_cmd_len)
bouaziz 0:7c305139fb85 415 {
bouaziz 0:7c305139fb85 416 USB_INT32U data_len;
bouaziz 0:7c305139fb85 417 static USB_INT32U tag_cnt = 0;
bouaziz 0:7c305139fb85 418 USB_INT32U cnt;
bouaziz 0:7c305139fb85 419
bouaziz 0:7c305139fb85 420
bouaziz 0:7c305139fb85 421 for (cnt = 0; cnt < CBW_SIZE; cnt++) {
bouaziz 0:7c305139fb85 422 TDBuffer[cnt] = 0;
bouaziz 0:7c305139fb85 423 }
bouaziz 0:7c305139fb85 424 switch(scsi_cmd) {
bouaziz 0:7c305139fb85 425
bouaziz 0:7c305139fb85 426 case SCSI_CMD_TEST_UNIT_READY:
bouaziz 0:7c305139fb85 427 data_len = 0;
bouaziz 0:7c305139fb85 428 break;
bouaziz 0:7c305139fb85 429 case SCSI_CMD_READ_CAPACITY:
bouaziz 0:7c305139fb85 430 data_len = 8;
bouaziz 0:7c305139fb85 431 break;
bouaziz 0:7c305139fb85 432 case SCSI_CMD_REQUEST_SENSE:
bouaziz 0:7c305139fb85 433 data_len = 18;
bouaziz 0:7c305139fb85 434 break;
bouaziz 0:7c305139fb85 435 case SCSI_CMD_INQUIRY:
bouaziz 0:7c305139fb85 436 data_len = 36;
bouaziz 0:7c305139fb85 437 break;
bouaziz 0:7c305139fb85 438 default:
bouaziz 0:7c305139fb85 439 data_len = block_size * num_blocks;
bouaziz 0:7c305139fb85 440 break;
bouaziz 0:7c305139fb85 441 }
bouaziz 0:7c305139fb85 442 WriteLE32U(TDBuffer, CBW_SIGNATURE);
bouaziz 0:7c305139fb85 443 WriteLE32U(&TDBuffer[4], tag_cnt);
bouaziz 0:7c305139fb85 444 WriteLE32U(&TDBuffer[8], data_len);
bouaziz 0:7c305139fb85 445 TDBuffer[12] = (direction == MS_DATA_DIR_NONE) ? 0 : direction;
bouaziz 0:7c305139fb85 446 TDBuffer[14] = scsi_cmd_len; /* Length of the CBW */
bouaziz 0:7c305139fb85 447 TDBuffer[15] = scsi_cmd;
bouaziz 0:7c305139fb85 448 if ((scsi_cmd == SCSI_CMD_REQUEST_SENSE)
bouaziz 0:7c305139fb85 449 || (scsi_cmd == SCSI_CMD_INQUIRY)) {
bouaziz 0:7c305139fb85 450 TDBuffer[19] = (USB_INT08U)data_len;
bouaziz 0:7c305139fb85 451 } else {
bouaziz 0:7c305139fb85 452 WriteBE32U(&TDBuffer[17], block_number);
bouaziz 0:7c305139fb85 453 }
bouaziz 0:7c305139fb85 454 WriteBE16U(&TDBuffer[22], num_blocks);
bouaziz 0:7c305139fb85 455 }