Testing

Dependencies:   mbed FatFileSystemCpp

Committer:
Richard_Xiong
Date:
Fri Apr 24 01:49:33 2020 +0000
Revision:
0:1855e9b8c2a2
USBTesting

Who changed what in which revision?

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