This program is an example of of using the MSCUSBHost code with a raw build of ELM Chan Fat Fs. This was done to add both Long File Name Support along with proper time/date stamps (assuming you have a battery hooked up to keep time). This code exposes the Chan API (see main.cpp) and is NOT a c++ class: http://elm-chan.org/fsw/ff/00index_e.html The diskio.c file has the mapping needed to link the filesystem to the MSC stuff

Dependencies:   mbed

Committer:
emh203
Date:
Sun Jan 23 18:35:43 2011 +0000
Revision:
0:2dbbafe1b1fb
1st test version.   Test with raw mbed and Samtec USB-RA type A connector wired directly to pins.

Who changed what in which revision?

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