Dependents:   sample_collection_for_starboard_orange starboard_orange_samples

Committer:
chris
Date:
Wed May 19 06:31:49 2010 +0000
Revision:
0:f4e330489777

        

Who changed what in which revision?

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