Ejemplo n.º 1
0
USB_STATUS usb_class_mass_pass_on_usb
   (
      /* [IN] Interface handle */
      USB_MASS_CLASS_INTF_STRUCT_PTR   intf_ptr
   )
{ /* Body */
   COMMAND_OBJECT_PTR      cmd_ptr = NULL;
   TR_INIT_PARAM_STRUCT    tr_init;
   USB_STATUS              status = USB_OK;
   uint_8                  tmp;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_pass_on_usb");
   #endif
   
   /* Nothing can be done if there is nothing pending */
   usb_class_mass_get_pending_request(intf_ptr, &cmd_ptr);
   if (cmd_ptr == NULL) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_pass_on_usb, no matching request");
      #endif
      return (USB_STATUS)USB_MASS_NO_MATCHING_REQUEST;
   } /* Endif */

   /* Determine the appropriate action based on the phase */
   switch (cmd_ptr->STATUS) {
      case STATUS_QUEUED_IN_DRIVER:
         /* means that CBW needs to be sent.*/
         usb_hostdev_tr_init(&tr_init, usb_class_mass_call_back_cbw,
            (pointer)intf_ptr);
         tr_init.TX_BUFFER = (uchar_ptr)cmd_ptr->CBW_PTR;
         tr_init.TX_LENGTH = sizeof(CBW_STRUCT);

         status = _usb_host_send_data(intf_ptr->G.host_handle,
            intf_ptr->BULK_OUT_PIPE, &tr_init);
         break;

      case STATUS_FINISHED_CBW_ON_USB:
         /* Determine next phase (DATA or STATUS), length and direction */
         if (LONG_LE_TO_HOST(*(uint_32_ptr)cmd_ptr->CBW_PTR->DCBWDATATRANSFERLENGTH) > 0) {

            /* Commen TR setup for IN or OUT direction */
            usb_hostdev_tr_init(&tr_init,usb_class_mass_call_back_dphase,
               (pointer)intf_ptr);

            tmp = (uint_8)((cmd_ptr->CBW_PTR->BMCBWFLAGS) & MASK_NON_DIRECTION_BITS);
            switch(tmp) {
               case DIRECTION_OUT:
                  /* Make a TR with DATA Phase call back.*/
                  tr_init.TX_BUFFER = (uchar_ptr)cmd_ptr->DATA_BUFFER;
                  tr_init.TX_LENGTH = cmd_ptr->BUFFER_LEN;

                  status = _usb_host_send_data(intf_ptr->G.host_handle,
                     intf_ptr->BULK_OUT_PIPE, &tr_init);
                  break;

               case DIRECTION_IN:
                  /* Make a TR with DATA call back.*/
                  tr_init.RX_BUFFER = (uchar_ptr)cmd_ptr->DATA_BUFFER;
                  tr_init.RX_LENGTH = cmd_ptr->BUFFER_LEN;

                  status = _usb_host_recv_data(intf_ptr->G.host_handle,
                     intf_ptr->BULK_IN_PIPE, &tr_init);
                  break;

               default:
                  break;
            } /* Endswitch */
            break;
         } /* Endif */

         /*
         ** else case:
         ** No data transfer is expected of the request. Fall through to
         ** STATUS phase
         */

      case STATUS_FINISHED_DPHASE_ON_USB:
         /* Make a TR and send it with STATUS call back */
         usb_hostdev_tr_init(&tr_init,usb_class_mass_call_back_csw,
            (pointer)intf_ptr);
         tr_init.RX_BUFFER = (uchar_ptr)cmd_ptr->CSW_PTR;
         tr_init.RX_LENGTH = sizeof(CSW_STRUCT);

         status = _usb_host_recv_data(intf_ptr->G.host_handle,
            intf_ptr->BULK_IN_PIPE, &tr_init);
            
         break;

      case STATUS_FINISHED_CSW_ON_USB: /* No action */
      case STATUS_FAILED_IN_CSW:       /* Should never happen */
      default:
         break;
   } /* Endswitch */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_pass_on_usb, SUCCESSFUL");
   #endif
   
   return USB_log_error(__FILE__,__LINE__,status);
} /* Endbody */
Ejemplo n.º 2
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_hub_device_sm
* Returned Value : None
* Comments       :
*     called when a hub changes state; sm = state machine
*END*--------------------------------------------------------------------*/
static void usb_host_hub_device_sm
   (
         /* [IN] structure with USB pipe information on the interface */
         PIPE_STRUCT_PTR   pipe,

         /* [IN] parameters */
         pointer           param,

         /* [IN] buffer of data from IN stage */
         pointer           buffer,

         /* [IN] length of data from IN stage */
         uint_32           len,

         /* [IN] status of transaction */
         USB_STATUS        status
   )
{ /* Body */
    register HUB_DEVICE_STRUCT_PTR hub_instance = (HUB_DEVICE_STRUCT_PTR) param;
    _mqx_int                       i;

    switch (hub_instance->STATE) {
        case HUB_GET_DESCRIPTOR_TINY_PROCESS: 

            /* here we get number of ports from USB data */
            hub_instance->HUB_PORT_NR = ((HUB_DESCRIPTOR_STRUCT_PTR) buffer)->BNRPORTS;
            hub_instance->STATE = HUB_GET_DESCRIPTOR_PROCESS;
            usb_class_hub_get_descriptor((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, 7 + hub_instance->HUB_PORT_NR / 8 + 1);
            break;

        case HUB_GET_DESCRIPTOR_PROCESS: 
            {
                /* here, we get information from the hub and fill info in hub_instance */
                HUB_DESCRIPTOR_STRUCT_PTR hub_desc = (HUB_DESCRIPTOR_STRUCT_PTR) buffer;

                hub_instance->HUB_PORTS = USB_mem_alloc_zero(hub_instance->HUB_PORT_NR * sizeof(HUB_PORT_STRUCT));
            
                for (i = 0; i < hub_instance->HUB_PORT_NR; i++) 
                {
                    /* get REMOVABLE bit from the desriptor for appropriate installed port */
                    (hub_instance->HUB_PORTS + i)->APP_STATUS = hub_desc->DEVICEREMOVABLE[(i + 1) / 8] & (0x01 << ((i + 1) % 8)) ? HUB_PORT_REMOVABLE : 0;
                }
            }

            /* pass fluently to HUB_SET_PORT_FEATURE_PROCESS */
            hub_instance->STATE = HUB_SET_PORT_FEATURE_PROCESS;
            hub_instance->port_iterator = 0;

        case HUB_SET_PORT_FEATURE_PROCESS: 
//              if (hub_instance->port_iterator)
                /* register, that the port is now powered */
//                hub_instance->HUB_PORTS[hub_instance->port_iterator - 1].POWERED = 1;
            if (hub_instance->port_iterator < hub_instance->HUB_PORT_NR) 
            {
                usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, ++hub_instance->port_iterator, PORT_POWER);
                break;
            } /* EndIf */
            /* else */

            /* pass fluently to HUB_CLEAR_PORT_FEATURE_PROCESS */
            hub_instance->STATE = HUB_CLEAR_PORT_FEATURE_PROCESS;
            hub_instance->port_iterator = 0;
        case HUB_CLEAR_PORT_FEATURE_PROCESS: 
            if (hub_instance->port_iterator < hub_instance->HUB_PORT_NR) 
            {
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, ++hub_instance->port_iterator, C_PORT_CONNECTION);
                break;
            } /* EndIf */
            /* else */

            /* pass fluently to HUB_GET_PORT_STATUS_PROCESS */
            hub_instance->STATE = HUB_GET_PORT_STATUS_PROCESS;
            hub_instance->port_iterator = 0;
        case HUB_GET_PORT_STATUS_PROCESS: 
            if (hub_instance->port_iterator)
                /* register the current status of the port, do the conversion LSB -> MSB */
                (hub_instance->HUB_PORTS + hub_instance->port_iterator - 1)->STATUS = SHORT_LE_TO_HOST(*(uint_16*)buffer);
            if (hub_instance->port_iterator < hub_instance->HUB_PORT_NR)
            {
                usb_class_hub_get_port_status((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, ++hub_instance->port_iterator, 4);
                break;
            } /* EndIf */
            /* else */
            
            /* test if device is attached since startup */
            for (i = 0; i < hub_instance->HUB_PORT_NR; i++)
                if ((hub_instance->HUB_PORTS + i)->STATUS & (1 << PORT_CONNECTION))
                {
                    /* if some device is attached since startup, then start session */
                    hub_instance->port_iterator = i;
                    hub_instance->STATE = HUB_NONE;
                    (hub_instance->HUB_PORTS + i)->APP_STATUS |= HUB_PORT_ATTACHED;
                    usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET);
                    break;
                }

            usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            break;
            
        case HUB_RESET_DEVICE_PORT_PROCESS:
            hub_instance->STATE = HUB_NONE;
            
            usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET);

            usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            break;

        case HUB_ADDRESS_DEVICE_PORT_PROCESS:
            /* compute speed */
            if ((hub_instance->HUB_PORTS + hub_instance->port_iterator)->STATUS & (1 << PORT_HIGH_SPEED))
                i = USB_SPEED_HIGH;
            else if ((hub_instance->HUB_PORTS + hub_instance->port_iterator)->STATUS & (1 << PORT_LOW_SPEED))
                i = USB_SPEED_LOW;
            else
                i = USB_SPEED_FULL;
            
            /* FIXME: accessing intf_handle directly without validation to get its host handle is not good method */
            usb_dev_list_attach_device(
                ((USB_HUB_CLASS_INTF_STRUCT_PTR) hub_instance->CCS.class_intf_handle)->G.host_handle,
                i, /* port speed */
                pipe->DEVICE_ADDRESS, /* hub address */
                hub_instance->port_iterator + 1 /* hub port */
                );

            /* test if there is still device which was not reset */
            for (i = 0; i < hub_instance->HUB_PORT_NR; i++)
                if (((hub_instance->HUB_PORTS + i)->STATUS & (1 << PORT_CONNECTION)) && !((hub_instance->HUB_PORTS + i)->APP_STATUS & HUB_PORT_ATTACHED))
                {
                    /* if some device is attached since startup, then start session */
                    hub_instance->port_iterator = i;
                    hub_instance->STATE = HUB_NONE;
                    (hub_instance->HUB_PORTS + i)->APP_STATUS |= HUB_PORT_ATTACHED;
                    usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET);
                    break;
                }

            usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            break;
        
        case HUB_DETACH_DEVICE_PORT_PROCESS:
            /* FIXME: accessing intf_handle directly without validation to get its host handle is not good method */
            usb_dev_list_detach_device(
                ((USB_HUB_CLASS_INTF_STRUCT_PTR) hub_instance->CCS.class_intf_handle)->G.host_handle,
                pipe->DEVICE_ADDRESS, /* hub address */
                hub_instance->port_iterator + 1 /* hub port */
                );
            
            /* reset the app status */
            (hub_instance->HUB_PORTS + hub_instance->port_iterator)->APP_STATUS = 0x00;

            /* test if there is still device which was not reset */
            for (i = 0; i < hub_instance->HUB_PORT_NR; i++)
                if (((hub_instance->HUB_PORTS + i)->STATUS & (1 << PORT_CONNECTION)) && !((hub_instance->HUB_PORTS + i)->APP_STATUS & HUB_PORT_ATTACHED))
                {
                    /* if some device is attached since startup, then start session */
                    hub_instance->port_iterator = i;
                    hub_instance->STATE = HUB_NONE;
                    (hub_instance->HUB_PORTS + i)->APP_STATUS |= HUB_PORT_ATTACHED;
                    usb_class_hub_set_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, PORT_RESET);
                    break;
                }

            usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            break;
            
        case HUB_GET_PORT_STATUS_ASYNC:
        {
            uint_32 stat = LONG_LE_TO_HOST(*(uint_32*)buffer);
            
            /* register the current status of the port */
            (hub_instance->HUB_PORTS + hub_instance->port_iterator)->STATUS = stat;
    
            /* let's see what happened */
            if ((1 << C_PORT_CONNECTION) & stat)
            {
                /* get if a device on port was attached or detached */
                if ((hub_instance->HUB_PORTS + hub_instance->port_iterator)->APP_STATUS & HUB_PORT_ATTACHED)
                {
                    hub_instance->STATE = HUB_DETACH_DEVICE_PORT_PROCESS;
                    usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_CONNECTION);
                }
                else 
                {
                    hub_instance->STATE = HUB_RESET_DEVICE_PORT_PROCESS;
                    usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_CONNECTION);
                }
                break;
            }
            else if ((1 << C_PORT_RESET) & stat)
            {
                hub_instance->STATE = HUB_ADDRESS_DEVICE_PORT_PROCESS;
                (hub_instance->HUB_PORTS + hub_instance->port_iterator)->APP_STATUS |= HUB_PORT_ATTACHED;
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_RESET);
                break;
            }
            else if ((1 << C_PORT_ENABLE) & stat)
            {
                /* unexpected event (error), just ignore the port */
                hub_instance->STATE = HUB_DETACH_DEVICE_PORT_PROCESS;
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_ENABLE);
                break;
            }
            else if ((1 << C_PORT_OVER_CURRENT) & stat) 
            {
                /* unexpected event (error), just ignore the port */
                hub_instance->STATE = HUB_NONE;
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_OVER_CURRENT);
                usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
                break;
            }
            else if ((1 << C_PORT_POWER) & stat) 
            {
                /* unexpected event (error), just ignore the port */
                hub_instance->STATE = HUB_NONE;
                usb_class_hub_clear_port_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, hub_instance->port_iterator + 1, C_PORT_POWER);
                usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
                break;
            }
            /* FIXME: handle more events */

            break;
        }

        case HUB_GET_STATUS_ASYNC:
        {
            HUB_STATUS_STRUCT_PTR hub_stat = (HUB_STATUS_STRUCT_PTR) buffer;
            uint_32 change = SHORT_LE_TO_HOST(hub_stat->WHUBCHANGE);

            if ((1 << C_HUB_LOCAL_POWER) & change) 
            {
                hub_instance->STATE = HUB_NONE;
                usb_class_hub_clear_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, C_HUB_LOCAL_POWER);
                usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            }
            else if ((1 << C_HUB_OVER_CURRENT) & change) 
            {
                hub_instance->STATE = HUB_NONE;
                usb_class_hub_clear_feature((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_device_sm, (pointer) hub_instance, C_HUB_OVER_CURRENT);
                usb_class_hub_wait_for_interrupt((CLASS_CALL_STRUCT_PTR) &hub_instance->CCS, (tr_callback) usb_host_hub_int_callback, (pointer) hub_instance, hub_instance->HUB_PORT_NR / 8 + 1);
            }
            break;
        }
        
    } /* EndSwitch */
    return;
} /* EndBody */
Ejemplo n.º 3
0
void usb_class_mass_call_back_csw
   (
      /* [IN] Pipe on which CBW call was made */
      _usb_pipe_handle pipe_handle,

      /* [IN] Pointer to the class instance */
      pointer          user_parm,

      /* [IN] Pointer to data buffer */
      uchar_ptr        buffer,

      /* [IN] Length of data transfered */
      uint_32          length_data_transfered,

      /* [IN] Status of the transfer */
      uint_32          status
   )
{ /* Body */
   USB_MASS_CLASS_INTF_STRUCT_PTR   plocal_intf = NULL;
   COMMAND_OBJECT_PTR               cmd_ptr = NULL;
   CSW_STRUCT_PTR                   pCsw = NULL;
   uint_32                          tmp1, tmp2, tmp3;
   boolean                          proc_next = FALSE;
   USB_STATUS                       return_code;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_call_back_csw");
   #endif

   if (user_parm) {
      /* Get the pointer to the pending request */
      plocal_intf =  (USB_MASS_CLASS_INTF_STRUCT_PTR) user_parm;
      usb_class_mass_get_pending_request(plocal_intf, &cmd_ptr);
   } /* Endif */

   if (!cmd_ptr) 
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_call_back_csw, bad param");
      #endif
      return;
   } /* Endif */

   /* Finish transaction and queue next command */
   if (status == USB_OK) {
      pCsw = (CSW_STRUCT_PTR) cmd_ptr->CSW_PTR;
      tmp1 = LONG_LE_TO_HOST(*(uint_32_ptr)pCsw->DCSWTAG);
      tmp2 = LONG_LE_TO_HOST(*(uint_32_ptr)cmd_ptr->CBW_PTR->DCBWTAG);
      tmp3 = LONG_LE_TO_HOST(*(uint_32_ptr)pCsw->DCSWSIGNATURE);

      /* Size must be verified, as well as the signature and the tags */
      if ((length_data_transfered != sizeof(CSW_STRUCT)) ||
         (tmp3 != CSW_SIGNATURE) || (tmp1 != tmp2))
      {
         if (cmd_ptr->RETRY_COUNT < MAX_RETRIAL_ATTEMPTS) {
            cmd_ptr->RETRY_COUNT++;
            cmd_ptr->STATUS = STATUS_FINISHED_DPHASE_ON_USB;
            cmd_ptr->PREV_STATUS =  cmd_ptr->STATUS; /* preserve the status */

            status = usb_class_mass_reset_recovery_on_usb(plocal_intf);
         } else {
            status = STATUS_CANCELLED; /* cannot keep repeating */
         } /* Endif */

         if ((status != USB_OK)  && (status != USBERR_TRANSFER_IN_PROGRESS) &&
             (status != USB_STATUS_TRANSFER_QUEUED))
         {
            proc_next = TRUE;
         } /* Endif */
      } else {
         /* Check value of status field in CSW */
         switch (pCsw->BCSWSTATUS) {
            case CSW_STATUS_GOOD:
               /* Command succeed. Notify application and cleanup */
               cmd_ptr->STATUS = STATUS_COMPLETED;
               proc_next = TRUE;
               break;

            case CSW_STATUS_FAILED:
               /* Command failed. Notify application and cleanup */
               cmd_ptr->STATUS = STATUS_FAILED_IN_CSW;
               proc_next = TRUE;
               break;

            default:
               break;
         } /* Endswitch */
      } /* Endif */
   } else if (status == USBERR_ENDPOINT_STALLED) {
      if (cmd_ptr->RETRY_COUNT < MAX_RETRIAL_ATTEMPTS) {
         cmd_ptr->RETRY_COUNT++;
         cmd_ptr->STATUS = STATUS_FINISHED_DPHASE_ON_USB;
         cmd_ptr->PREV_STATUS =  cmd_ptr->STATUS; /* preserve the status */

         return_code = usb_class_mass_clear_bulk_pipe_on_usb(plocal_intf);
         
         if (return_code != USB_OK && return_code != USB_STATUS_TRANSFER_QUEUED)
         {
            status = USBERR_TRANSFER_IN_PROGRESS;
         }
      } else {
         status = STATUS_CANCELLED; /* cannot keep repeating */
      } /* Endif */

      if ((status != USB_OK) && (status != USBERR_TRANSFER_IN_PROGRESS)) {
         /* Command didn't succeed. Notify application and cleanup */
         cmd_ptr->STATUS = STATUS_CANCELLED;
         proc_next = TRUE;
      } /* Endbody */
   } else {
      /* Command didn't succeed. Notify application and cleanup */
      cmd_ptr->STATUS = STATUS_CANCELLED;
      proc_next = TRUE;
   } /* Endif */

   /* Should we cleanup and process the next command? */
   if (proc_next) {
      cmd_ptr->CALLBACK(status, plocal_intf, cmd_ptr, cmd_ptr->TR_BUF_LEN);
      usb_class_mass_deleteq(plocal_intf);

      /* Send next command, if any */
      if (!USB_CLASS_MASS_IS_Q_EMPTY(plocal_intf)) {
         status = usb_class_mass_pass_on_usb( plocal_intf);
      } /* Endbody */
   } /* Endif */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_call_back_csw, SUCCESSFUL");
   #endif
   
} /* Endbody */