This is a lib to use ChaNFS lib with USB mass storages like USB Sticks .. Long file names work

Dependencies:  

Dependents:   WeatherStation

Committer:
NeoBelerophon
Date:
Tue Feb 01 22:14:30 2011 +0000
Revision:
0:f0133ccac168
Initial commit

Who changed what in which revision?

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