Sertel USB Log

Fork of MSCFileSystem by Chris Styles

Committer:
chris
Date:
Tue Apr 05 23:36:08 2011 +0000
Revision:
0:3e7d2baed4b4

        

Who changed what in which revision?

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