firmware update from USB stick, does not work properly. If someone can get it work, please inform me.

Dependencies:   mbed

Committer:
Markus_Paar
Date:
Fri Apr 01 07:51:52 2011 +0000
Revision:
0:dad421e28e26
0.1

Who changed what in which revision?

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