Dependencies:   mbed

Committer:
lynxeyed_atsu
Date:
Fri Jan 21 08:39:48 2011 +0000
Revision:
0:63ed631d8c3a

        

Who changed what in which revision?

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