SAMV71 Xplained Ultra Software Package 1.5

MSDDStateMachine.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
00028 /* ---------------------------------------------------------------------------- */
00029 
00030 /** \file
00031  * \addtogroup usbd_msd
00032  *@{
00033  */
00034 
00035 /*-----------------------------------------------------------------------------
00036  *      Includes
00037  *-----------------------------------------------------------------------------*/
00038 
00039 #include "SBCMethods.h"
00040 #include "MSDDStateMachine.h"
00041 #include "USBD_HAL.h"
00042 #include "chip.h"
00043 
00044 /*-----------------------------------------------------------------------------
00045  *      Internal functions
00046  *-----------------------------------------------------------------------------*/
00047 
00048 /**
00049  * This function is to be used as a callback for USB or LUN transfers.
00050  * \param  transfer    Pointer to the transfer structure to update
00051  * \param  status      Operation result code
00052  * \param  transferred Number of bytes transferred by the command
00053  * \param  remaining   Number of bytes not transferred
00054  */
00055 static void MSDDriver_Callback(MSDTransfer *transfer,
00056                                uint8_t status,
00057                                uint32_t transferred,
00058                                uint32_t remaining)
00059 {
00060     if (transfer->semaphore == 0) {
00061         transfer->semaphore++;
00062         transfer->status = status;
00063         transfer->transferred = transferred;
00064         transfer->remaining = remaining;
00065     }
00066 }
00067 
00068 /**
00069  * Returns the expected transfer length and direction (IN, OUT or don't care)
00070  * from the host point-of-view.
00071  * \param  cbw     Pointer to the CBW to examinate
00072  * \param  pLength Expected length of command
00073  * \param  pType   Expected direction of command
00074  */
00075 static void MSDD_GetCommandInformation(MSCbw *cbw,
00076                                        unsigned int  *length,
00077                                        unsigned char *type)
00078 {
00079     /* Expected host transfer direction and length */
00080     (*length) = cbw->dCBWDataTransferLength;
00081 
00082     if (*length == 0)
00083 
00084         (*type) = MSDD_NO_TRANSFER;
00085     else if ((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) != 0)
00086 
00087         (*type) = MSDD_DEVICE_TO_HOST;
00088     else
00089 
00090         (*type) = MSDD_HOST_TO_DEVICE;
00091 }
00092 
00093 /**
00094  * Pre-processes a command by checking the differences between the host and
00095  * device expectations in term of transfer type and length.
00096  * Once one of the thirteen cases is identified, the actions to do during the
00097  * post-processing phase are stored in the dCase variable of the command
00098  * state.
00099  * \param  pMsdDriver Pointer to a MSDDriver instance
00100  * \return 1 if the command is supported, false otherwise
00101  */
00102 static unsigned char MSDD_PreProcessCommand(MSDDriver *pMsdDriver)
00103 {
00104     unsigned int        hostLength = 0;
00105     unsigned int        deviceLength = 0;
00106     unsigned char       hostType;
00107     unsigned char       deviceType;
00108     unsigned char       isCommandSupported;
00109     MSDCommandState *commandState = &(pMsdDriver->commandState);
00110     MSCsw           *csw = &(commandState->csw);
00111     MSCbw           *cbw = &(commandState->cbw);
00112     MSDLun          *lun = &(pMsdDriver->luns[(unsigned char) cbw->bCBWLUN]);
00113 
00114     /* Get information about the command */
00115     /* Host-side */
00116     MSDD_GetCommandInformation(cbw, &hostLength, &hostType);
00117 
00118     /* Device-side */
00119     isCommandSupported = SBC_GetCommandInformation(cbw->pCommand,
00120                          &deviceLength,
00121                          &deviceType,
00122                          lun);
00123 
00124     /* Initialize data residue and result status */
00125     csw->dCSWDataResidue = 0;
00126     csw->bCSWStatus = MSD_CSW_COMMAND_PASSED;
00127 
00128     /* Check if the command is supported */
00129     if (isCommandSupported) {
00130 
00131         /* Identify the command case */
00132         if (hostType == MSDD_NO_TRANSFER) {
00133 
00134             /* Case 1  (Hn = Dn) */
00135             if (deviceType == MSDD_NO_TRANSFER) {
00136 
00137                 /*TRACE_WARNING("Case 1\n\r"); */
00138                 commandState->postprocess = 0;
00139                 commandState->length = 0;
00140                 csw->bCSWStatus = MSD_CSW_COMMAND_PASSED;
00141             } else if (deviceType == MSDD_DEVICE_TO_HOST) {
00142 
00143                 /* Case 2  (Hn < Di) */
00144                 TRACE_WARNING(
00145                     "MSDD_PreProcessCommand: Case 2\n\r");
00146                 commandState->postprocess = MSDD_CASE_STALL_IN;
00147                 commandState->length = 0;
00148                 csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00149             } else { /*if (deviceType == MSDD_HOST_TO_DEVICE) { */
00150 
00151                 /* Case 3  (Hn < Do) */
00152                 TRACE_WARNING(
00153                     "MSDD_PreProcessCommand: Case 3\n\r");
00154                 commandState->postprocess = MSDD_CASE_STALL_IN;
00155                 commandState->length = 0;
00156                 csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00157             }
00158         }
00159 
00160         /* Case 4  (Hi > Dn) */
00161         else if (hostType == MSDD_DEVICE_TO_HOST) {
00162 
00163             if (deviceType == MSDD_NO_TRANSFER) {
00164 
00165                 TRACE_WARNING(
00166                     "MSDD_PreProcessCommand: Case 4\n\r");
00167                 commandState->postprocess = MSDD_CASE_STALL_IN;
00168                 commandState->length = 0;
00169                 csw->dCSWDataResidue = hostLength;
00170             } else if (deviceType == MSDD_DEVICE_TO_HOST) {
00171 
00172                 if (hostLength > deviceLength) {
00173 
00174                     /* Case 5  (Hi > Di) */
00175                     TRACE_WARNING(
00176                         "MSDD_PreProcessCommand: Case 5\n\r");
00177                     commandState->postprocess = MSDD_CASE_STALL_IN;
00178                     commandState->length = deviceLength;
00179                     csw->dCSWDataResidue = hostLength - deviceLength;
00180                 } else if (hostLength == deviceLength) {
00181 
00182                     /* Case 6  (Hi = Di) */
00183                     commandState->postprocess = 0;
00184                     commandState->length = deviceLength;
00185                 } else { /*if (hostLength < deviceLength) { */
00186 
00187                     /* Case 7  (Hi < Di) */
00188                     TRACE_WARNING(
00189                         "MSDD_PreProcessCommand: Case 7\n\r");
00190                     commandState->postprocess = MSDD_CASE_STALL_IN;
00191                     commandState->length = hostLength;
00192                     csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00193                 }
00194             } else { /*if (deviceType == MSDD_HOST_TO_DEVICE) { */
00195 
00196                 /* Case 8  (Hi <> Do) */
00197                 TRACE_WARNING(
00198                     "MSDD_PreProcessCommand: Case 8\n\r");
00199                 commandState->postprocess = MSDD_CASE_STALL_IN;
00200                 commandState->length = 0;
00201                 csw->dCSWDataResidue = hostLength;
00202                 csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00203             }
00204         } else if (hostType == MSDD_HOST_TO_DEVICE) {
00205 
00206             if (deviceType == MSDD_NO_TRANSFER) {
00207 
00208                 /* Case 9  (Ho > Dn) */
00209                 TRACE_WARNING(
00210                     "MSDD_PreProcessCommand: Case 9\n\r");
00211                 commandState->postprocess = MSDD_CASE_STALL_OUT;
00212                 commandState->length = 0;
00213                 csw->dCSWDataResidue = hostLength;
00214                 csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00215             } else if (deviceType == MSDD_DEVICE_TO_HOST) {
00216 
00217                 /* Case 10 (Ho <> Di) */
00218                 TRACE_WARNING(
00219                     "MSDD_PreProcessCommand: Case 10\n\r");
00220                 commandState->postprocess =
00221                     MSDD_CASE_STALL_OUT;
00222                 commandState->length = 0;
00223                 csw->dCSWDataResidue = hostLength;
00224                 csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00225             } else { /*if (deviceType == MSDD_HOST_TO_DEVICE) { */
00226 
00227                 if (hostLength > deviceLength) {
00228 
00229                     /* Case 11 (Ho > Do) */
00230                     TRACE_WARNING(
00231                         "MSDD_PreProcessCommand: Case 11\n\r");
00232                     commandState->postprocess = MSDD_CASE_STALL_OUT;
00233                     /*                    commandState->length = deviceLength; */
00234                     /*                    csw->dCSWDataResidue = hostLength - deviceLength; */
00235                     commandState->length = 0;
00236                     csw->dCSWDataResidue = deviceLength;
00237                 } else if (hostLength == deviceLength) {
00238 
00239                     /* Case 12 (Ho = Do) */
00240                     /*TRACE_WARNING(*/
00241                     /*    "MSDD_PreProcessCommand: Case 12\n\r"); */
00242                     commandState->postprocess = 0;
00243                     commandState->length = deviceLength;
00244                 } else { /*if (hostLength < deviceLength) { */
00245 
00246                     /* Case 13 (Ho < Do) */
00247                     TRACE_WARNING(
00248                         "MSDD_PreProcessCommand: Case 13\n\r");
00249                     commandState->postprocess = MSDD_CASE_STALL_OUT;
00250                     commandState->length = hostLength;
00251                     csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00252                 }
00253             }
00254         }
00255     }
00256 
00257     return isCommandSupported;
00258 }
00259 
00260 /**
00261  * Post-processes a command given the case identified during the
00262  * pre-processing step.
00263  * Depending on the case, one of the following actions can be done:
00264  *           - Bulk IN endpoint is stalled
00265  *           - Bulk OUT endpoint is stalled
00266  *           - CSW status set to phase error
00267  * \param  pMsdDriver Pointer to a MSDDriver instance
00268  * \return If the device is halted
00269  */
00270 static unsigned char MSDD_PostProcessCommand(MSDDriver *pMsdDriver)
00271 {
00272     MSDCommandState *commandState = &(pMsdDriver->commandState);
00273     MSCsw           *csw = &(commandState->csw);
00274     unsigned char haltStatus = 0;
00275 
00276     /* Set CSW status code to phase error ? */
00277     if ((commandState->postprocess & MSDD_CASE_PHASE_ERROR) != 0) {
00278 
00279         TRACE_INFO_WP("PhaseErr ");
00280         csw->bCSWStatus = MSD_CSW_PHASE_ERROR;
00281     }
00282 
00283     /* STALL Bulk IN endpoint ? */
00284     if (((commandState->postprocess & MSDD_CASE_STALL_IN) != 0)) {
00285 
00286         TRACE_INFO_WP("StallIn ");
00287         //MSDD_Halt(MSDD_CASE_STALL_IN);
00288         USBD_Halt(commandState->pipeIN);
00289         haltStatus = 1;
00290     }
00291 
00292     /* STALL Bulk OUT endpoint ? */
00293     if ((commandState->postprocess & MSDD_CASE_STALL_OUT) != 0) {
00294 
00295         TRACE_INFO_WP("StallOut ");
00296         //MSDD_Halt(MSDD_CASE_STALL_OUT);
00297         USBD_Halt(commandState->pipeOUT);
00298         haltStatus = 1;
00299     }
00300 
00301     return haltStatus;
00302 }
00303 
00304 /**
00305  * Processes the latest command received by the %device.
00306  * \param  pMsdDriver Pointer to a MSDDriver instance
00307  * \return 1 if the command has been completed, false otherwise.
00308  */
00309 static unsigned char MSDD_ProcessCommand(MSDDriver *pMsdDriver)
00310 {
00311     unsigned char   status;
00312     MSDCommandState *commandState = &(pMsdDriver->commandState);
00313     MSCbw           *cbw = &(commandState->cbw);
00314     MSCsw           *csw = &(commandState->csw);
00315     MSDLun          *lun = &(pMsdDriver->luns[(unsigned char) cbw->bCBWLUN]);
00316     unsigned char   isCommandComplete = 1;
00317 
00318     /* Check if LUN is valid */
00319     if (cbw->bCBWLUN > pMsdDriver->maxLun) {
00320 
00321         TRACE_WARNING(
00322             "MSDD_ProcessCommand: LUN %d not exist\n\r", cbw->bCBWLUN);
00323         status = MSDD_STATUS_ERROR;
00324     } else {
00325 
00326         /* Process command */
00327         if (pMsdDriver->maxLun > 0) {
00328             TRACE_INFO_WP("LUN%d ", cbw->bCBWLUN);
00329         }
00330 
00331         status = SBC_ProcessCommand(lun, commandState);
00332     }
00333 
00334     /* Check command result code */
00335     switch (status) {
00336     case MSDD_STATUS_PARAMETER:
00337         TRACE_WARNING(
00338             "MSDD_ProcessCommand: Unknown cmd 0x%02X\n\r",
00339             cbw->pCommand[0]);
00340 
00341         /* Update sense data */
00342         SBC_UpdateSenseData(&(lun->requestSenseData),
00343                             SBC_SENSE_KEY_ILLEGAL_REQUEST,
00344                             SBC_ASC_INVALID_FIELD_IN_CDB,
00345                             0);
00346 
00347         /* Result codes */
00348         csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00349 
00350         /* stall the request, IN or OUT */
00351         if (((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) == 0)
00352             && (cbw->dCBWDataTransferLength > 0)) {
00353 
00354             /* Stall the OUT endpoint : host to device */
00355             /* MSDD_Halt(MSDD_CASE_STALL_OUT); */
00356             commandState->postprocess = MSDD_CASE_STALL_OUT;
00357             TRACE_INFO_WP("StaOUT ");
00358         } else {
00359 
00360             /* Stall the IN endpoint : device to host */
00361             /* MSDD_Halt(MSDD_CASE_STALL_IN); */
00362             commandState->postprocess = MSDD_CASE_STALL_IN;
00363             TRACE_INFO_WP("StaIN ");
00364         }
00365 
00366         break;
00367 
00368     case MSDD_STATUS_ERROR:
00369         TRACE_WARNING("MSD_ProcessCommand: Cmd %x fail\n\r",
00370                       ((SBCCommand *)commandState->cbw.pCommand)->bOperationCode);
00371 
00372         /* Update sense data */
00373         SBC_UpdateSenseData(&(lun->requestSenseData),
00374                             SBC_SENSE_KEY_MEDIUM_ERROR,
00375                             SBC_ASC_INVALID_FIELD_IN_CDB,
00376                             0);
00377 
00378         /* Result codes */
00379         csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00380         break;
00381 
00382     case MSDD_STATUS_RW:
00383         csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00384         break;
00385 
00386     case MSDD_STATUS_INCOMPLETE:
00387         isCommandComplete = 0;
00388         /* Update sense data */
00389         SBC_UpdateSenseData(&(lun->requestSenseData),
00390                             SBC_SENSE_KEY_NO_SENSE,
00391                             0,
00392                             0);
00393         break;
00394 
00395     case MSDD_STATUS_SUCCESS:
00396         /* Update sense data */
00397         SBC_UpdateSenseData(&(lun->requestSenseData),
00398                             SBC_SENSE_KEY_NO_SENSE,
00399                             0,
00400                             0);
00401         break;
00402     }
00403 
00404     /* Check if command has been completed */
00405     if (isCommandComplete) {
00406 
00407         TRACE_INFO_WP("Cplt ");
00408 
00409         /* Adjust data residue */
00410         if (commandState->length != 0) {
00411 
00412             csw->dCSWDataResidue += commandState->length;
00413 
00414             /* STALL the endpoint waiting for data */
00415             if ((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) == 0) {
00416 
00417                 /* Stall the OUT endpoint : host to device */
00418                 /* MSDD_Halt(MSDD_CASE_STALL_OUT); */
00419                 commandState->postprocess = MSDD_CASE_STALL_OUT;
00420                 TRACE_INFO_WP("StaOUT ");
00421             } else {
00422 
00423                 /* Stall the IN endpoint : device to host */
00424                 /* MSDD_Halt(MSDD_CASE_STALL_IN); */
00425                 commandState->postprocess = MSDD_CASE_STALL_IN;
00426                 TRACE_INFO_WP("StaIN ");
00427             }
00428         }
00429 
00430         /* Reset command state */
00431         commandState->state = 0;
00432     }
00433 
00434     return isCommandComplete;
00435 }
00436 
00437 /**
00438  * State machine for the MSD %device driver
00439  * \param  pMsdDriver Pointer to a MSDDriver instance
00440  */
00441 void MSDD_StateMachine(MSDDriver *pMsdDriver)
00442 {
00443     MSDCommandState *commandState = &(pMsdDriver->commandState);
00444     MSCbw           *cbw = &(commandState->cbw);
00445     MSCsw           *csw = &(commandState->csw);
00446     MSDTransfer     *transfer = &(commandState->transfer);
00447     unsigned char   status;
00448 
00449     /* Identify current driver state */
00450     switch (pMsdDriver->state) {
00451     /*---------------------- */
00452     case MSDD_STATE_READ_CBW:
00453         /*---------------------- */
00454         /* Start the CBW read operation */
00455         transfer->semaphore = 0;
00456 
00457         USBD_HAL_WaitReadData(commandState->pipeOUT);
00458         status = USBD_Read(commandState->pipeOUT,
00459                            cbw,
00460                            MSD_CBW_SIZE,
00461                            (TransferCallback) MSDDriver_Callback,
00462                            (void *) transfer);
00463 
00464         /* Check operation result code */
00465         if (status == USBD_STATUS_SUCCESS) {
00466 
00467             /* If the command was successful, wait for transfer */
00468             pMsdDriver->state = MSDD_STATE_WAIT_CBW;
00469         }
00470 
00471         break;
00472 
00473     /*---------------------- */
00474     case MSDD_STATE_WAIT_CBW:
00475 
00476         /*---------------------- */
00477         /* Check transfer semaphore */
00478         if (transfer->semaphore > 0) {
00479 
00480             /* Take semaphore and terminate transfer */
00481             transfer->semaphore--;
00482 
00483             /* Check if transfer was successful */
00484             if (transfer->status == USBD_STATUS_SUCCESS) {
00485                 TRACE_INFO_WP("\n\r------------------------------\n\r");
00486 
00487                 /* Process received command */
00488                 pMsdDriver->state = MSDD_STATE_PROCESS_CBW;
00489             } else if (transfer->status == USBD_STATUS_RESET) {
00490 
00491                 TRACE_INFO("MSDD_StateMachine: EP reset\n\r");
00492                 pMsdDriver->state = MSDD_STATE_READ_CBW;
00493             } else {
00494 
00495                 TRACE_WARNING(
00496                     "MSDD_StateMachine: Failed to read CBW\n\r");
00497                 pMsdDriver->state = MSDD_STATE_READ_CBW;
00498             }
00499         }
00500 
00501         break;
00502 
00503     /*------------------------- */
00504     case MSDD_STATE_PROCESS_CBW:
00505 
00506         /*------------------------- */
00507         /* Check if this is a new command */
00508         if (commandState->state == 0) {
00509 
00510             /* Copy the CBW tag */
00511             csw->dCSWTag = cbw->dCBWTag;
00512 
00513             /* Check that the CBW is 31 bytes long */
00514             if ((transfer->transferred != MSD_CBW_SIZE)
00515                 || (cbw->dCBWSignature != MSD_CBW_SIGNATURE)) {
00516                 /* Wait for a reset recovery */
00517                 pMsdDriver->waitResetRecovery = 1;
00518 
00519                 /* Halt the Bulk-IN and Bulk-OUT pipes */
00520                 //USBD_Halt(commandState->pipeIN);
00521                 //USBD_Halt(commandState->pipeOUT);
00522 
00523                 csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
00524                 pMsdDriver->state = MSDD_STATE_SEND_CSW;
00525                 commandState->postprocess = MSDD_CASE_STALL_IN | MSDD_CASE_STALL_OUT;
00526             } else {
00527 
00528                 /* Pre-process command */
00529                 MSDD_PreProcessCommand(pMsdDriver);
00530             }
00531         }
00532 
00533         /* Process command */
00534         if (csw->bCSWStatus == MSD_CSW_COMMAND_PASSED) {
00535 
00536             if (MSDD_ProcessCommand(pMsdDriver)) {
00537 
00538                 /* Post-process command if it is finished */
00539                 if (MSDD_PostProcessCommand(pMsdDriver)) {
00540 
00541                     TRACE_INFO_WP("WaitHALT ");
00542                     pMsdDriver->state = MSDD_STATE_WAIT_HALT;
00543                 } else
00544 
00545                     pMsdDriver->state = MSDD_STATE_SEND_CSW;
00546             }
00547 
00548             TRACE_INFO_WP("\n\r");
00549         } else {
00550             /* Post-process command if it is finished */
00551             if (MSDD_PostProcessCommand(pMsdDriver)) {
00552 
00553                 TRACE_INFO_WP("WaitHALT ");
00554                 pMsdDriver->state = MSDD_STATE_WAIT_HALT;
00555             } else
00556 
00557                 pMsdDriver->state = MSDD_STATE_SEND_CSW;
00558 
00559             TRACE_INFO_WP("\n\r");
00560         }
00561 
00562         break;
00563 
00564     /*---------------------- */
00565     case MSDD_STATE_SEND_CSW:
00566         /*---------------------- */
00567         /* Set signature */
00568         csw->dCSWSignature = MSD_CSW_SIGNATURE;
00569 
00570         /* Start the CSW write operation */
00571         status = USBD_Write(commandState->pipeIN,
00572                             csw,
00573                             MSD_CSW_SIZE,
00574                             (TransferCallback) MSDDriver_Callback,
00575                             (void *) transfer);
00576 
00577         /* Check operation result code */
00578         if (status == USBD_STATUS_SUCCESS) {
00579 
00580             TRACE_INFO_WP("SendCSW ");
00581 
00582             /* Wait for end of transfer */
00583             pMsdDriver->state = MSDD_STATE_WAIT_CSW;
00584         }
00585 
00586         break;
00587 
00588     /*---------------------- */
00589     case MSDD_STATE_WAIT_CSW:
00590 
00591         /*---------------------- */
00592         /* Check transfer semaphore */
00593         if (transfer->semaphore > 0) {
00594 
00595             /* Take semaphore and terminate transfer */
00596             transfer->semaphore--;
00597 
00598 //            /* Check if transfer was successful */
00599 //            if (transfer->status == USBD_STATUS_RESET) {
00600 
00601 //                TRACE_INFO("MSDD_StateMachine: EP resetted\n\r");
00602 //            }
00603 //            else if (transfer->status == USBD_STATUS_ABORTED) {
00604 
00605 //                TRACE_WARNING(
00606 //                    "MSDD_StateMachine: Failed to send CSW\n\r");
00607 //            }
00608 //            else {
00609 
00610 //                TRACE_INFO_WP("ok");
00611 //            }
00612 
00613             /* Read new CBW */
00614             pMsdDriver->state = MSDD_STATE_READ_CBW;
00615         }
00616 
00617         break;
00618 
00619     /*---------------------- */
00620     case MSDD_STATE_WAIT_HALT:
00621 
00622         /*---------------------- */
00623         //if (MSDD_IsHalted() == 0) {
00624         if (!USBD_IsHalted(commandState->pipeIN))
00625 
00626             pMsdDriver->state = MSDD_STATE_SEND_CSW;
00627 
00628         break;
00629     }
00630 }
00631 
00632 /**@}*/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines