Dependencies:   mbed

Committer:
chris
Date:
Sat Mar 13 17:19:08 2010 +0000
Revision:
0:144fed3d9420

        

Who changed what in which revision?

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