hattori&ide

Dependencies:   mbed

Committer:
hattori_atsushi
Date:
Sun Dec 18 08:16:01 2022 +0000
Revision:
0:f77369cabd75
hattori

Who changed what in which revision?

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