Dependencies:   mbed

Committer:
slowness
Date:
Sun Aug 28 16:16:43 2011 +0000
Revision:
0:2063c10a1022

        

Who changed what in which revision?

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