| Line No. | Rev | Author | Line |
|---|---|---|---|
| 1 | 32 | kaklik | /********************************************************************* |
| 2 | File Information: |
||
| 3 | FileName: usb_function_msd.c |
||
| 4 | Dependencies: See INCLUDES section below |
||
| 5 | Processor: PIC18, PIC24, or PIC32 |
||
| 6 | Compiler: C18, C30, or C32 |
||
| 7 | Company: Microchip Technology, Inc. |
||
| 8 | |||
| 9 | Software License Agreement |
||
| 10 | |||
| 11 | The software supplied herewith by Microchip Technology Incorporated |
||
| 12 | (the Company) for its PICmicro® Microcontroller is intended and |
||
| 13 | supplied to you, the Companys customer, for use solely and |
||
| 14 | exclusively on Microchip PICmicro Microcontroller products. The |
||
| 15 | software is owned by the Company and/or its supplier, and is |
||
| 16 | protected under applicable copyright laws. All rights are reserved. |
||
| 17 | Any use in violation of the foregoing restrictions may subject the |
||
| 18 | user to criminal sanctions under applicable laws, as well as to |
||
| 19 | civil liability for the breach of the terms and conditions of this |
||
| 20 | license. |
||
| 21 | |||
| 22 | THIS SOFTWARE IS PROVIDED IN AN AS IS CONDITION. NO WARRANTIES, |
||
| 23 | WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED |
||
| 24 | TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
||
| 25 | PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, |
||
| 26 | IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR |
||
| 27 | CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. |
||
| 28 | |||
| 29 | Summary: |
||
| 30 | This file contains functions, macros, definitions, variables, |
||
| 31 | datatypes, etc. that are required for use of the MSD function |
||
| 32 | driver. This file should be included in projects that use the MSD |
||
| 33 | \function driver. |
||
| 34 | |||
| 35 | |||
| 36 | |||
| 37 | This file is located in the "\<Install Directory\>\\Microchip\\USB\\MSD |
||
| 38 | Device Driver" directory. |
||
| 39 | |||
| 40 | Description: |
||
| 41 | USB MSD Function Driver File |
||
| 42 | |||
| 43 | This file contains functions, macros, definitions, variables, |
||
| 44 | datatypes, etc. that are required for use of the MSD function |
||
| 45 | driver. This file should be included in projects that use the MSD |
||
| 46 | \function driver. |
||
| 47 | |||
| 48 | This file is located in the "\<Install Directory\>\\Microchip\\USB\\MSD |
||
| 49 | Device Driver" directory. |
||
| 50 | |||
| 51 | When including this file in a new project, this file can either be |
||
| 52 | referenced from the directory in which it was installed or copied |
||
| 53 | directly into the user application folder. If the first method is |
||
| 54 | chosen to keep the file located in the folder in which it is installed |
||
| 55 | then include paths need to be added so that the library and the |
||
| 56 | application both know where to reference each others files. If the |
||
| 57 | application folder is located in the same folder as the Microchip |
||
| 58 | folder (like the current demo folders), then the following include |
||
| 59 | paths need to be added to the application's project: |
||
| 60 | |||
| 61 | ..\\..\\Microchip\\Include |
||
| 62 | . |
||
| 63 | |||
| 64 | If a different directory structure is used, modify the paths as |
||
| 65 | required. An example using absolute paths instead of relative paths |
||
| 66 | would be the following: |
||
| 67 | |||
| 68 | C:\\Microchip Solutions\\Microchip\\Include |
||
| 69 | |||
| 70 | C:\\Microchip Solutions\\My Demo Application |
||
| 71 | |||
| 72 | Change History: |
||
| 73 | Rev Description |
||
| 74 | ---------- ---------------------------------------------------------- |
||
| 75 | 2.6 - 2.7a No change |
||
| 76 | |||
| 77 | ********************************************************************/ |
||
| 78 | |||
| 79 | /** I N C L U D E S **************************************************/ |
||
| 80 | #include "USB/USB.h" |
||
| 81 | #include "HardwareProfile.h" |
||
| 82 | #include "FSConfig.h" |
||
| 83 | |||
| 84 | #include "./USB/usb_function_msd.h" |
||
| 85 | |||
| 86 | #ifdef USB_USE_MSD |
||
| 87 | |||
| 88 | #if MAX_LUN == 0 |
||
| 89 | #define LUN_INDEX 0 |
||
| 90 | #else |
||
| 91 | #define LUN_INDEX gblCBW.bCBWLUN |
||
| 92 | #endif |
||
| 93 | |||
| 94 | #if defined(__C30__) || defined(__C32__) |
||
| 95 | #if defined(USE_INTERNAL_FLASH) |
||
| 96 | #include "MDD File System\Internal Flash.h" |
||
| 97 | #endif |
||
| 98 | |||
| 99 | #if defined(USE_SD_INTERFACE_WITH_SPI) |
||
| 100 | #include "MDD File System\SD-SPI.h" |
||
| 101 | #endif |
||
| 102 | |||
| 103 | extern LUN_FUNCTIONS LUN[MAX_LUN + 1]; |
||
| 104 | #define LUNMediaInitialize() LUN[LUN_INDEX].MediaInitialize() |
||
| 105 | #define LUNReadCapacity() LUN[LUN_INDEX].ReadCapacity() |
||
| 106 | #define LUNReadSectorSize() LUN[LUN_INDEX].ReadSectorSize() |
||
| 107 | #define LUNMediaDetect() LUN[LUN_INDEX].MediaDetect() |
||
| 108 | #define LUNSectorWrite(bLBA,pDest,Write0) LUN[LUN_INDEX].SectorWrite(bLBA, pDest, Write0) |
||
| 109 | #define LUNWriteProtectState() LUN[LUN_INDEX].WriteProtectState() |
||
| 110 | #define LUNSectorRead(bLBA,pSrc) LUN[LUN_INDEX].SectorRead(bLBA, pSrc) |
||
| 111 | #else |
||
| 112 | #if defined(USE_INTERNAL_FLASH) |
||
| 113 | #include "MDD File System\Internal Flash.h" |
||
| 114 | #endif |
||
| 115 | |||
| 116 | #if defined(USE_SD_INTERFACE_WITH_SPI) |
||
| 117 | #include "MDD File System\SD-SPI.h" |
||
| 118 | #endif |
||
| 119 | |||
| 120 | #define LUNMediaInitialize() MDD_MediaInitialize() |
||
| 121 | #define LUNReadCapacity() MDD_ReadCapacity() |
||
| 122 | #define LUNReadSectorSize() MDD_ReadSectorSize() |
||
| 123 | #define LUNMediaDetect() MDD_MediaDetect() |
||
| 124 | #define LUNSectorWrite(bLBA,pDest,Write0) MDD_SectorWrite(bLBA, pDest, Write0) |
||
| 125 | #define LUNWriteProtectState() MDD_WriteProtectState() |
||
| 126 | #define LUNSectorRead(bLBA,pSrc) MDD_SectorRead(bLBA, pSrc) |
||
| 127 | #endif |
||
| 128 | |||
| 129 | /** V A R I A B L E S ************************************************/ |
||
| 130 | #pragma udata |
||
| 131 | BYTE MSD_State; // Takes values MSD_WAIT, MSD_DATA_IN or MSD_DATA_OUT |
||
| 132 | USB_MSD_CBW gblCBW; |
||
| 133 | BYTE gblCBWLength; |
||
| 134 | RequestSenseResponse gblSenseData[MAX_LUN + 1]; |
||
| 135 | BYTE *ptrNextData; |
||
| 136 | USB_HANDLE USBMSDOutHandle; |
||
| 137 | USB_HANDLE USBMSDInHandle; |
||
| 138 | WORD MSBBufferIndex; |
||
| 139 | WORD gblMediaPresent; |
||
| 140 | BOOL SoftDetach[MAX_LUN + 1]; |
||
| 141 | static BYTE MSDCommandState = MSD_COMMAND_WAIT; |
||
| 142 | |||
| 143 | static WORD_VAL TransferLength; |
||
| 144 | static DWORD_VAL LBA; |
||
| 145 | |||
| 146 | /* |
||
| 147 | * Number of Blocks and Block Length are global because |
||
| 148 | * for every READ_10 and WRITE_10 command need to verify if the last LBA |
||
| 149 | * is less than gblNumBLKS |
||
| 150 | */ |
||
| 151 | DWORD_VAL gblNumBLKS,gblBLKLen; |
||
| 152 | extern const ROM InquiryResponse inq_resp; |
||
| 153 | |||
| 154 | /** P R I V A T E P R O T O T Y P E S ***************************************/ |
||
| 155 | BYTE MSDProcessCommand(void); |
||
| 156 | BYTE MSDReadHandler(void); |
||
| 157 | BYTE MSDWriteHandler(void); |
||
| 158 | void ResetSenseData(void); |
||
| 159 | |||
| 160 | /** D E C L A R A T I O N S **************************************************/ |
||
| 161 | #pragma code |
||
| 162 | |||
| 163 | /** C L A S S S P E C I F I C R E Q ****************************************/ |
||
| 164 | |||
| 165 | /****************************************************************************** |
||
| 166 | Function: |
||
| 167 | void USBMSDInit(void) |
||
| 168 | |||
| 169 | Summary: |
||
| 170 | This routine initializes the MSD class packet handles, prepares to |
||
| 171 | receive a MSD packet, and initializes the MSD state machine. This |
||
| 172 | \function should be called once after the device is enumerated. |
||
| 173 | |||
| 174 | Description: |
||
| 175 | This routine initializes the MSD class packet handles, prepares to |
||
| 176 | receive a MSD packet, and initializes the MSD state machine. This |
||
| 177 | \function should be called once after the device is enumerated. |
||
| 178 | |||
| 179 | Typical Usage: |
||
| 180 | <code> |
||
| 181 | void USBCBInitEP(void) |
||
| 182 | { |
||
| 183 | USBEnableEndpoint(MSD_DATA_IN_EP,USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP); |
||
| 184 | USBMSDInit(); |
||
| 185 | } |
||
| 186 | </code> |
||
| 187 | Conditions: |
||
| 188 | The device should already be enumerated with a configuration that |
||
| 189 | supports MSD before calling this function. |
||
| 190 | |||
| 191 | Paramters: None |
||
| 192 | |||
| 193 | Remarks: |
||
| 194 | None |
||
| 195 | ****************************************************************************/ |
||
| 196 | void USBMSDInit(void) |
||
| 197 | { |
||
| 198 | USBMSDInHandle = 0; |
||
| 199 | USBMSDOutHandle = USBRxOnePacket(MSD_DATA_OUT_EP,(BYTE*)&msd_cbw,MSD_OUT_EP_SIZE); |
||
| 200 | MSD_State=MSD_WAIT; |
||
| 201 | gblNumBLKS.Val = 0; |
||
| 202 | gblBLKLen.Val = 0; |
||
| 203 | |||
| 204 | gblMediaPresent = 0; |
||
| 205 | |||
| 206 | //For each of the possible logical units |
||
| 207 | for(gblCBW.bCBWLUN=0;gblCBW.bCBWLUN<(MAX_LUN + 1);gblCBW.bCBWLUN++) |
||
| 208 | { |
||
| 209 | //clear all of the soft detach variables |
||
| 210 | SoftDetach[gblCBW.bCBWLUN] = FALSE; |
||
| 211 | |||
| 212 | //see if the media is attached |
||
| 213 | if(LUNMediaDetect()) |
||
| 214 | { |
||
| 215 | //initialize the media |
||
| 216 | if(LUNMediaInitialize()) |
||
| 217 | { |
||
| 218 | //if the media was present and successfully initialized |
||
| 219 | // then mark and indicator that the media is ready |
||
| 220 | gblMediaPresent |= (1<<gblCBW.bCBWLUN); |
||
| 221 | } |
||
| 222 | } |
||
| 223 | ResetSenseData(); |
||
| 224 | } |
||
| 225 | } |
||
| 226 | |||
| 227 | /****************************************************************************** |
||
| 228 | Function: |
||
| 229 | void USBCheckMSDRequest(void) |
||
| 230 | |||
| 231 | Summary: |
||
| 232 | This routine handles MSD specific request that happen on EP0. |
||
| 233 | This function should be called from the USBCBCheckOtherReq() call back |
||
| 234 | function whenever implementing an MSD device. |
||
| 235 | |||
| 236 | Description: |
||
| 237 | This routine handles MSD specific request that happen on EP0. These |
||
| 238 | include, but are not limited to, the standard RESET and GET_MAX_LUN |
||
| 239 | command requests. This function should be called from the |
||
| 240 | USBCBCheckOtherReq() call back function whenever using an MSD device. |
||
| 241 | |||
| 242 | Typical Usage: |
||
| 243 | <code> |
||
| 244 | void USBCBCheckOtherReq(void) |
||
| 245 | { |
||
| 246 | //Since the stack didn't handle the request I need to check |
||
| 247 | // my class drivers to see if it is for them |
||
| 248 | USBCheckMSDRequest(); |
||
| 249 | } |
||
| 250 | </code> |
||
| 251 | |||
| 252 | PreCondition: |
||
| 253 | None |
||
| 254 | |||
| 255 | Parameters: |
||
| 256 | None |
||
| 257 | |||
| 258 | Return Values: |
||
| 259 | None |
||
| 260 | |||
| 261 | Remarks: |
||
| 262 | None |
||
| 263 | |||
| 264 | *****************************************************************************/ |
||
| 265 | void USBCheckMSDRequest(void) |
||
| 266 | { |
||
| 267 | if(SetupPkt.Recipient != USB_SETUP_RECIPIENT_INTERFACE_BITFIELD) return; |
||
| 268 | if(SetupPkt.bIntfID != MSD_INTF_ID) return; |
||
| 269 | |||
| 270 | switch(SetupPkt.bRequest) |
||
| 271 | { |
||
| 272 | case MSD_RESET: |
||
| 273 | break; |
||
| 274 | case GET_MAX_LUN: |
||
| 275 | //If the host asks for the maximum number of logical units |
||
| 276 | // then send out a packet with that information |
||
| 277 | CtrlTrfData[0] = MAX_LUN; |
||
| 278 | USBEP0SendRAMPtr((BYTE*)&CtrlTrfData[0],1,USB_EP0_INCLUDE_ZERO); |
||
| 279 | break; |
||
| 280 | } //end switch(SetupPkt.bRequest) |
||
| 281 | } |
||
| 282 | |||
| 283 | /********************************************************************************* |
||
| 284 | Function: |
||
| 285 | BYTE MSDTasks(void) |
||
| 286 | |||
| 287 | Summary: |
||
| 288 | This function runs the MSD class state machines and all of its |
||
| 289 | sub-systems. This function should be called periodically once the |
||
| 290 | device is in the configured state in order to keep the MSD state |
||
| 291 | machine going. |
||
| 292 | Description: |
||
| 293 | This function runs the MSD class state machines and all of its |
||
| 294 | sub-systems. This function should be called periodically once the |
||
| 295 | device is in the configured state in order to keep the MSD state |
||
| 296 | machine going. |
||
| 297 | |||
| 298 | Typical Usage: |
||
| 299 | <code> |
||
| 300 | void main(void) |
||
| 301 | { |
||
| 302 | USBDeviceInit(); |
||
| 303 | while(1) |
||
| 304 | { |
||
| 305 | USBDeviceTasks(); |
||
| 306 | if((USBGetDeviceState() \< CONFIGURED_STATE) || |
||
| 307 | (USBIsDeviceSuspended() == TRUE)) |
||
| 308 | { |
||
| 309 | //Either the device is not configured or we are suspended |
||
| 310 | // so we don't want to do execute any application code |
||
| 311 | continue; //go back to the top of the while loop |
||
| 312 | } |
||
| 313 | else |
||
| 314 | { |
||
| 315 | //Keep the MSD state machine going |
||
| 316 | MSDTasks(); |
||
| 317 | |||
| 318 | //Run application code. |
||
| 319 | UserApplication(); |
||
| 320 | } |
||
| 321 | } |
||
| 322 | } |
||
| 323 | </code> |
||
| 324 | Conditions: |
||
| 325 | None |
||
| 326 | Return Values: |
||
| 327 | BYTE - the current state of the MSD state machine the valid values are |
||
| 328 | defined in MSD.h under the MSDTasks state machine declaration section. |
||
| 329 | The possible values are the following\: |
||
| 330 | * MSD_WAIT |
||
| 331 | * MSD_DATA_IN |
||
| 332 | * MSD_DATA_OUT |
||
| 333 | * MSD_SEND_CSW |
||
| 334 | Remarks: |
||
| 335 | None |
||
| 336 | *********************************************************************************/ |
||
| 337 | BYTE MSDTasks(void) |
||
| 338 | { |
||
| 339 | BYTE i; |
||
| 340 | |||
| 341 | switch(MSD_State) |
||
| 342 | { |
||
| 343 | case MSD_WAIT: |
||
| 344 | { |
||
| 345 | //If the MSD state machine is waiting for something to happen |
||
| 346 | if(!USBHandleBusy(USBMSDOutHandle)) |
||
| 347 | { |
||
| 348 | //If we received an OUT packet from the host |
||
| 349 | // then copy the data from the buffer to a global |
||
| 350 | // buffer so that we can keep the information but |
||
| 351 | // reuse the buffer |
||
| 352 | gblCBW.dCBWSignature=msd_cbw.dCBWSignature; |
||
| 353 | gblCBW.dCBWTag=msd_cbw.dCBWTag; |
||
| 354 | gblCBW.dCBWDataTransferLength=msd_cbw.dCBWDataTransferLength; |
||
| 355 | gblCBW.bCBWFlags=msd_cbw.bCBWFlags; |
||
| 356 | gblCBW.bCBWLUN=msd_cbw.bCBWLUN; |
||
| 357 | gblCBW.bCBWCBLength=msd_cbw.bCBWCBLength; // 3 MSB are zero |
||
| 358 | |||
| 359 | for (i=0;i<msd_cbw.bCBWCBLength;i++) |
||
| 360 | { |
||
| 361 | gblCBW.CBWCB[i]=msd_cbw.CBWCB[i]; |
||
| 362 | } |
||
| 363 | |||
| 364 | gblCBWLength=USBHandleGetLength(USBMSDOutHandle); |
||
| 365 | |||
| 366 | //If this CBW is valid? |
||
| 367 | if ((gblCBWLength==MSD_CBW_SIZE)&&(gblCBW.dCBWSignature==0x43425355)) |
||
| 368 | { |
||
| 369 | //Is this CBW meaningful? |
||
| 370 | if((gblCBW.bCBWLUN<=0x0f) |
||
| 371 | &&(gblCBW.bCBWCBLength<=0x10) |
||
| 372 | &&(gblCBW.bCBWCBLength>=0x01) |
||
| 373 | &&(gblCBW.bCBWFlags==0x00||gblCBW.bCBWFlags==0x80)) |
||
| 374 | { |
||
| 375 | //Prepare the CSW to be sent |
||
| 376 | msd_csw.dCSWTag=gblCBW.dCBWTag; |
||
| 377 | msd_csw.dCSWSignature=0x53425355; |
||
| 378 | |||
| 379 | /* If direction is device to host*/ |
||
| 380 | if (gblCBW.bCBWFlags==0x80) |
||
| 381 | { |
||
| 382 | MSD_State=MSD_DATA_IN; |
||
| 383 | } |
||
| 384 | else if (gblCBW.bCBWFlags==0x00) |
||
| 385 | { |
||
| 386 | /* If direction is host to device*/ |
||
| 387 | /* prepare to read data in msd_buffer */ |
||
| 388 | MSD_State=MSD_DATA_OUT; |
||
| 389 | } |
||
| 390 | } |
||
| 391 | } |
||
| 392 | } |
||
| 393 | break; |
||
| 394 | } |
||
| 395 | case MSD_DATA_IN: |
||
| 396 | if(MSDProcessCommand() == MSD_COMMAND_WAIT) |
||
| 397 | { |
||
| 398 | // Done processing the command, send the status |
||
| 399 | MSD_State = MSD_SEND_CSW; |
||
| 400 | } |
||
| 401 | break; |
||
| 402 | case MSD_DATA_OUT: |
||
| 403 | if(MSDProcessCommand() == MSD_COMMAND_WAIT) |
||
| 404 | { |
||
| 405 | /* Finished receiving the data prepare and send the status */ |
||
| 406 | if ((msd_csw.bCSWStatus==0x00)&&(msd_csw.dCSWDataResidue!=0)) |
||
| 407 | { |
||
| 408 | msd_csw.bCSWStatus=0x02; |
||
| 409 | } |
||
| 410 | MSD_State = MSD_SEND_CSW; |
||
| 411 | } |
||
| 412 | break; |
||
| 413 | case MSD_SEND_CSW: |
||
| 414 | if(USBHandleBusy(USBMSDInHandle)) |
||
| 415 | { |
||
| 416 | //The TX buffer is not ready to send the status yet. |
||
| 417 | break; |
||
| 418 | } |
||
| 419 | |||
| 420 | USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,(BYTE*)&msd_csw,MSD_CSW_SIZE); |
||
| 421 | |||
| 422 | //Get ready for next command to come in |
||
| 423 | if(!USBHandleBusy(USBMSDOutHandle)) |
||
| 424 | { |
||
| 425 | USBMSDOutHandle = USBRxOnePacket(MSD_DATA_OUT_EP,(BYTE*)&msd_cbw,sizeof(msd_cbw)); |
||
| 426 | } |
||
| 427 | |||
| 428 | MSD_State=MSD_WAIT; |
||
| 429 | break; |
||
| 430 | } |
||
| 431 | |||
| 432 | return MSD_State; |
||
| 433 | } |
||
| 434 | |||
| 435 | /****************************************************************************** |
||
| 436 | Function: |
||
| 437 | void MSDProcessCommandMediaPresent(void) |
||
| 438 | |||
| 439 | Description: |
||
| 440 | This funtion processes a command received through the MSD |
||
| 441 | class driver |
||
| 442 | |||
| 443 | PreCondition: |
||
| 444 | None |
||
| 445 | |||
| 446 | Paramters: |
||
| 447 | None |
||
| 448 | |||
| 449 | Return Values: |
||
| 450 | BYTE - the current state of the MSDProcessCommand state |
||
| 451 | machine. The valid values are defined in MSD.h under the |
||
| 452 | MSDProcessCommand state machine declaration section |
||
| 453 | |||
| 454 | Remarks: |
||
| 455 | None |
||
| 456 | |||
| 457 | *****************************************************************************/ |
||
| 458 | void MSDProcessCommandMediaPresent(void) |
||
| 459 | { |
||
| 460 | BYTE i; |
||
| 461 | |||
| 462 | switch(MSDCommandState) |
||
| 463 | { |
||
| 464 | case MSD_COMMAND_WAIT: |
||
| 465 | //copy the received command to the command state machine |
||
| 466 | MSDCommandState = gblCBW.CBWCB[0]; |
||
| 467 | break; |
||
| 468 | case MSD_INQUIRY: |
||
| 469 | { |
||
| 470 | //copy the inquiry results from the defined ROM buffer |
||
| 471 | // into the USB buffer so that it can be transmitted |
||
| 472 | memcpypgm2ram( |
||
| 473 | (void *)&msd_buffer[0], |
||
| 474 | (ROM void*)&inq_resp, |
||
| 475 | sizeof(InquiryResponse) |
||
| 476 | ); |
||
| 477 | msd_csw.dCSWDataResidue=sizeof(InquiryResponse); |
||
| 478 | msd_csw.bCSWStatus=0x00; // success |
||
| 479 | MSDCommandState = MSD_COMMAND_RESPONSE; |
||
| 480 | break; |
||
| 481 | } |
||
| 482 | case MSD_READ_CAPACITY: |
||
| 483 | { |
||
| 484 | //If the host asked for the capacity of the device |
||
| 485 | DWORD_VAL sectorSize; |
||
| 486 | DWORD_VAL capacity; |
||
| 487 | |||
| 488 | msd_csw.bCSWStatus=0x00; // success |
||
| 489 | |||
| 490 | //get the information from the physical media |
||
| 491 | capacity.Val = LUNReadCapacity(); |
||
| 492 | sectorSize.Val = LUNReadSectorSize(); |
||
| 493 | |||
| 494 | //copy the data to the buffer |
||
| 495 | msd_buffer[0]=capacity.v[3]; |
||
| 496 | msd_buffer[1]=capacity.v[2]; |
||
| 497 | msd_buffer[2]=capacity.v[1]; |
||
| 498 | msd_buffer[3]=capacity.v[0]; |
||
| 499 | |||
| 500 | msd_buffer[4]=sectorSize.v[3]; |
||
| 501 | msd_buffer[5]=sectorSize.v[2]; |
||
| 502 | msd_buffer[6]=sectorSize.v[1]; |
||
| 503 | msd_buffer[7]=sectorSize.v[0]; |
||
| 504 | |||
| 505 | msd_csw.dCSWDataResidue=0x08; // size of response |
||
| 506 | MSDCommandState = MSD_COMMAND_RESPONSE; |
||
| 507 | break; |
||
| 508 | } |
||
| 509 | case MSD_READ_10: |
||
| 510 | if(MSDReadHandler() == MSD_READ10_WAIT) |
||
| 511 | { |
||
| 512 | MSDCommandState = MSD_COMMAND_WAIT; |
||
| 513 | } |
||
| 514 | break; |
||
| 515 | case MSD_WRITE_10: |
||
| 516 | if(MSDWriteHandler() == MSD_WRITE10_WAIT) |
||
| 517 | { |
||
| 518 | MSDCommandState = MSD_COMMAND_WAIT; |
||
| 519 | } |
||
| 520 | break; |
||
| 521 | case MSD_REQUEST_SENSE: |
||
| 522 | for(i=0;i<sizeof(RequestSenseResponse);i++) |
||
| 523 | { |
||
| 524 | msd_buffer[i]=gblSenseData[LUN_INDEX]._byte[i]; |
||
| 525 | } |
||
| 526 | |||
| 527 | msd_csw.dCSWDataResidue=sizeof(RequestSenseResponse); |
||
| 528 | msd_csw.bCSWStatus=0x0; // success |
||
| 529 | MSDCommandState = MSD_COMMAND_RESPONSE; |
||
| 530 | break; |
||
| 531 | case MSD_MODE_SENSE: |
||
| 532 | msd_buffer[0]=0x02; |
||
| 533 | msd_buffer[1]=0x00; |
||
| 534 | msd_buffer[2]=0x00; |
||
| 535 | msd_buffer[3]=0x00; |
||
| 536 | |||
| 537 | msd_csw.bCSWStatus=0x0; |
||
| 538 | msd_csw.dCSWDataResidue=0x04; |
||
| 539 | MSDCommandState = MSD_COMMAND_RESPONSE; |
||
| 540 | break; |
||
| 541 | case MSD_PREVENT_ALLOW_MEDIUM_REMOVAL: |
||
| 542 | if(LUNMediaDetect()) |
||
| 543 | { |
||
| 544 | msd_csw.bCSWStatus=0x00; |
||
| 545 | msd_csw.dCSWDataResidue=0x00; |
||
| 546 | } |
||
| 547 | else |
||
| 548 | { |
||
| 549 | gblSenseData[LUN_INDEX].SenseKey=S_NOT_READY; |
||
| 550 | gblSenseData[LUN_INDEX].ASC=ASC_MEDIUM_NOT_PRESENT; |
||
| 551 | gblSenseData[LUN_INDEX].ASCQ=ASCQ_MEDIUM_NOT_PRESENT; |
||
| 552 | msd_csw.bCSWStatus=0x01; |
||
| 553 | } |
||
| 554 | MSDCommandState = MSD_COMMAND_WAIT; |
||
| 555 | break; |
||
| 556 | case MSD_TEST_UNIT_READY: |
||
| 557 | if((gblSenseData[LUN_INDEX].SenseKey==S_UNIT_ATTENTION) && (msd_csw.bCSWStatus==1)) |
||
| 558 | { |
||
| 559 | MSDCommandState = MSD_COMMAND_WAIT; |
||
| 560 | } |
||
| 561 | else |
||
| 562 | { |
||
| 563 | ResetSenseData(); |
||
| 564 | msd_csw.dCSWDataResidue=0x00; |
||
| 565 | MSDCommandState = MSD_COMMAND_WAIT; |
||
| 566 | } |
||
| 567 | break; |
||
| 568 | case MSD_VERIFY: |
||
| 569 | //Fall through to STOP_START |
||
| 570 | case MSD_STOP_START: |
||
| 571 | msd_csw.bCSWStatus=0x0; |
||
| 572 | msd_csw.dCSWDataResidue=0x00; |
||
| 573 | MSDCommandState = MSD_COMMAND_WAIT; |
||
| 574 | break; |
||
| 575 | case MSD_COMMAND_RESPONSE: |
||
| 576 | if(USBHandleBusy(USBMSDInHandle) == FALSE) |
||
| 577 | { |
||
| 578 | USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,(BYTE*)&msd_buffer[0],msd_csw.dCSWDataResidue); |
||
| 579 | MSDCommandState = MSD_COMMAND_WAIT; |
||
| 580 | |||
| 581 | msd_csw.dCSWDataResidue=0; |
||
| 582 | } |
||
| 583 | break; |
||
| 584 | case MSD_COMMAND_ERROR: |
||
| 585 | default: |
||
| 586 | ResetSenseData(); |
||
| 587 | gblSenseData[LUN_INDEX].SenseKey=S_ILLEGAL_REQUEST; |
||
| 588 | gblSenseData[LUN_INDEX].ASC=ASC_INVALID_COMMAND_OPCODE; |
||
| 589 | gblSenseData[LUN_INDEX].ASCQ=ASCQ_INVALID_COMMAND_OPCODE; |
||
| 590 | msd_csw.bCSWStatus=0x01; |
||
| 591 | msd_csw.dCSWDataResidue=0x00; |
||
| 592 | MSDCommandState = MSD_COMMAND_RESPONSE; |
||
| 593 | break; |
||
| 594 | } // end switch |
||
| 595 | } |
||
| 596 | |||
| 597 | /****************************************************************************** |
||
| 598 | Function: |
||
| 599 | void MSDProcessCommandMediaAbsent(void) |
||
| 600 | |||
| 601 | Description: |
||
| 602 | This funtion processes a command received through the MSD |
||
| 603 | class driver |
||
| 604 | |||
| 605 | PreCondition: |
||
| 606 | None |
||
| 607 | |||
| 608 | Parameters: |
||
| 609 | None |
||
| 610 | |||
| 611 | Return Values: |
||
| 612 | BYTE - the current state of the MSDProcessCommand state |
||
| 613 | machine. The valid values are defined in MSD.h under the |
||
| 614 | MSDProcessCommand state machine declaration section |
||
| 615 | |||
| 616 | Remarks: |
||
| 617 | None |
||
| 618 | |||
| 619 | *****************************************************************************/ |
||
| 620 | void MSDProcessCommandMediaAbsent(void) |
||
| 621 | { |
||
| 622 | BYTE i; |
||
| 623 | |||
| 624 | switch(MSDCommandState) |
||
| 625 | { |
||
| 626 | case MSD_REQUEST_SENSE: |
||
| 627 | { |
||
| 628 | ResetSenseData(); |
||
| 629 | gblSenseData[LUN_INDEX].SenseKey=S_NOT_READY; |
||
| 630 | gblSenseData[LUN_INDEX].ASC=ASC_MEDIUM_NOT_PRESENT; |
||
| 631 | gblSenseData[LUN_INDEX].ASCQ=ASCQ_MEDIUM_NOT_PRESENT; |
||
| 632 | |||
| 633 | for(i=0;i<sizeof(RequestSenseResponse);i++) |
||
| 634 | { |
||
| 635 | msd_buffer[i]=gblSenseData[LUN_INDEX]._byte[i]; |
||
| 636 | } |
||
| 637 | |||
| 638 | msd_csw.dCSWDataResidue=sizeof(RequestSenseResponse); |
||
| 639 | msd_csw.bCSWStatus=0x0; // success |
||
| 640 | MSDCommandState = MSD_COMMAND_RESPONSE; |
||
| 641 | break; |
||
| 642 | } |
||
| 643 | case MSD_PREVENT_ALLOW_MEDIUM_REMOVAL: |
||
| 644 | case MSD_TEST_UNIT_READY: |
||
| 645 | { |
||
| 646 | msd_csw.bCSWStatus=0x01; |
||
| 647 | MSDCommandState = MSD_COMMAND_WAIT; |
||
| 648 | break; |
||
| 649 | } |
||
| 650 | case MSD_INQUIRY: |
||
| 651 | { |
||
| 652 | memcpypgm2ram( |
||
| 653 | (void *)&msd_buffer[0], |
||
| 654 | (ROM void*)&inq_resp, |
||
| 655 | sizeof(InquiryResponse) |
||
| 656 | ); |
||
| 657 | msd_csw.dCSWDataResidue=sizeof(InquiryResponse); |
||
| 658 | msd_csw.bCSWStatus=0x00; // success |
||
| 659 | MSDCommandState = MSD_COMMAND_RESPONSE; |
||
| 660 | break; |
||
| 661 | } |
||
| 662 | case MSD_COMMAND_WAIT: |
||
| 663 | { |
||
| 664 | MSDCommandState = gblCBW.CBWCB[0]; |
||
| 665 | break; |
||
| 666 | } |
||
| 667 | case MSD_COMMAND_RESPONSE: |
||
| 668 | if(USBHandleBusy(USBMSDInHandle) == FALSE) |
||
| 669 | { |
||
| 670 | USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,(BYTE*)&msd_buffer[0],msd_csw.dCSWDataResidue); |
||
| 671 | MSDCommandState = MSD_COMMAND_WAIT; |
||
| 672 | |||
| 673 | msd_csw.dCSWDataResidue=0; |
||
| 674 | } |
||
| 675 | break; |
||
| 676 | default: |
||
| 677 | { |
||
| 678 | //Stall MSD endpoint IN |
||
| 679 | USBStallEndpoint(MSD_DATA_IN_EP,1); |
||
| 680 | msd_csw.bCSWStatus=0x01; |
||
| 681 | MSDCommandState = MSD_COMMAND_WAIT; |
||
| 682 | break; |
||
| 683 | } |
||
| 684 | } |
||
| 685 | } |
||
| 686 | |||
| 687 | /****************************************************************************** |
||
| 688 | Function: |
||
| 689 | BYTE MSDProcessCommand(void) |
||
| 690 | |||
| 691 | Description: |
||
| 692 | This funtion processes a command received through the MSD |
||
| 693 | class driver |
||
| 694 | |||
| 695 | PreCondition: |
||
| 696 | None |
||
| 697 | |||
| 698 | Paramters: |
||
| 699 | None |
||
| 700 | |||
| 701 | Return Values: |
||
| 702 | BYTE - the current state of the MSDProcessCommand state |
||
| 703 | machine. The valid values are defined in MSD.h under the |
||
| 704 | MSDProcessCommand state machine declaration section |
||
| 705 | |||
| 706 | Remarks: |
||
| 707 | None |
||
| 708 | |||
| 709 | *****************************************************************************/ |
||
| 710 | BYTE MSDProcessCommand(void) |
||
| 711 | { |
||
| 712 | if(LUNMediaDetect() == FALSE || SoftDetach[gblCBW.bCBWLUN] == TRUE) |
||
| 713 | { |
||
| 714 | gblMediaPresent &= ~(1<<gblCBW.bCBWLUN); |
||
| 715 | |||
| 716 | MSDProcessCommandMediaAbsent(); |
||
| 717 | } |
||
| 718 | else |
||
| 719 | { |
||
| 720 | if((gblMediaPresent & (1<<gblCBW.bCBWLUN)) == 0) |
||
| 721 | { |
||
| 722 | if(LUNMediaInitialize()) |
||
| 723 | { |
||
| 724 | gblMediaPresent |= (1<<gblCBW.bCBWLUN); |
||
| 725 | |||
| 726 | gblSenseData[LUN_INDEX].SenseKey=S_UNIT_ATTENTION; |
||
| 727 | gblSenseData[LUN_INDEX].ASC=0x28; |
||
| 728 | gblSenseData[LUN_INDEX].ASCQ=0x00; |
||
| 729 | msd_csw.bCSWStatus=0x01; |
||
| 730 | |||
| 731 | MSDProcessCommandMediaPresent(); |
||
| 732 | } |
||
| 733 | else |
||
| 734 | { |
||
| 735 | MSDProcessCommandMediaAbsent(); |
||
| 736 | } |
||
| 737 | } |
||
| 738 | else |
||
| 739 | { |
||
| 740 | MSDProcessCommandMediaPresent(); |
||
| 741 | } |
||
| 742 | } |
||
| 743 | |||
| 744 | return MSDCommandState; |
||
| 745 | } |
||
| 746 | |||
| 747 | /****************************************************************************** |
||
| 748 | Function: |
||
| 749 | BYTE MSDReadHandler(void) |
||
| 750 | |||
| 751 | Description: |
||
| 752 | This funtion processes a read command received through |
||
| 753 | the MSD class driver |
||
| 754 | |||
| 755 | PreCondition: |
||
| 756 | None |
||
| 757 | |||
| 758 | Parameters: |
||
| 759 | None |
||
| 760 | |||
| 761 | Return Values: |
||
| 762 | BYTE - the current state of the MSDReadHandler state |
||
| 763 | machine. The valid values are defined in MSD.h under the |
||
| 764 | MSDReadHandler state machine declaration section |
||
| 765 | |||
| 766 | Remarks: |
||
| 767 | None |
||
| 768 | |||
| 769 | *****************************************************************************/ |
||
| 770 | |||
| 771 | BYTE MSDReadHandler(void) |
||
| 772 | { |
||
| 773 | static BYTE MSDReadState = MSD_READ10_WAIT; |
||
| 774 | |||
| 775 | switch(MSDReadState) |
||
| 776 | { |
||
| 777 | case MSD_READ10_WAIT: |
||
| 778 | LBA.v[3]=gblCBW.CBWCB[2]; |
||
| 779 | LBA.v[2]=gblCBW.CBWCB[3]; |
||
| 780 | LBA.v[1]=gblCBW.CBWCB[4]; |
||
| 781 | LBA.v[0]=gblCBW.CBWCB[5]; |
||
| 782 | |||
| 783 | TransferLength.v[1]=gblCBW.CBWCB[7]; |
||
| 784 | TransferLength.v[0]=gblCBW.CBWCB[8]; |
||
| 785 | |||
| 786 | msd_csw.bCSWStatus=0x0; |
||
| 787 | msd_csw.dCSWDataResidue=0x0; |
||
| 788 | |||
| 789 | MSDReadState = MSD_READ10_BLOCK; |
||
| 790 | //Fall through to MSD_READ_BLOCK |
||
| 791 | case MSD_READ10_BLOCK: |
||
| 792 | if(TransferLength.Val == 0) |
||
| 793 | { |
||
| 794 | MSDReadState = MSD_READ10_WAIT; |
||
| 795 | break; |
||
| 796 | } |
||
| 797 | |||
| 798 | TransferLength.Val--; // we have read 1 LBA |
||
| 799 | MSDReadState = MSD_READ10_SECTOR; |
||
| 800 | //Fall through to MSD_READ10_SECTOR |
||
| 801 | case MSD_READ10_SECTOR: |
||
| 802 | //if the old data isn't completely sent yet |
||
| 803 | if(USBHandleBusy(USBMSDInHandle) != 0) |
||
| 804 | { |
||
| 805 | break; |
||
| 806 | } |
||
| 807 | |||
| 808 | if(LUNSectorRead(LBA.Val, (BYTE*)&msd_buffer[0]) != TRUE) |
||
| 809 | { |
||
| 810 | msd_csw.bCSWStatus=0x01; // Error 0x01 Refer page#18 |
||
| 811 | // of BOT specifications |
||
| 812 | /* Don't read any more data*/ |
||
| 813 | msd_csw.dCSWDataResidue=0x0; |
||
| 814 | |||
| 815 | MSD_State = MSD_DATA_IN; |
||
| 816 | break; |
||
| 817 | } |
||
| 818 | |||
| 819 | LBA.Val++; |
||
| 820 | |||
| 821 | msd_csw.bCSWStatus=0x00; // success |
||
| 822 | msd_csw.dCSWDataResidue=BLOCKLEN_512;//in order to send the |
||
| 823 | //512 bytes of data read |
||
| 824 | |||
| 825 | ptrNextData=(BYTE *)&msd_buffer[0]; |
||
| 826 | |||
| 827 | MSDReadState = MSD_READ10_TX_SECTOR; |
||
| 828 | |||
| 829 | //Fall through to MSD_READ10_TX_SECTOR |
||
| 830 | case MSD_READ10_TX_SECTOR: |
||
| 831 | if(msd_csw.dCSWDataResidue == 0) |
||
| 832 | { |
||
| 833 | MSDReadState = MSD_READ10_BLOCK; |
||
| 834 | break; |
||
| 835 | } |
||
| 836 | |||
| 837 | MSDReadState = MSD_READ10_TX_PACKET; |
||
| 838 | //Fall through to MSD_READ10_TX_PACKET |
||
| 839 | |||
| 840 | case MSD_READ10_TX_PACKET: |
||
| 841 | if ((msd_csw.bCSWStatus==0x00)&&(msd_csw.dCSWDataResidue>=MSD_IN_EP_SIZE)) |
||
| 842 | { |
||
| 843 | /* Write next chunk of data to EP Buffer and send */ |
||
| 844 | if(USBHandleBusy(USBMSDInHandle)) |
||
| 845 | { |
||
| 846 | break; |
||
| 847 | } |
||
| 848 | |||
| 849 | USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,ptrNextData,MSD_IN_EP_SIZE); |
||
| 850 | |||
| 851 | MSDReadState = MSD_READ10_TX_SECTOR; |
||
| 852 | |||
| 853 | gblCBW.dCBWDataTransferLength-= MSD_IN_EP_SIZE; |
||
| 854 | msd_csw.dCSWDataResidue-=MSD_IN_EP_SIZE; |
||
| 855 | ptrNextData+=MSD_IN_EP_SIZE; |
||
| 856 | } |
||
| 857 | break; |
||
| 858 | } |
||
| 859 | |||
| 860 | return MSDReadState; |
||
| 861 | } |
||
| 862 | |||
| 863 | |||
| 864 | /****************************************************************************** |
||
| 865 | Function: |
||
| 866 | BYTE MSDWriteHandler(void) |
||
| 867 | |||
| 868 | Description: |
||
| 869 | This funtion processes a write command received through |
||
| 870 | the MSD class driver |
||
| 871 | |||
| 872 | PreCondition: |
||
| 873 | None |
||
| 874 | |||
| 875 | Parameters: |
||
| 876 | None |
||
| 877 | |||
| 878 | Return Values: |
||
| 879 | BYTE - the current state of the MSDWriteHandler state |
||
| 880 | machine. The valid values are defined in MSD.h under the |
||
| 881 | MSDWriteHandler state machine declaration section |
||
| 882 | |||
| 883 | Remarks: |
||
| 884 | None |
||
| 885 | |||
| 886 | *****************************************************************************/ |
||
| 887 | BYTE MSDWriteHandler(void) |
||
| 888 | { |
||
| 889 | static BYTE MSDWriteState = MSD_WRITE10_WAIT; |
||
| 890 | |||
| 891 | switch(MSDWriteState) |
||
| 892 | { |
||
| 893 | case MSD_WRITE10_WAIT: |
||
| 894 | /* Read the LBA, TransferLength fields from Command Block |
||
| 895 | NOTE: CB is Big-Endian */ |
||
| 896 | |||
| 897 | LBA.v[3]=gblCBW.CBWCB[2]; |
||
| 898 | LBA.v[2]=gblCBW.CBWCB[3]; |
||
| 899 | LBA.v[1]=gblCBW.CBWCB[4]; |
||
| 900 | LBA.v[0]=gblCBW.CBWCB[5]; |
||
| 901 | TransferLength.v[1]=gblCBW.CBWCB[7]; |
||
| 902 | TransferLength.v[0]=gblCBW.CBWCB[8]; |
||
| 903 | |||
| 904 | msd_csw.bCSWStatus=0x0; |
||
| 905 | |||
| 906 | MSD_State = MSD_WRITE10_BLOCK; |
||
| 907 | //Fall through to MSD_WRITE10_BLOCK |
||
| 908 | case MSD_WRITE10_BLOCK: |
||
| 909 | if(TransferLength.Val == 0) |
||
| 910 | { |
||
| 911 | MSDWriteState = MSD_WRITE10_WAIT; |
||
| 912 | break; |
||
| 913 | } |
||
| 914 | |||
| 915 | MSDWriteState = MSD_WRITE10_RX_SECTOR; |
||
| 916 | ptrNextData=(BYTE *)&msd_buffer[0]; |
||
| 917 | |||
| 918 | msd_csw.dCSWDataResidue=BLOCKLEN_512; |
||
| 919 | |||
| 920 | //Fall through to MSD_WRITE10_RX_SECTOR |
||
| 921 | case MSD_WRITE10_RX_SECTOR: |
||
| 922 | { |
||
| 923 | /* Read 512B into msd_buffer*/ |
||
| 924 | if(msd_csw.dCSWDataResidue>0) |
||
| 925 | { |
||
| 926 | if(USBHandleBusy(USBMSDOutHandle) == TRUE) |
||
| 927 | { |
||
| 928 | break; |
||
| 929 | } |
||
| 930 | |||
| 931 | USBMSDOutHandle = USBRxOnePacket(MSD_DATA_OUT_EP,ptrNextData,MSD_OUT_EP_SIZE); |
||
| 932 | MSDWriteState = MSD_WRITE10_RX_PACKET; |
||
| 933 | //Fall through to MSD_WRITE10_RX_PACKET |
||
| 934 | } |
||
| 935 | else |
||
| 936 | { |
||
| 937 | if(LUNWriteProtectState()) |
||
| 938 | { |
||
| 939 | gblSenseData[LUN_INDEX].SenseKey=S_NOT_READY; |
||
| 940 | gblSenseData[LUN_INDEX].ASC=ASC_WRITE_PROTECTED; |
||
| 941 | gblSenseData[LUN_INDEX].ASCQ=ASCQ_WRITE_PROTECTED; |
||
| 942 | msd_csw.bCSWStatus=0x01; |
||
| 943 | //TODO: (DF) - what state should I return to? |
||
| 944 | } |
||
| 945 | else |
||
| 946 | { |
||
| 947 | MSDWriteState = MSD_WRITE10_SECTOR; |
||
| 948 | } |
||
| 949 | break; |
||
| 950 | } |
||
| 951 | } |
||
| 952 | //Fall through to MSD_WRITE10_RX_PACKET |
||
| 953 | case MSD_WRITE10_RX_PACKET: |
||
| 954 | if(USBHandleBusy(USBMSDOutHandle) == TRUE) |
||
| 955 | { |
||
| 956 | break; |
||
| 957 | } |
||
| 958 | |||
| 959 | gblCBW.dCBWDataTransferLength-=USBHandleGetLength(USBMSDOutHandle); // 64B read |
||
| 960 | msd_csw.dCSWDataResidue-=USBHandleGetLength(USBMSDOutHandle); |
||
| 961 | ptrNextData += MSD_OUT_EP_SIZE; |
||
| 962 | |||
| 963 | MSDWriteState = MSD_WRITE10_RX_SECTOR; |
||
| 964 | break; |
||
| 965 | case MSD_WRITE10_SECTOR: |
||
| 966 | { |
||
| 967 | if(LUNSectorWrite(LBA.Val, (BYTE*)&msd_buffer[0], (LBA.Val==0)?TRUE:FALSE) != TRUE) |
||
| 968 | { |
||
| 969 | break; |
||
| 970 | } |
||
| 971 | |||
| 972 | // if (status) { |
||
| 973 | // msd_csw.bCSWStatus=0x01; |
||
| 974 | // /* add some sense keys here*/ |
||
| 975 | // } |
||
| 976 | |||
| 977 | LBA.Val++; // One LBA is written. Write the next LBA |
||
| 978 | TransferLength.Val--; |
||
| 979 | |||
| 980 | MSDWriteState = MSD_WRITE10_BLOCK; |
||
| 981 | break; |
||
| 982 | } |
||
| 983 | } |
||
| 984 | |||
| 985 | return MSDWriteState; |
||
| 986 | } |
||
| 987 | |||
| 988 | /****************************************************************************** |
||
| 989 | Function: |
||
| 990 | void ResetSenseData(void) |
||
| 991 | |||
| 992 | Description: |
||
| 993 | This routine resets the Sense Data, initializing the |
||
| 994 | structure RequestSenseResponse gblSenseData. |
||
| 995 | |||
| 996 | PreCondition: |
||
| 997 | None |
||
| 998 | |||
| 999 | Parameters: |
||
| 1000 | None |
||
| 1001 | |||
| 1002 | Return Values: |
||
| 1003 | None |
||
| 1004 | |||
| 1005 | Remarks: |
||
| 1006 | None |
||
| 1007 | |||
| 1008 | *****************************************************************************/ |
||
| 1009 | void ResetSenseData(void) |
||
| 1010 | { |
||
| 1011 | gblSenseData[LUN_INDEX].ResponseCode=S_CURRENT; |
||
| 1012 | gblSenseData[LUN_INDEX].VALID=0; // no data in the information field |
||
| 1013 | gblSenseData[LUN_INDEX].Obsolete=0x0; |
||
| 1014 | gblSenseData[LUN_INDEX].SenseKey=S_NO_SENSE; |
||
| 1015 | //gblSenseData.Resv; |
||
| 1016 | gblSenseData[LUN_INDEX].ILI=0; |
||
| 1017 | gblSenseData[LUN_INDEX].EOM=0; |
||
| 1018 | gblSenseData[LUN_INDEX].FILEMARK=0; |
||
| 1019 | gblSenseData[LUN_INDEX].InformationB0=0x00; |
||
| 1020 | gblSenseData[LUN_INDEX].InformationB1=0x00; |
||
| 1021 | gblSenseData[LUN_INDEX].InformationB2=0x00; |
||
| 1022 | gblSenseData[LUN_INDEX].InformationB3=0x00; |
||
| 1023 | gblSenseData[LUN_INDEX].AddSenseLen=0x0a; // n-7 (n=17 (0..17)) |
||
| 1024 | gblSenseData[LUN_INDEX].CmdSpecificInfo.Val=0x0; |
||
| 1025 | gblSenseData[LUN_INDEX].ASC=0x0; |
||
| 1026 | gblSenseData[LUN_INDEX].ASCQ=0x0; |
||
| 1027 | gblSenseData[LUN_INDEX].FRUC=0x0; |
||
| 1028 | gblSenseData[LUN_INDEX].SenseKeySpecific[0]=0x0; |
||
| 1029 | gblSenseData[LUN_INDEX].SenseKeySpecific[1]=0x0; |
||
| 1030 | gblSenseData[LUN_INDEX].SenseKeySpecific[2]=0x0; |
||
| 1031 | } |
||
| 1032 | |||
| 1033 | #endif |
Powered by WebSVN v2.8.3