Committer:
apm_litoral
Date:
Tue Apr 10 03:34:23 2012 +0000
Revision:
0:78a36db66fbb

        

Who changed what in which revision?

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