Dependencies:   mbed

Committer:
iva2k
Date:
Thu Jan 21 01:15:42 2010 +0000
Revision:
0:1802fb31b938

        

Who changed what in which revision?

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