Esempio n. 1
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_host_driver_info_match
* Returned Value : TRUE for driver match, else FALSE
* Comments       :
*     Match device driver info with class etc. in device/interface
*     following the ordering in "USB Common Class Specification"
*     Rev. 1.0, August 18, 1998, p. 7
*  It is presumed that this function is called with USB interrupts disabled
*
*END*--------------------------------------------------------------------*/
bool  usb_host_driver_info_match
(
    /* [IN] USB device */
    dev_instance_t*           dev_ptr,
    /* [IN] Configuration number */
    interface_descriptor_t*   intf_ptr,
    /* [IN] TRUE=attach, FALSE=detach */
    usb_host_driver_info_t*   info_ptr
)
{ /* Body */
    uint16_t  info_Vendor, info_Product, dev_Vendor, dev_Product;

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

    info_Vendor = USB_SHORT_UNALIGNED_LE_TO_HOST(info_ptr->idVendor);
    info_Product = USB_SHORT_UNALIGNED_LE_TO_HOST(info_ptr->idProduct);

    /* If vendor and product are listed in table (non-zero) */
    if ((info_Vendor | info_Product) != 0)
    {
        dev_Vendor = USB_SHORT_UNALIGNED_LE_TO_HOST(dev_ptr->dev_descriptor.idVendor);
        dev_Product = USB_SHORT_UNALIGNED_LE_TO_HOST(dev_ptr->dev_descriptor.idProduct);
 
        if ((info_Vendor == dev_Vendor) &&
            (info_Product == dev_Product))
        {
            #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_driver_info_match PID, VID match");
            #endif
            return TRUE;
        } /* Endif */
    }

   /* note: zero value class in the device descriptor means
   ** that the class is defined in interface descriptor
   */
    if ((info_ptr->bDeviceClass == 0xFF) || /* if the device class is any OR */
      ((info_ptr->bDeviceClass ==             /* or the device class matches */
      dev_ptr->dev_descriptor.bDeviceClass) && 
      (dev_ptr->dev_descriptor.bDeviceClass != 0x00))) /* but it is not zero-value match */
    {
        if ((info_ptr->bDeviceSubClass ==
             dev_ptr->dev_descriptor.bDeviceSubClass) &&
             (info_ptr->bDeviceProtocol ==
             dev_ptr->dev_descriptor.bDeviceProtocol))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match class, match subclass, match protocol");
            #endif
            return TRUE;
        } /* Endif */

        if ((info_ptr->bDeviceSubClass ==
             dev_ptr->dev_descriptor.bDeviceSubClass) &&
             (info_ptr->bDeviceProtocol == 0xFF))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match class, match subclass");
            #endif
            return TRUE;
        }

        if ((info_ptr->bDeviceSubClass == 0xFF) && 
            (info_ptr->bDeviceProtocol ==
            dev_ptr->dev_descriptor.bDeviceProtocol))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match class, match protocol");
            #endif
            return TRUE;
        }

        if ((info_ptr->bDeviceSubClass == 0xFF) && 
            (info_ptr->bDeviceProtocol == 0xFF))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match class");
            #endif
            return TRUE;
        }
    }

    /* No Device match, try Interface */
    if ((info_ptr->bDeviceClass == 0xFF) || /* if the device class is any OR */
        ((info_ptr->bDeviceClass == /* or the class matches interface class */
        intf_ptr->bInterfaceClass)))
    {
        if ((info_ptr->bDeviceSubClass ==
             intf_ptr->bInterfaceSubClass) &&
            (info_ptr->bDeviceProtocol ==
             intf_ptr->bInterfaceProtocol))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match interface class, match interface subclass, match interface protocol");
            #endif
            return TRUE;
        } /* Endif */

        if ((info_ptr->bDeviceSubClass ==
             intf_ptr->bInterfaceSubClass) &&
            (info_ptr->bDeviceProtocol == 0xFF))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match interface class, match interface subclass, match interface protocol");
            #endif
            return TRUE;
        }

        if ((info_ptr->bDeviceSubClass == 0xFF) && 
            (info_ptr->bDeviceProtocol ==
            intf_ptr->bInterfaceProtocol))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match interface class, match interface protocol");
            #endif
            return TRUE;
        }

        if ((info_ptr->bDeviceSubClass == 0xFF) && 
            (info_ptr->bDeviceProtocol == 0xFF))
        {
            #ifdef _HOST_DEBUG_
                DEBUG_LOG_TRACE("usb_host_driver_info_match interface class");
            #endif
            return TRUE;
        }
   }

    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_host_driver_info_match interface No Match");
    #endif
    return FALSE;
} /* EndBody */
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,
            (pointer2)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 (utoh32(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,
               (pointer2)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,
            (pointer2)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 status;
} /* Endbody */
Esempio n. 3
0
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_host_dev_mng_attach
* Returned Value : 
* Comments       :
*     This function will be called when attach interrupt happens, to
*       add onto the device list and do common initialization.     
* 
*END*--------------------------------------------------------------------*/
usb_status usb_host_dev_mng_attach
   (
      usb_host_handle  handle,
      hub_device_struct_t* hub_instance,
      uint8_t            speed,
      uint8_t            hub_no,
      uint8_t            port_no,
      uint8_t           level,
      usb_device_instance_handle* handle_ptr 
   )
{
    usb_status                  status;
    dev_instance_t*             new_instance_ptr;
    dev_instance_t*             dev_instance_ptr;
    dev_instance_t*             dev_instance_prev_ptr;
    usb_host_state_struct_t*    usb_host_ptr;
    //dev_instance_t*           device_root = NULL;
    pipe_init_struct_t          pipe_init;

    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_dev_list_attach_device attach device");
    #endif
    usb_host_ptr = (usb_host_state_struct_t*)handle;
    //printf("a %d %d %d\n", hub_no, port_no, level);
 
    /* Allocate new device instance */
    new_instance_ptr = (dev_instance_t*) OS_Mem_alloc_uncached_zero(sizeof(dev_instance_t));
    if (new_instance_ptr == NULL)
    {
        #ifdef _HOST_DEBUG_
           DEBUG_LOG_TRACE("usb_dev_list_attach_device failed to malloc device handle");
        #endif
        printf("memory allocation failed in usb_host_dev_mng_attach\n");
        return USB_log_error(__FILE__,__LINE__, USBERR_GET_MEMORY_FAILED);
    } /* EndIf */
 
    new_instance_ptr->host = handle;
    new_instance_ptr->speed = speed;
	new_instance_ptr->hub_instance = hub_instance;
    new_instance_ptr->hub_no = hub_no;
    new_instance_ptr->port_no = port_no;
    new_instance_ptr->level = level;
    new_instance_ptr->cfg_value = 0; /* We don't know yet what the device's default configuration is */
    new_instance_ptr->attached = (uint8_t)TRUE;
    new_instance_ptr->pre_detached = (uint8_t)FALSE;
    //printf("l1\n");
    USB_Host_lock();
    //printf("l2\n");
    dev_instance_ptr = usb_host_ptr->device_list_ptr;
    while (dev_instance_ptr != NULL)
    {
        if ((dev_instance_ptr->hub_no == hub_no) &&
            (dev_instance_ptr->port_no == port_no))
        {
            USB_Host_unlock();
            OS_Mem_free((void*)new_instance_ptr);
            printf("invalidate attach\n");
            *handle_ptr = NULL;
            return USBERR_ERROR;
        }
        else
        {
            dev_instance_ptr = dev_instance_ptr->next;
        }
    }
    //printf("l3\n");
    /* Find unused address from 1 - 127 for this host */
    dev_instance_ptr = usb_host_ptr->device_list_ptr;
    if ((dev_instance_ptr == NULL) || (dev_instance_ptr->address != 1))
    {
        /* Insert at the beginning of list */
        new_instance_ptr->target_address = 1;
        new_instance_ptr->next = dev_instance_ptr;
        usb_host_ptr->device_list_ptr = new_instance_ptr;
    }
    else
    {
        dev_instance_prev_ptr = dev_instance_ptr;
        /* Searching for a 'hole' in devices instance adresses */
        while (dev_instance_ptr->target_address <= (dev_instance_prev_ptr->target_address + 1))
        {
            new_instance_ptr->target_address = dev_instance_ptr->target_address;
            dev_instance_prev_ptr = dev_instance_ptr;
            dev_instance_ptr = dev_instance_ptr->next;
            if (dev_instance_ptr == NULL)
                break;
        } /* EndWhile */
        if (new_instance_ptr->target_address >= 127)
        {
            /* If all 127 addresses used up, delete instance & bail out */
            USB_Host_unlock();
            OS_Mem_free((void*)new_instance_ptr);
            #ifdef _HOST_DEBUG_
               DEBUG_LOG_TRACE("usb_dev_list_attach_device out of addresses");
            #endif
            printf("no valid address for the device\n");
            *handle_ptr = NULL;
            return USB_log_error(__FILE__,__LINE__, USBERR_ADDRESS_ALLOC_FAILED);
        } /* EndIf */
        new_instance_ptr->target_address++;
        new_instance_ptr->next = dev_instance_ptr;
        dev_instance_prev_ptr->next = new_instance_ptr;
    };
    //printf("l4\n");   
    USB_Host_unlock();
 
    /*-----------------------------------------------------------**
        ** Open control pipe, get first 8 bytes of device descriptor **
        ** The host_ch9 routine internally sets the callback to      **
        **    usb_host_cntrl_transaction_done (in usb_host_ch9.c)    **
        **    where the action resumes on completion of the get.     **
        **-----------------------------------------------------------*/
    pipe_init.endpoint_number  = 0;
    pipe_init.direction        = 0;
    pipe_init.pipetype         = USB_CONTROL_PIPE;
    pipe_init.max_packet_size  = 64;
    pipe_init.interval         = 0;
    pipe_init.flags            = 0;
    pipe_init.dev_instance     = new_instance_ptr;
    pipe_init.nak_count        = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT;
 
    if (USB_OK != usb_host_open_pipe(new_instance_ptr->host, &new_instance_ptr->control_pipe, &pipe_init))
    {
        OS_Mem_free((void*)new_instance_ptr);
        *handle_ptr = NULL;
        #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_dev_list_attach_device open pipe failed");
        #endif
        printf("can't open control pipe\n");
        return USB_log_error(__FILE__,__LINE__, USBERR_PIPE_OPENED_FAILED);
    } /* Endif */
 
    /* Set state to enter after transaction completion */
    new_instance_ptr->state = DEVSTATE_DEVDESC8;
 
    status = _usb_host_ch9_get_descriptor((usb_device_instance_handle)new_instance_ptr,
                                          USB_DESC_TYPE_DEV << 8, 0, 8, 
                                          (uint8_t *)&new_instance_ptr->dev_descriptor);
       
    if (status != USB_OK)
    {
        new_instance_ptr->state = DEVSTATE_INITIAL;
        #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_dev_list_attach_device FAILED");
        #endif
        printf("get descriptor error\n");
        *handle_ptr = (usb_device_instance_handle)new_instance_ptr;
        return USB_log_error(__FILE__,__LINE__, USBERR_NO_DESCRIPTOR);
    }
    
    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_dev_list_attach_device SUCCESSFUL");
    #endif
    *handle_ptr = (usb_device_instance_handle)new_instance_ptr;
    //printf("attach done\n");
    return USB_OK;
} /* EndBody */
Esempio n. 4
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_dev_list_detach_device
* Returned Value :
* Comments       :
*     This function will be called when detach interrupt happens.
*
*END*--------------------------------------------------------------------*/
void  usb_dev_list_detach_device
(
    _usb_host_handle  handle,
    uint_8            hub_no,
    uint_8            port_no
)
{   /* Body */
    USB_HOST_STATE_STRUCT_PTR  usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
    DEV_INSTANCE_PTR  dev_instance_ptr;
    DEV_INSTANCE_PTR  _PTR_ device_root = (DEV_INSTANCE_PTR _PTR_)&usb_host_ptr->DEVICE_LIST_PTR;
#ifdef __USB_OTG__
    uint_32           state;
#endif

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

    /* search device list for the one being detached */
    USB_lock();
    for (dev_instance_ptr = *device_root;
            dev_instance_ptr != NULL;
            dev_instance_ptr = dev_instance_ptr->next)
    {
        if (dev_instance_ptr->port_no != port_no)
            continue;
        if (dev_instance_ptr->hub_no != hub_no)
            continue;
        if (dev_instance_ptr->host != handle)
            continue;
        break;
    } /* EndFor */

    USB_unlock();

    if (dev_instance_ptr == NULL) {
#ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_dev_list_detach_device NULL device pointer");
#endif
        return;  /* No match, abandon ship! */
    } /* Endif */

    /* SGarg 09/23/2003 . Sometimes  a detach could come even before a
    attach is finished. This means that we should make sure that device
    memory is not NULL before we try to clean it up. For example this happens
    with OPT tester test 4.10.*/

    if(dev_instance_ptr->memlist != NULL)
    {
        /* Notify the application of unavailable interfaces */
        usb_hostdev_attach_detach(dev_instance_ptr, USB_DETACH_EVENT);

    }

    /* Unlink device from the instance list */
    dev_instance_ptr->control_callback = NULL; /* no surprises */

    /* Close control pipe */
    usb_dev_list_close_pipe(handle, (PIPE_STRUCT_PTR)dev_instance_ptr->control_pipe);

    /* SGarg 09/24/2003 . Sometimes  a detach could come even before a
    attach is finished. This means that we should make sure that device
    memory is not NULL before we try to clean it up. For example this happens
    with OPT tester test 4.10.*/
    if(dev_instance_ptr->memlist != NULL)
    {
        usb_dev_list_free_memlist((_usb_device_instance_handle)dev_instance_ptr);
    }

    USB_lock();

    /* Find the address of the "pointer to the detached device" */
    while (*device_root != dev_instance_ptr) {
        device_root = &(*device_root)->next;
    } /* Endwhile */

    /* Remove the device */
    *device_root = dev_instance_ptr->next;

    USB_mem_free(dev_instance_ptr);

#ifdef __USB_OTG__
    _usb_otg_get_status((pointer)usb_otg_state_struct_ptr,
                        USB_OTG_STATE, &state);

    if (state < B_IDLE) {
        _usb_otg_get_status((pointer)usb_otg_state_struct_ptr,
                            USB_OTG_B_CONN, &state);
        if (state) {
            _usb_otg_set_status((pointer)usb_otg_state_struct_ptr,
                                USB_OTG_B_CONN, FALSE);
        } /* Endif */
    } else {
        _usb_otg_get_status((pointer)usb_otg_state_struct_ptr,
                            USB_OTG_A_CONN, &state);
        if (state) {
            _usb_otg_set_status((pointer)usb_otg_state_struct_ptr,
                                USB_OTG_A_CONN, FALSE);
        } /* Endif */
    } /* Endif */
#endif

    USB_unlock();
#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_dev_list_detach_device SUCCESSFUL");
#endif

} /* EndBody */
void usb_class_mass_call_back_dphase
   (
      /* [IN] Pipe on which CBW call was made */
      _usb_pipe_handle pipe_handle,

      /* [IN] Pointer to the class instance */
      pointer2          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;
   COMMAND_OBJECT_PTR               cmd_ptr = NULL;
   USB_STATUS                       return_code;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_call_back_dphase");
   #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_dphase, bad parameter");
      #endif
      return;
   } /* Endif */

   /* Save length transferred during data phase */
   cmd_ptr->TR_BUF_LEN = length_data_transfered;

   /* Test if full or partial data received */
   if (status == USB_OK || status == USB_STATUS_TRANSFER_QUEUED ||
      ((status == USBERR_TR_FAILED) && (buffer != NULL)))
   {
      /* Everything is OK, update status and go to next phase */
      cmd_ptr->STATUS = STATUS_FINISHED_DPHASE_ON_USB;
      status = usb_class_mass_pass_on_usb(plocal_intf);

   } else if (status == USBERR_ENDPOINT_STALLED) {

      if (cmd_ptr->RETRY_COUNT < MAX_RETRIAL_ATTEMPTS) {
         cmd_ptr->RETRY_COUNT++;
         cmd_ptr->STATUS = STATUS_QUEUED_IN_DRIVER;
         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 = STATUS_CANCELLED;
         }

      } else {
         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 = STATUS_CANCELLED;
         }
      } /* Endif */
   } /* Endif */

   if ((status != USB_OK) && (status != USBERR_ENDPOINT_STALLED) &&
      (status != USBERR_TRANSFER_IN_PROGRESS) && (status != USB_STATUS_TRANSFER_QUEUED))
   {
      /* Command didn't succeed. Notify application and cleanup */
      cmd_ptr->STATUS =STATUS_CANCELLED;
      cmd_ptr->CALLBACK((USB_STATUS)USB_MASS_FAILED_IN_DATA, plocal_intf, cmd_ptr,
         cmd_ptr->TR_BUF_LEN);
      usb_class_mass_deleteq(plocal_intf);

      /* Go to the next command, if any */
      status = usb_class_mass_pass_on_usb(plocal_intf);
   } /* Endif */
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_call_back_dphase, SUCCESSFUL");
   #endif
   
} /* Endbody */
Esempio n. 6
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_dev_list_free_mem
* Returned Value : USB_OK if memory is freed, else error code
* Comments       :
*     Memory is unlinked and freed from dev_ptr->memlist
*
*END*--------------------------------------------------------------------*/
USB_STATUS usb_dev_list_free_mem
(
    /* [IN] Pointer to the USB device */
    DEV_INSTANCE_PTR        dev_ptr,

    /* [IN] Pointer to memory */
    DEV_MEMORY_PTR          header_ptr
)
{   /* Body */

    DEV_MEMORY_PTR  mem_ptr, list_ptr;
    DEV_MEMORY_PTR  prev_ptr = NULL;
    USB_STATUS      error;

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

    USB_lock();
    error = usb_hostdev_validate((_usb_device_instance_handle)dev_ptr);
    USB_unlock();

    if (error != USB_OK) {
#ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_dev_list_free_mem invalid device handle");
#endif
        return USB_log_error(__FILE__,__LINE__,error);
    }
    mem_ptr = (DEV_MEMORY_PTR) header_ptr;

    if (mem_ptr == NULL)
    {
#ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_dev_list_free_mem invalid memory pointer");
#endif
        return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_MEM_TYPE);
    } /* Endif */

    for (list_ptr = dev_ptr->memlist; list_ptr != NULL; list_ptr = list_ptr->next) {
        if (list_ptr == mem_ptr)
            break;
        prev_ptr = list_ptr;
    }

    if (list_ptr == NULL) {
#ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_dev_list_free_mem not found");
#endif
        return USB_log_error(__FILE__,__LINE__,USBERR_NOT_FOUND);
    }

    /* Unlink the buffer from the list */
    if (dev_ptr->memlist == mem_ptr) {
        /* Unlink from anchor */
        /* WARNING!!! The first buffer in the chain is the full configuration descriptor,
        ** so there is probably some issue if there is attempt to free it, because
        ** configuration descriptor must have its lifetime till the device's detach or
        ** till selecting another configuration.
        */
        dev_ptr->memlist = mem_ptr->next;
    } else {
        if(prev_ptr != NULL) {
            /* Unlink from chain */
            prev_ptr->next = mem_ptr->next;
        }
    }

    /* Free associated memory */
    USB_mem_free(mem_ptr);

#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_dev_list_free_mem SUCCESSFUL");
#endif

    return USB_OK;
} /* Endbody */
Esempio n. 7
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_dev_list_attach_device
* Returned Value :
* Comments       :
*     This function will be called when attach interrupt happens, to
*       add onto the device list and do common initialization.
*
*END*--------------------------------------------------------------------*/
USB_STATUS usb_dev_list_attach_device
(
    _usb_host_handle  handle,
    uint_8            speed,
    uint_8            hub_no,
    uint_8            port_no
)
{   /* Body */
    USB_STATUS                 status;
    DEV_INSTANCE_PTR           new_instance_ptr, dev_instance_ptr, dev_instance_prev_ptr;
    PIPE_INIT_PARAM_STRUCT     ctrl_pipe_init_params;
    USB_HOST_STATE_STRUCT_PTR  usb_host_ptr;
    DEV_INSTANCE_PTR           device_root = NULL;
#ifdef __USB_OTG__
    uint_32                    state;
#endif

#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_dev_list_attach_device attach device");
#endif
    usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;

    /* Allocate new device instance */
    new_instance_ptr = (DEV_INSTANCE_PTR) USB_mem_alloc_uncached(sizeof(DEV_INSTANCE));

    if (new_instance_ptr == NULL) {
#ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_dev_list_attach_device failed to malloc device handle");
#endif
        return USB_log_error(__FILE__,__LINE__, USBERR_GET_MEMORY_FAILED);
    } /* EndIf */
    _mem_set_type(new_instance_ptr, MEM_TYPE_USB_HOST_STATE_STRUCT);

    USB_mem_zero(new_instance_ptr, sizeof(DEV_INSTANCE));

    new_instance_ptr->host = handle;
    new_instance_ptr->speed = speed;
    new_instance_ptr->hub_no = hub_no;
    new_instance_ptr->port_no = port_no;
    new_instance_ptr->cfg_value = 0; /* We don't know yet what the device's default configuration is */

    USB_lock();

    /* Find unused address from 1 - 127 for this host */
    dev_instance_ptr = usb_host_ptr->DEVICE_LIST_PTR;
    if ((dev_instance_ptr == NULL) || (dev_instance_ptr->address != 1)) {
        /* Insert at the beginning of list */
        new_instance_ptr->address = 1;
        new_instance_ptr->next = dev_instance_ptr;
        usb_host_ptr->DEVICE_LIST_PTR = new_instance_ptr;
    }
    else {
        dev_instance_prev_ptr = dev_instance_ptr;
        /* Searching for a 'hole' in devices instance adresses */
        while (dev_instance_ptr->address <= (dev_instance_prev_ptr->address + 1)) {
            new_instance_ptr->address = dev_instance_ptr->address;
            dev_instance_prev_ptr = dev_instance_ptr;
            dev_instance_ptr = dev_instance_ptr->next;
            if (dev_instance_ptr == NULL)
                break;
        } /* EndWhile */
        if (new_instance_ptr->address >= 127) {
            /* If all 127 addresses used up, delete instance & bail out */
            USB_unlock();
            USB_mem_free((pointer)new_instance_ptr);
#ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_dev_list_attach_device out of addresses");
#endif
            return USB_log_error(__FILE__,__LINE__, USBERR_ADDRESS_ALLOC_FAILED);
        } /* EndIf */
        new_instance_ptr->address++;
        new_instance_ptr->next = dev_instance_ptr;
        dev_instance_prev_ptr->next = new_instance_ptr;
    };

    USB_unlock();

    /*-----------------------------------------------------------**
    ** Open control pipe, get first 8 bytes of device descriptor **
    ** The host_ch9 routine internally sets the callback to      **
    **    usb_host_cntrl_transaction_done (in usb_host_ch9.c)    **
    **    where the action resumes on completion of the get.     **
    **-----------------------------------------------------------*/

    ctrl_pipe_init_params = pipe_init_params_prototype;
    ctrl_pipe_init_params.G.DEV_INSTANCE = new_instance_ptr;
    ctrl_pipe_init_params.G.PIPETYPE = USB_CONTROL_PIPE;
    ctrl_pipe_init_params.G.SPEED = new_instance_ptr->speed;

    ctrl_pipe_init_params.G.HUB_DEVICE_ADDR = hub_no;
    ctrl_pipe_init_params.G.HUB_PORT_NUM = port_no;
#ifdef __USB_OTG__
    _usb_otg_get_status((pointer)usb_otg_state_struct_ptr,
                        USB_OTG_STATE, &state);

    if (state < B_IDLE) {
        _usb_otg_set_status((pointer)usb_otg_state_struct_ptr,
                            USB_OTG_A_BUS_REQ, TRUE);
        _usb_otg_set_status((pointer)usb_otg_state_struct_ptr,
                            USB_OTG_B_CONN, TRUE);
    } else {
        _usb_otg_set_status((pointer)usb_otg_state_struct_ptr,
                            USB_OTG_A_CONN, TRUE);
    } /* Endif */
#endif

    if (USB_OK != _usb_host_open_pipe(new_instance_ptr->host,
                                      &ctrl_pipe_init_params,
                                      &new_instance_ptr->control_pipe))
    {
        USB_mem_free((pointer)new_instance_ptr);
#ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_dev_list_attach_device open pipe failed");
#endif
        return USB_log_error(__FILE__,__LINE__, USBERR_PIPE_OPENED_FAILED);
    } /* Endif */

    /* Set state to enter after transaction completion */
    new_instance_ptr->state = DEVSTATE_DEVDESC8;

    status = _usb_host_ch9_get_descriptor((_usb_device_instance_handle)new_instance_ptr,
                                          USB_DESC_TYPE_DEV << 8, 0, 8,
                                          (uchar_ptr)&new_instance_ptr->dev_descriptor);

    if (status != USB_STATUS_TRANSFER_QUEUED)
    {
        new_instance_ptr->state = DEVSTATE_INITIAL;
#ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_dev_list_attach_device FAILED");
#endif
        return USB_log_error(__FILE__,__LINE__, USBERR_NO_DESCRIPTOR);
    }

#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_dev_list_attach_device SUCCESSFUL");
#endif
    return USB_OK;

} /* EndBody */
Esempio n. 8
0
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_recv_data
*  Returned Value : USB_OK or error code
*  Comments       :
*        Receives data on a specified endpoint.
*
*END*-----------------------------------------------------------------*/
uint_8 _usb_device_recv_data
   (
      /* [IN] the USB_USB_dev_initialize state structure */
      _usb_device_handle         handle,
            
      /* [IN] the Endpoint number */
      uint_8                     ep_num,
            
      /* [IN] buffer to receive data */
      uchar_ptr                  buff_ptr,
            
      /* [IN] length of the transfer */
      uint_32                    size
   )
{ /* Body */

   #ifdef _DEVICE_DEBUG_
      DEBUG_LOG_TRACE("_usb_device_recv_data");
   #endif

   uint_8                           error = USB_OK;
   XD_STRUCT_PTR                    xd_ptr;
   USB_DEV_STATE_STRUCT_PTR         usb_dev_ptr;
   
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
   
   USB_lock();

   if (!usb_dev_ptr->XD_ENTRIES) 
   {
      USB_unlock();
      #ifdef _DEVICE_DEBUG_
         DEBUG_LOG_TRACE("_usb_device_recv_data, transfer in progress");
      #endif
      return USB_STATUS_TRANSFER_IN_PROGRESS;
   } /* Endif */

   /* Get a transfer descriptor for the specified endpoint 
   ** and direction 
   */
   USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr);
   
   usb_dev_ptr->XD_ENTRIES--;

   /* Initialize the new transfer descriptor */      
   xd_ptr->EP_NUM = ep_num;
   xd_ptr->BDIRECTION = USB_RECV;
   xd_ptr->WTOTALLENGTH = size;
   xd_ptr->WSOFAR = 0;
   xd_ptr->WSTARTADDRESS = buff_ptr;
   
   xd_ptr->BSTATUS = USB_STATUS_TRANSFER_ACCEPTED;

  error = _usb_dci_vusb20_recv_data(handle, xd_ptr);

   USB_unlock();
   
   if (error) 
   {
      #ifdef _DEVICE_DEBUG_
         DEBUG_LOG_TRACE("_usb_device_recv_data, receive failed");
      #endif
      return USBERR_RX_FAILED;
   } /* Endif */
   
   return error;

} /* EndBody */
Esempio n. 9
0
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_device_get_status
* Returned Value : USB_OK or error code
* Comments       :
*     Provides API to access the USB internal state.
* 
*END*--------------------------------------------------------------------*/
uint_8 _usb_device_get_status
   (
      /* [IN] Handle to the USB device */
      _usb_device_handle   handle,
      
      /* [IN] What to get the status of */
      uint_8               component,
      
      /* [OUT] The requested status */
      uint_16_ptr          status
   )
{ /* Body */
   USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;

   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

   #ifdef _DEVICE_DEBUG_
      DEBUG_LOG_TRACE("_usb_device_get_status, SUCCESSFULL");
   #endif
   
   USB_lock();
   switch (component) {

      case USB_STATUS_DEVICE_STATE:
         *status = usb_dev_ptr->USB_STATE;
         break;

      case USB_STATUS_DEVICE:
         *status = usb_dev_ptr->USB_DEVICE_STATE;
         break;
         #ifndef SMALL_CODE_SIZE
      case USB_STATUS_INTERFACE:
         break;
         #endif         
      case USB_STATUS_ADDRESS:
         *status = usb_dev_ptr->DEVICE_ADDRESS;
         break;
         
      case USB_STATUS_CURRENT_CONFIG:
         *status = usb_dev_ptr->USB_CURR_CONFIG;
         break;

      case USB_STATUS_SOF_COUNT:
         *status = usb_dev_ptr->USB_SOF_COUNT;
         break;
         
      default:
         if (component & USB_STATUS_ENDPOINT) {
            *status = _usb_dci_vusb20_get_endpoint_status(handle,
               component & USB_STATUS_ENDPOINT_NUMBER_MASK);
         } else {
            USB_unlock();
            #ifdef _DEVICE_DEBUG_
               DEBUG_LOG_TRACE("_usb_device_get_status, bad status");
            #endif
            return USBERR_BAD_STATUS;
         } /* Endif */
         break;

   } /* Endswitch */
   
   USB_unlock();

   #ifdef _DEVICE_DEBUG_
      DEBUG_LOG_TRACE("_usb_device_get_status, SUCCESSFUL");
   #endif
   
   return USB_OK;   
} /* EndBody */  
Esempio n. 10
0
/*FUNCTION*-------------------------------------------------------------------
 *
 * Function Name    : usb_otg_init
 * Returned Value   : initialization message
 * Comments         : Initializes OTG stack 
 *    
 *
 *END*----------------------------------------------------------------------*/
usb_status usb_otg_init
(
    /* [IN] the USB device controller to initialize */
    uint8_t controller_id,
    /*[IN] address of the OTG initialization  structure */
    otg_int_struct_t * init_struct_ptr,
    /* [IN] the USB otg board init handle */
    otg_board_init  board_init_callback,   
    /* [OUT] the USB host handle */
    usb_otg_handle * handle
)
{
    usb_status error = USB_OK;
    const usb_otg_api_functions_struct_t * otg_api = NULL;
    usb_otg_state_struct_t * usb_otg_ptr = NULL;
    if ((init_struct_ptr == NULL) || (handle == NULL))
    {
#if ((defined _OTG_DEBUG_) && (_OTG_DEBUG))
        DEBUG_LOG_TRACE ("usb_otg_init invalid parameters");
#endif

        return USBERR_ERROR;
    }
    _usb_otg_get_api(controller_id, &otg_api);
    if (otg_api == NULL)
    {
        return USBERR_ERROR;
    }
    /* Initialize the USB interface. */
    if (otg_api->otg_preinit != NULL)
    {
        error = otg_api->otg_preinit((usb_otg_handle *) (&(usb_otg_ptr)));
        if (error || (usb_otg_ptr == NULL))
        {
#if ((defined _OTG_DEBUG_) && (_OTG_DEBUG))
            DEBUG_LOG_TRACE ("usb_OTG_init preinit failure");
#endif
            return USBERR_ALLOC;
        }
    }
    g_usb_otg_handle = usb_otg_ptr;
    usb_otg_ptr->otg_controller_api = otg_api; 
    if( NULL !=board_init_callback )
    {
        error = (uint32_t)board_init_callback(controller_id);
    }
    else
    {
        error = USB_OK;
    }
    if(USB_OK == error)
    {
        error = usb_otg_soc_init(controller_id);
    }
    if (error != USB_OK)
    {
        if (otg_api->otg_shutdown != NULL)
        {
            error = otg_api->otg_shutdown(usb_otg_ptr);
        }
#if ((defined _OTG_DEBUG_) && (_OTG_DEBUG))
        DEBUG_LOG_TRACE ("_usb_host_init: BSP-specific USB initialization failure");
#endif
        return USB_log_error(__FILE__, __LINE__, USBERR_UNKNOWN_ERROR);
    }

    usb_otg_ptr->init_struct = init_struct_ptr;
    /* initialize the event used for application signaling and for ISR*/
    usb_otg_ptr->otg_app_event = OS_Event_create(0);
    usb_otg_ptr->otg_isr_event = OS_Event_create(0);
    usb_otg_ptr->device_state = USB_OTG_DEVSTATE_UNDEFINED;
    usb_otg_ptr->sub_state = USB_OTG_SM_UNDEFINED;
    usb_otg_ptr->power_up = TRUE;

    if (otg_api->otg_init != NULL)
    {
        error = otg_api->otg_init(controller_id, usb_otg_ptr);
    }

    if (error != USB_OK)
    {
        if (otg_api->otg_shutdown != NULL)
        {
            error = otg_api->otg_shutdown(usb_otg_ptr);
        }
#if ((defined _OTG_DEBUG_) && (_OTG_DEBUG))
        DEBUG_LOG_TRACE ("_usb_host_init: BSP-specific USB initialization failure");
#endif
        return USB_log_error(__FILE__, __LINE__, USBERR_UNKNOWN_ERROR);
    }

    error = _usb_otg_task_create(usb_otg_ptr);

    if (error != USB_OK)
    {
        if (otg_api->otg_shutdown != NULL)
        {
            otg_api->otg_shutdown(usb_otg_ptr);
        }
        (void) OS_Event_destroy(usb_otg_ptr->otg_app_event);
        (void) OS_Event_destroy(usb_otg_ptr->otg_isr_event);
        OS_Mem_free(usb_otg_ptr);
        usb_otg_ptr = NULL;

        OS_Unlock();
        return error;
    }
    *handle = (usb_otg_handle) usb_otg_ptr;
    return USB_OK;
}
Esempio n. 11
0
void usb_printer_init
   (
      /* [IN] device/descriptor/pipe handles */
      PIPE_BUNDLE_STRUCT_PTR  pbs_ptr,
      
      /* [IN] class-interface data pointer + key */
      CLASS_CALL_STRUCT_PTR   prt_call_ptr
   )
{ /* Body */

   PRINTER_INTERFACE_STRUCT_PTR  prt_intf;

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

   /* Pointer validity-checking, clear memory, init header */
   prt_intf = prt_call_ptr->class_intf_handle;
   if (USB_OK != usb_host_class_intf_init (pbs_ptr, (pointer)prt_intf, (pointer)&prt_anchor, NULL))
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_printer_init, error class init");
      #endif
      return;
   }

   USB_lock();
   prt_call_ptr->code_key = 0;
   prt_call_ptr->code_key = usb_host_class_intf_validate(prt_call_ptr);

   if (NULL == 
         (prt_intf->control_pipe = usb_hostdev_get_pipe_handle 
         (pbs_ptr, USB_CONTROL_PIPE, 0) ))
      goto Bad_Exit;

   if (NULL == 
         (prt_intf->bulk_out_pipe = usb_hostdev_get_pipe_handle 
         (pbs_ptr, USB_BULK_PIPE, USB_SEND) ))
      goto Bad_Exit;

   /* Uni-directional printers don't have a bulk-in pipe */
   if (((INTERFACE_DESCRIPTOR_PTR)prt_intf->intf_handle)->
         bInterfaceSubClass > USB_PROTOCOL_PRT_UNIDIR)
      {
      if (NULL ==
            (prt_intf->bulk_in_pipe = usb_hostdev_get_pipe_handle 
            (pbs_ptr, USB_BULK_PIPE, USB_RECV) ))
         goto Bad_Exit;
      } /* EndIf */

   USB_unlock ();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_init, SUCCESSFUL");
   #endif
   
   return;  /* Good exit, interface struct initialized */

   Bad_Exit:
   USB_mem_zero (prt_intf,sizeof(PRINTER_INTERFACE_STRUCT_PTR));
   prt_call_ptr->class_intf_handle = NULL;
   prt_call_ptr->code_key = 0;
   USB_unlock ();
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_printer_init, bad exit");
   #endif
   
} /* Endbody */
Esempio n. 12
0
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_recv_data
*  Returned Value : USB_OK or error code
*  Comments       :
*        Receives data on a specified endpoint.
*
*END*-----------------------------------------------------------------*/
uint8_t _usb_device_recv_data(
				   /* [IN] the USB_USB_dev_initialize state structure */
				   _usb_device_handle handle,
				   /* [IN] the Endpoint number */
				   uint8_t ep_num,
				   /* [IN] buffer to receive data */
				   uint8_t * buff_ptr,
				   /* [IN] length of the transfer */
				   uint32_t size)
{				/* Body */
	uint8_t error = USB_OK;
	XD_STRUCT_PTR xd_ptr;
	USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;

	TOMBSTONE_USB_DEVICE_DEBUG(0x40210000);

#ifdef _DEVICE_DEBUG_
	DEBUG_LOG_TRACE("_usb_device_recv_data");
#endif

	usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR) handle;

#ifdef ENABLE_DCACHE
   /********************************************************
   If system has a data cache, it is assumed that buffer
   passed to this routine will be aligned on a cache line
   boundry. The following code will invalidate the
   buffer before passing it to hardware driver.
   ********************************************************/
	USB_dcache_invalidate_mlines((void *)buff_ptr, size);

#endif

	USB_device_lock();

	if (!usb_dev_ptr->XD_ENTRIES) {
		TOMBSTONE_USB_DEVICE_DEBUG(0x40210001);

		USB_device_unlock();
#ifdef _DEVICE_DEBUG_
		DEBUG_LOG_TRACE("_usb_device_recv_data, transfer in progress");
#endif
		TOMBSTONE_USB_DEVICE_DEBUG(0x40210002);
		return USB_STATUS_TRANSFER_IN_PROGRESS;
	}

	/* Endif */
	/* Get a transfer descriptor for the specified endpoint
	 ** and direction
	 */
	USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr);

	usb_dev_ptr->XD_ENTRIES--;

	/* Initialize the new transfer descriptor */
	xd_ptr->EP_NUM = ep_num;
	xd_ptr->BDIRECTION = USB_RECV;
	xd_ptr->WTOTALLENGTH = size;
	xd_ptr->WSOFAR = 0;
	xd_ptr->WSTARTADDRESS = buff_ptr;

	xd_ptr->BSTATUS = USB_STATUS_TRANSFER_ACCEPTED;

	TOMBSTONE_USB_DEVICE_DEBUG(0x40210003);
	error = _usb_dci_vusb20_recv_data(handle, xd_ptr);
	TOMBSTONE_USB_DEVICE_DEBUG(0x40210004);

	USB_device_unlock();

	if (error) {
		TOMBSTONE_USB_DEVICE_DEBUG(0x40210005);
#ifdef _DEVICE_DEBUG_
		DEBUG_LOG_TRACE("_usb_device_recv_data, receive failed");
#endif
		return USBERR_RX_FAILED;
	}
	/* Endif */
	TOMBSTONE_USB_DEVICE_DEBUG(0x40210099);
	return error;
}				/* EndBody */
Esempio n. 13
0
USB_STATUS usb_class_audio_stream_get_descriptors
(
    /* [IN] pointer to device instance */
    _usb_device_instance_handle      dev_handle,

    /* [IN] pointer to interface descriptor */
    _usb_interface_descriptor_handle intf_handle,

    /* [OUT] pointer to specific audio stream interface descriptor */
    USB_AUDIO_STREAM_DESC_SPEPIFIC_AS_IF_PTR _PTR_       as_itf_desc,

    /* [OUT] pointer to format type descriptor */
    USB_AUDIO_STREAM_DESC_FORMAT_TYPE_PTR _PTR_        	 frm_type_desc,

    /* [OUT] pointer to specific isochronous endpoint descriptor */
    USB_AUDIO_STREAM_DESC_SPECIFIC_ISO_ENDP_PTR _PTR_		iso_endp_spec_desc
)
{
    INTERFACE_DESCRIPTOR_PTR   intf_ptr =
        (INTERFACE_DESCRIPTOR_PTR)intf_handle;
    USB_STATUS                 status;
    _mqx_int i;
    USB_AUDIO_STREAM_FUNC_DESC_PTR      fd;

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

    status = USB_OK;
    /* collect all interface functional descriptors */
    for (i = 0; ; i++) {
        if (USB_OK != _usb_hostdev_get_descriptor(
                    dev_handle,
                    intf_handle,
                    USB_DESC_TYPE_CS_INTERFACE,  /* Functional descriptor for interface */
                    i,                           /* Index of descriptor */
                    intf_ptr->bAlternateSetting, /* Index of interface alternate */
                    (pointer _PTR_) &fd))
        {
            /* Here we can check capabilities from functional descriptors */
            /* But for now, nothing is checked */
            if (as_itf_desc == NULL)
                status = USBERR_INIT_FAILED;
            break;
        }
        /* Check if this union descriptor describes master for this interface */
        switch (fd->as_general.bDescriptorSubtype) {
        case USB_DESC_SUBTYPE_AS_CS_GENERAL:
            *as_itf_desc = &fd->as_general;
            break;
        case USB_DESC_SUBTYPE_AS_CS_FORMAT_TYPE:
            *frm_type_desc = &fd->frm_type;
            break;
        }
        if (status != USB_OK)
            break;
    }

    /* collect all interface functional descriptors */
    for (i = 0; ; i++) {
        if (USB_OK != _usb_hostdev_get_descriptor(
                    dev_handle,
                    intf_handle,
                    USB_DESC_TYPE_CS_ENDPOINT,  /* Functional descriptor for interface */
                    i,                           /* Index of descriptor */
                    intf_ptr->bAlternateSetting, /* Index of interface alternate */
                    (pointer _PTR_) &fd))
        {
            /* Here we can check capabilities from functional descriptors */
            /* But for now, nothing is checked */
            if (as_itf_desc == NULL)
                status = USBERR_INIT_FAILED;
            break;
        }
        /* Check if this union descriptor describes master for this interface */
        switch (fd->as_general.bDescriptorSubtype) {
        case USB_DESC_CLASS_ENDPOINT_GENERAL:
            *iso_endp_spec_desc = &fd->iso_endp_specific;
            break;
        default:
            break;
        }
        if (status != USB_OK)
            break;
    }

#ifdef _HOST_DEBUG_
    if (!status)
        DEBUG_LOG_TRACE("usb_class_audio_stream_get_descriptors, SUCCESSFULL");
    else
        DEBUG_LOG_TRACE("usb_class_audio_stream_get_descriptors, FAILED");
#endif

    return status;
}
Esempio n. 14
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_control_get_descriptors
* Returned Value : USB_OK
* Comments       :
*     This function is hunting for descriptors in the device configuration
*     and fills back fields if the descriptor was found.
*     Must be run in locked state and validated USB device or
*     directly from attach event.
*END*--------------------------------------------------------------------*/
USB_STATUS usb_class_audio_control_get_descriptors
(
    /* [IN] pointer to device instance */
    _usb_device_instance_handle      			dev_handle,

    /* [IN] pointer to interface descriptor */
    _usb_interface_descriptor_handle 			intf_handle,

    /* [OUT] pointer to header descriptor */
    USB_AUDIO_CTRL_DESC_HEADER_PTR _PTR_        header_desc,

    /* [OUT] pointer to input terminal descriptor */
    USB_AUDIO_CTRL_DESC_IT_PTR _PTR_        	it_desc,

    /* [OUT] pointer to output terminal descriptor */
    USB_AUDIO_CTRL_DESC_OT_PTR _PTR_        	ot_desc,

    /* [OUT] pointer to feature unit descriptor */
    USB_AUDIO_CTRL_DESC_FU_PTR _PTR_     		fu_desc
)
{
    INTERFACE_DESCRIPTOR_PTR   intf_ptr = (INTERFACE_DESCRIPTOR_PTR)intf_handle;
    USB_STATUS                 status;
    int_32 i;
    USB_AUDIO_CTRL_FUNC_DESC_PTR      fd;

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

    status = USB_OK;
    /* collect all interface functional descriptors */
    for (i = 0; ; i++) {
        if (USB_OK != _usb_hostdev_get_descriptor(
                    dev_handle,
                    intf_handle,
                    USB_DESC_TYPE_CS_INTERFACE,  /* Functional descriptor for interface */
                    i,                           /* Index of descriptor */
                    intf_ptr->bAlternateSetting, /* Index of interface alternate */
                    (pointer _PTR_) &fd))
        {
            /* Here we can check capabilities from functional descriptors */
            /* But for now, nothing is checked */
            if (fu_desc == NULL)
                status = USBERR_INIT_FAILED;
            break;
        }
        /* Check if this union descriptor describes master for this interface */
        switch (fd->header.bDescriptorSubtype) {
        case USB_DESC_SUBTYPE_AUDIO_CS_HEADER:
            *header_desc = &fd->header;
            if (SHORT_LE_TO_HOST(*(uint_16*)((*header_desc)->bcdCDC)) > 0x0110)
                status = USBERR_INIT_FAILED;
            break;
        case USB_DESC_SUBTYPE_AUDIO_CS_IT:
            *it_desc = &fd->it;
            break;
        case USB_DESC_SUBTYPE_AUDIO_CS_OT:
            *ot_desc = &fd->ot;
            break;
        case USB_DESC_SUBTYPE_AUDIO_CS_FU:
            *fu_desc = &fd->fu;
            break;
        }
        if (status != USB_OK)
            break;
    }

#ifdef _HOST_DEBUG_
    if (!status)
        DEBUG_LOG_TRACE("usb_class_audio_control_get_descriptors, SUCCESSFULL");
    else
        DEBUG_LOG_TRACE("usb_class_audio_control_get_descriptors, FAILED");
#endif

    return status;
}
Esempio n. 15
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : _usb_hostdev_cntrl_request
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process class- or vendor-specific control pipe device
*     requests.
*
*END*--------------------------------------------------------------------*/
usb_status  _usb_hostdev_cntrl_request
(
    /* usb device */
    usb_device_instance_handle    dev_handle,
    /* Device Request to send */
    usb_setup_t*                  devreq,
    /* buffer to send/receive */
    uint8_t *                     buff_ptr,
    /* callback upon completion */
    tr_callback                   callback,
    /* [IN] the parameter to pass back to the callback function */
    void*                         callback_param
)
{ /* Body */
    dev_instance_t*           dev_ptr;
    usb_pipe_handle           pipe_handle;
    tr_struct_t                  tr;
    usb_status                 error = USB_OK;

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

    /* Verify that device handle is valid */
    OS_Lock();
    error = usb_hostdev_validate(dev_handle);

    if (error != USB_OK) 
    {
        OS_Unlock();
        #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, invalid device handle");
        #endif
        return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
    } /* Endif */

    dev_ptr = (dev_instance_t*)dev_handle;

    if (dev_ptr->state < DEVSTATE_ENUM_OK) 
    {
        OS_Unlock();
        #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request, no device found");
        #endif
        return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
   } /* Endif */

    pipe_handle = dev_ptr->control_pipe;
    usb_hostdev_tr_init(&tr, callback, callback_param);

    /* Set TR buffer length as required */
    if ((REQ_TYPE_IN & devreq->bmrequesttype) != 0) 
    {
        tr.rx_buffer = buff_ptr;
        tr.rx_length = USB_SHORT_UNALIGNED_LE_TO_HOST(devreq->wlength);
    } 
    else 
    {
        tr.TX_BUFFER = buff_ptr;
        tr.tx_length = USB_SHORT_UNALIGNED_LE_TO_HOST(devreq->wlength);
    } /* EndIf */

    tr.setup_packet = *devreq;
    error = _usb_host_send_setup(dev_ptr->host, pipe_handle, &tr);

    OS_Unlock();

    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("_usb_hostdev_cntrl_request,SUCCESSFUL");
    #endif

    return USB_log_error(__FILE__,__LINE__,error);
}
Esempio n. 16
0
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_device_set_status
* Returned Value : USB_OK or error code
* Comments       :
*     Provides API to set internal state
* 
*END*--------------------------------------------------------------------*/
uint_8 _usb_device_set_status
   (
      /* [IN] Handle to the usb device */
      _usb_device_handle   handle,
      
      /* [IN] What to set the status of */
      uint_8               component,
      
      /* [IN] What to set the status to */
      uint_16              setting
   )
{ /* Body */
   USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;

   #ifdef _DEVICE_DEBUG_
      DEBUG_LOG_TRACE("_usb_device_set_status");
   #endif
   
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
   USB_lock();
   switch (component) {

      case USB_STATUS_DEVICE_STATE:
         usb_dev_ptr->USB_STATE = setting;
         break;

      case USB_STATUS_DEVICE:
         usb_dev_ptr->USB_DEVICE_STATE = setting;
         break;

      case USB_STATUS_INTERFACE:
         break;

      case USB_STATUS_CURRENT_CONFIG:
         usb_dev_ptr->USB_CURR_CONFIG = setting;
         break;

      case USB_STATUS_SOF_COUNT:
         usb_dev_ptr->USB_SOF_COUNT = setting;
         break;
         
      case USB_FORCE_FULL_SPEED:
         _usb_dci_vusb20_set_speed_full((pointer)usb_dev_ptr, setting);
         break;
      case USB_PHY_LOW_POWER_SUSPEND:
         _usb_dci_vusb20_suspend_phy((pointer)usb_dev_ptr, setting);
         break;

      case USB_STATUS_ADDRESS:
         usb_dev_ptr->DEVICE_ADDRESS = setting;
         _usb_dci_vusb20_set_address((pointer)usb_dev_ptr, setting);
         break;
#if 0      
      case USB_STATUS_TEST_MODE:
         _usb_dci_vusb20_set_test_mode(handle, 
            setting);
         break;
#endif         
      default:
         if (component & USB_STATUS_ENDPOINT) {
            _usb_dci_vusb20_set_endpoint_status(handle,
               component & USB_STATUS_ENDPOINT_NUMBER_MASK,
               setting);
         } else {
            USB_unlock();
            #ifdef _DEVICE_DEBUG_
               DEBUG_LOG_TRACE("_usb_device_set_status, bad status");
            #endif
            return USBERR_BAD_STATUS;
         } /* Endif */
         break;

   } /* Endswitch */

   USB_unlock();

   #ifdef _DEVICE_DEBUG_
      DEBUG_LOG_TRACE("_usb_device_set_status, SUCCESSFUL");
   #endif
   
   return USB_OK;   
} /* EndBody */
Esempio n. 17
0
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_host_ch9_dev_req
* Returned Value : USB_OK, or error status
* Comments       :
*     Function to process standard device requests in Chapter 9.
*        See Table 9-3 p. 250 of USB 2.0 specification.
*     This code does minimal error checking, on the assumption
*        that it is called only from wrappers in this file.
*     It is presumed that this function is called with USB interrupts disabled
* 
*END*--------------------------------------------------------------------*/
static usb_status  usb_host_ch9_dev_req
(
    /* usb device */
    usb_device_instance_handle   dev_handle,
    /* Device Request to send */
    usb_setup_t*                 devreq_ptr,
    /* buffer to send/receive */
    uint8_t *                    buff_ptr
)
{
    dev_instance_t*           dev_ptr;
    usb_pipe_handle           pipe_handle;
    tr_struct_t*              tr_ptr;
    usb_status                 error;

    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_host_ch9_dev_req");
    #endif
    
    /* Verify that device handle is valid */
    error = usb_hostdev_validate(dev_handle);
    if (error != USB_OK) 
    {
        #ifdef _HOST_DEBUG_
          DEBUG_LOG_TRACE("usb_host_ch9_dev_req device not found");
        #endif
        return USB_log_error(__FILE__,__LINE__,USBERR_DEVICE_NOT_FOUND);
    } /* Endif */

    dev_ptr = (dev_instance_t*)dev_handle;
    pipe_handle = dev_ptr->control_pipe;

    if (usb_host_get_tr(dev_ptr->host, dev_ptr->control_callback, dev_ptr->control_callback_param, &tr_ptr) != USB_OK)
    {
        printf("error to get tr ch9\n");
        return USBERR_ERROR;
    }

    /* Set buffer length if required */
    switch (devreq_ptr->brequest)
    {
        case REQ_SET_DESCRIPTOR:
            tr_ptr->tx_buffer = buff_ptr;
            tr_ptr->tx_length = USB_SHORT_UNALIGNED_LE_TO_HOST(devreq_ptr->wlength);
            break;
        case REQ_GET_CONFIGURATION:
        case REQ_GET_DESCRIPTOR:
        case REQ_GET_INTERFACE:
        case REQ_GET_STATUS:
        case REQ_SYNCH_FRAME:
            tr_ptr->rx_buffer = buff_ptr;
            tr_ptr->rx_length = USB_SHORT_UNALIGNED_LE_TO_HOST(devreq_ptr->wlength);
            break;
    } /* EndSwitch */

    tr_ptr->setup_packet = *devreq_ptr;

    if ((dev_ptr->state < DEVSTATE_ENUM_OK) ||
        (tr_ptr->callback == NULL))
    {
        tr_ptr->callback = usb_host_cntrl_transaction_done;
        tr_ptr->callback_param = dev_ptr;
    } /* Endif */

    #ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_host_ch9_dev_req SUCCESSFUL");
    #endif
    error = usb_host_send_setup(dev_ptr->host, pipe_handle, tr_ptr);

    return USB_log_error(__FILE__,__LINE__,error);
} /* EndBody */
Esempio n. 18
0
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_init
*  Returned Value : USB_OK or error code
*  Comments       :
*        Initializes the USB device specific data structures and calls 
*  the low-level device controller chip initialization routine.
*
*END*-----------------------------------------------------------------*/
uint_8 _usb_device_init
   (
      /* [IN] the USB device controller to initialize */
      uint_8                    devnum,

      /* [OUT] the USB_USB_dev_initialize state structure */
      _usb_device_handle _PTR_  handle,
            
      /* [IN] number of endpoints to initialize */
      uint_8                    endpoints 
   )
{ /* Body */

   USB_DEV_STATE_STRUCT_PTR         usb_dev_ptr;
   XD_STRUCT_PTR                    xd_ptr;
   uint_8                           temp, i, error;
   SCRATCH_STRUCT_PTR               temp_scratch_ptr;
   //uint_32                          total_memory;
   //uint_8_ptr                       stack_mem_ptr;
   
   #ifdef _DEVICE_DEBUG_
      DEBUG_LOG_TRACE("_usb_device_init");
   #endif
   
   #ifndef REDUCED_ERROR_CHECKING                   
      
      if (devnum > MAX_USB_DEVICES) 
      {
         #ifdef _DEVICE_DEBUG_
            DEBUG_LOG_TRACE("_usb_device_init, error invalid device number");
         #endif
         return USBERR_INVALID_DEVICE_NUM;
      } /* Endif */
   #endif
      
   /**************************************************************
   All memory allocations should be consolidated in one.
   **************************************************************/
                                       
         /* Allocate memory for the state structure */
         //usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)
         //   USB_memalloc(sizeof(USB_DEV_STATE_STRUCT));
         usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)
            malloc(sizeof(USB_DEV_STATE_STRUCT));
      
         if (usb_dev_ptr == NULL) 
         {
            #ifdef _DEVICE_DEBUG_
               DEBUG_LOG_TRACE("_usb_device_init, error NULL device handle");
            #endif
            return USBERR_ALLOC_STATE;
         } /* Endif */
   
         /* Zero out the internal USB state structure */
         USB_memzero((char *)usb_dev_ptr,sizeof(USB_DEV_STATE_STRUCT));
  
   /**************************************************************
   **************************************************************/
        
   /* Multiple devices will have different base addresses and 
   ** interrupt vectors (For future)
   */   
   //usb_dev_ptr->DEV_PTR = 0x1cb20100;
   usb_dev_ptr->DEV_PTR = (VUSB20_REG_STRUCT_PTR)otg_base + 0x100;
   usb_dev_ptr->DEV_VEC = otg_irq;
   usb_dev_ptr->USB_STATE = USB_STATE_UNKNOWN;
   
   usb_dev_ptr->MAX_ENDPOINTS = endpoints;

   #ifndef SMALL_CODE_SIZE                   
      temp = (usb_dev_ptr->MAX_ENDPOINTS * 2);
   #endif
                
      /* Allocate MAX_XDS_FOR_TR_CALLS */
      xd_ptr = (XD_STRUCT_PTR)
         malloc(sizeof(XD_STRUCT) * MAX_XDS_FOR_TR_CALLS);
         //USB_memalloc(sizeof(XD_STRUCT) * MAX_XDS_FOR_TR_CALLS);
      if (xd_ptr == NULL) 
      {
         #ifdef _DEVICE_DEBUG_
            DEBUG_LOG_TRACE("_usb_device_init, malloc error");
         #endif
         return USBERR_ALLOC_TR;
      }

      USB_memzero((char *)xd_ptr, sizeof(XD_STRUCT) * MAX_XDS_FOR_TR_CALLS);

      /* Allocate memory for internal scratch structure */   
      usb_dev_ptr->XD_SCRATCH_STRUCT_BASE = (SCRATCH_STRUCT_PTR)
         malloc(sizeof(SCRATCH_STRUCT)*MAX_XDS_FOR_TR_CALLS);
         //USB_memalloc(sizeof(SCRATCH_STRUCT)*MAX_XDS_FOR_TR_CALLS);
   
      if (usb_dev_ptr->XD_SCRATCH_STRUCT_BASE == NULL) 
      {
         #ifdef _DEVICE_DEBUG_
            DEBUG_LOG_TRACE("_usb_device_init, malloc error");
         #endif
         return USBERR_ALLOC;
      } /* Endif */
   
   usb_dev_ptr->XD_BASE = xd_ptr;
   

   temp_scratch_ptr = usb_dev_ptr->XD_SCRATCH_STRUCT_BASE;
   
   #ifndef SMALL_CODE_SIZE
      usb_dev_ptr->XD_HEAD = NULL;
      usb_dev_ptr->XD_TAIL = NULL;
      usb_dev_ptr->XD_ENTRIES = 0;
   #endif
   
   /* Enqueue all the XDs */   
   for (i=0;i<MAX_XDS_FOR_TR_CALLS;i++) {
      xd_ptr->SCRATCH_PTR = temp_scratch_ptr;
      xd_ptr->SCRATCH_PTR->FREE = _usb_device_free_XD;
      xd_ptr->SCRATCH_PTR->PRIVATE = (pointer)usb_dev_ptr;
      _usb_device_free_XD((pointer)xd_ptr);
      xd_ptr++;
      temp_scratch_ptr++;
   } /* Endfor */

      usb_dev_ptr->TEMP_XD_PTR = (XD_STRUCT_PTR)malloc(sizeof(XD_STRUCT));
      USB_memzero((char *)usb_dev_ptr->TEMP_XD_PTR, sizeof(XD_STRUCT));
      
   /* Initialize the USB controller chip */

   error = _usb_dci_vusb20_init(devnum, usb_dev_ptr);

   if (error) 
   {
      #ifdef _DEVICE_DEBUG_
         DEBUG_LOG_TRACE("_usb_device_init, init failed");
      #endif
      return USBERR_INIT_FAILED;
   } /* Endif */
   
   *handle = usb_dev_ptr;
   #ifdef _DEVICE_DEBUG_
      DEBUG_LOG_TRACE("_usb_device_init, SUCCESSFUL");
   #endif
   return USB_OK;
   
} /* EndBody */
Esempio n. 19
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_dev_list_get_mem
* Returned Value : USB_OK if memory allocated, else error code
* Comments       :
*     Memory is added at the end of a linked list, whose
*        anchor is device.memlist
*
*END*--------------------------------------------------------------------*/
USB_STATUS usb_dev_list_get_mem
(
    /* [IN] Pointer to the USB device */
    DEV_INSTANCE_PTR        dev_ptr,

    /* [IN] Size of memory payload required */
    uint_32                 mem_size,

    /* [IN] Type of memory payload required */
    memory_type             mem_type,

    /* [IN] Alignment required */
    uint_32                 align,

    /* [OUT] Pointer to memory block's header */
    DEV_MEMORY_PTR _PTR_    header_ptr
)
{   /* Body */

    DEV_MEMORY_PTR  mem_ptr, list_ptr;
    USB_STATUS      error;

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

    if (align > 256)
    {
#ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_dev_list_get_mem invalid alignment");
#endif
        return USB_log_error(__FILE__,__LINE__,USBERR_BAD_ALIGNMENT);
    }

    if ((mem_type <= USB_MEMTYPE_MIN_VALUE) || (mem_type >= USB_MEMTYPE_MAX_VALUE))
    {
#ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_dev_list_get_mem invalid memory type");
#endif
        return USB_log_error(__FILE__,__LINE__,USBERR_INVALID_MEM_TYPE);
    }

    USB_lock();
    error = usb_hostdev_validate((_usb_device_instance_handle)dev_ptr);

    if (error != USB_OK) {
        USB_unlock();
#ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_dev_list_get_mem invalid device handle");
#endif
        return USB_log_error(__FILE__,__LINE__,error);
    }

    /* get memory for header + payload, rounded up to align bytes */
    mem_ptr = (DEV_MEMORY_PTR) USB_mem_alloc_uncached_zero(MEM_HEADER_LEN + mem_size +  align - 1);

    if (mem_ptr == NULL) {
        USB_unlock();
#ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_dev_list_get_mem malloc FAILED");
#endif

        return USB_log_error(__FILE__,__LINE__,USBERR_GET_MEMORY_FAILED);
    }
    _mem_set_type(mem_ptr, MEM_TYPE_USB_LIST_MEM_BUFF);

    if (dev_ptr->memlist == NULL) {
        dev_ptr->memlist = mem_ptr;
    } else {
        list_ptr = dev_ptr->memlist;

        while (list_ptr->next != NULL)
            list_ptr = list_ptr->next;

        list_ptr->next = mem_ptr;
    } /* EndIf */

    mem_ptr->next = NULL;
    mem_ptr->blktype = mem_type;
    mem_ptr->blksize = mem_size;
    mem_ptr->offset = (~(uint_32) mem_ptr->payload.data + 1) & (align - 1);
    if (mem_ptr->offset) {
        /* Real payload is by offset bytes shifted from original payload. We want to write offset in the byte just before
        ** real payload. */
        mem_ptr->payload.data[mem_ptr->offset - 1] = mem_ptr->offset; /* write offset value also 1 byte before payload */
    }
    *header_ptr = (pointer)mem_ptr;

    USB_unlock();

#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_dev_list_get_mem SUCCESSFUL");
#endif
    return USB_OK;
} /* Endbody */
Esempio n. 20
0
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_host_recv_data
*  Returned Value : error or status of the transfer
*  Comments       :
* The Receive Data routine is non-blocking routine that causes a buffer 
* to be made available for data recieved from the 
* USB host. It takes the buffer and passes it down to lower
level hardware driver. 
*END*-----------------------------------------------------------------*/
USB_STATUS _usb_host_recv_data
   (
      /* [IN] the USB Host state structure */
      _usb_host_handle           handle, 

      /* [IN] the pipe handle */
      _usb_pipe_handle           pipe_handle,

      /* [IN] transfer parameters */
      TR_INIT_PARAM_STRUCT_PTR   tr_params_ptr
   )
{ /* Body */
   PIPE_DESCRIPTOR_STRUCT_PTR pipe_descr_ptr;
   USB_HOST_STATE_STRUCT_PTR usb_host_ptr;
   USB_STATUS status;



/*****************************************************************
CODE FOR ARC FULL SPEED CORE
*****************************************************************/

   PIPE_TR_STRUCT_PTR   pipe_tr_ptr;
   USB_STATUS  return_code;   

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

   USB_lock();

   return_code = _usb_host_set_up_TR(pipe_handle, tr_params_ptr, &pipe_tr_ptr);

   if (return_code != USB_STATUS_TRANSFER_QUEUED) {
      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("_usb_host_recv_data transfer queue failed");
      #endif
      return USB_log_error(__FILE__,__LINE__,return_code);
   } /* Endif */
   
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;
   pipe_descr_ptr = (PIPE_DESCRIPTOR_STRUCT_PTR)pipe_handle;

   /*Must Flush and Invalidate the buffer before sending
   /receiving the data in it */
   USB_dcache_invalidate_mlines((void *)pipe_tr_ptr->RX_BUFFER, pipe_tr_ptr->RX_LENGTH);  

   /* We have obtained the current TR on the Pipe's TR list 
   ** from _usb_host_set_up_TR
   */

   /* Call the low-level routine to receive data */
   status = _usb_host_recv_data_call_interface (handle, pipe_descr_ptr, pipe_tr_ptr);
         
   USB_unlock();
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("_usb_host_recv_data SUCCESSFUL");
   #endif

   if(status == USB_OK) 
   {
      return USB_STATUS_TRANSFER_QUEUED;
   }
   else
   {
      return USB_log_error(__FILE__,__LINE__,status);
   }

   
} /* Endbody */
Esempio n. 21
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_dev_list_close_pipe
* Returned Value :
* Comments       :
*     Cancel pending TR's and close a pipe.
*
*END*--------------------------------------------------------------------*/
static void  usb_dev_list_close_pipe
(
    _usb_host_handle              handle,
    PIPE_STRUCT_PTR               pipe_ptr
)
{   /* Body */
    USB_STATUS                       status;
    USB_HOST_STATE_STRUCT_PTR        usb_host_ptr;
    TR_STRUCT_PTR                    tr_ptr;

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

    if (pipe_ptr == NULL)
    {
#ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_dev_list_close_pipe NULL pipe");
#endif
        return;
    }

    usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;

    USB_lock();

    /* Cancel all active TR's in the pipe */
    tr_ptr = pipe_ptr->tr_list_ptr;
    if (tr_ptr != NULL) {
        do {
            //tr_ptr->CALLBACK = NULL;
            if (tr_ptr->TR_INDEX != 0) {
                tr_ptr->FLAG &= ~TR_CANCEL_ASYNC;
                /* Cancel the transfer at low-level */
                status = _usb_host_cancel_call_interface(handle, pipe_ptr, tr_ptr);

                if (status != USB_OK)
                {
#ifdef _HOST_DEBUG_
                    DEBUG_LOG_TRACE("usb_dev_list_close_pipe failed to cancel transaction");
#endif
                }
            }

            tr_ptr->STATUS = USB_STATUS_IDLE;
            /* Indicate that the TR is idle */
            tr_ptr->TR_INDEX = 0;
            tr_ptr = tr_ptr->NEXT;
        } while (tr_ptr != pipe_ptr->tr_list_ptr); //this indicates end of queue
    } /* EndWhile */

    /* zero the pipe descriptor, except keep TR list */
    tr_ptr = pipe_ptr->tr_list_ptr;
    _usb_host_close_pipe(handle, (pointer)pipe_ptr);
    pipe_ptr->tr_list_ptr = tr_ptr;

    USB_unlock();
#ifdef _HOST_DEBUG_
    DEBUG_LOG_TRACE("usb_dev_list_close_pipe SUCCESSFUL");
#endif

} /* EndBody */
Esempio n. 22
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_audio_cntrl_common
* Returned Value : USB_OK if command has been passed on USB.
* Comments       :
*     This function is used to send a control request.
*     It must be run with USB locked.
*
*END*--------------------------------------------------------------------*/
static USB_STATUS usb_class_audio_cntrl_common
(
    /* [IN] The communication device common command structure */
    AUDIO_COMMAND_PTR           com_ptr,

    /* [IN] The audio control interface */
    //AUDIO_CONTROL_INTERFACE_STRUCT_PTR if_ctrl_ptr,

    /* [IN] Bitmask of the request type */
    uint8_t                    bmrequesttype,

    /* [IN] Request code */
    uint8_t                    brequest,

    /* [IN] Value to copy into WVALUE field of the REQUEST */
    uint16_t                   wvalue,

    /* [IN] Value to copy into WINDEX field of the REQUEST */
    uint16_t                   wIndex,

    /* [IN] Length of the data associated with REQUEST */
    uint16_t                   wlength,

    /* [IN] Pointer to data buffer used to send/recv */
    unsigned char                 *data
)
{ /* Body */
    USB_AUDIO_GENERAL_CLASS_PTR      if_ptr;
    USB_SETUP                        req;
    USB_STATUS                       status = USBERR_NO_INTERFACE;

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

    if_ptr = (USB_AUDIO_GENERAL_CLASS_PTR) com_ptr->CLASS_PTR->class_intf_handle;

    /* Save the higher level callback and ID */
    if_ptr->USER_CALLBACK = com_ptr->CALLBACK_FN;
    if_ptr->USER_PARAM = com_ptr->CALLBACK_PARAM;

    /* Setup the request */
    req.BMREQUESTTYPE = bmrequesttype;
    req.BREQUEST = brequest;

    *(uint16_t*)req.WINDEX = HOST_TO_LE_SHORT(wIndex);
    *(uint16_t*)req.WVALUE = HOST_TO_LE_SHORT(wvalue);
    *(uint16_t*)req.WLENGTH = HOST_TO_LE_SHORT(wlength);


    if (USB_STATUS_TRANSFER_QUEUED == (status = _usb_hostdev_cntrl_request(if_ptr->G.dev_handle, &req, data,
                                       usb_class_audio_cntrl_callback, if_ptr)))
        status = USB_OK;

#ifdef _HOST_DEBUG_
    if (!status)
        DEBUG_LOG_TRACE("usb_class_audio_cntrl_common, SUCCESSFUL");
    else
        DEBUG_LOG_TRACE("usb_class_audio_cntrl_common, FAILED");
#endif

    return status;
} /* Endbody */
Esempio n. 23
0
void usb_class_mass_call_back_cbw
   (
      /* [IN] Pipe on which CBW call was made */
      _usb_pipe_handle pipe_handle,

      /* [IN] Pointer to the class instance */
      pointer2          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;
   COMMAND_OBJECT_PTR               cmd_ptr = NULL;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_call_back_cbw");
   #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 there is no user_parm or cmd_ptr we return */
   if (!cmd_ptr) 
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_call_back_cbw, bad parameter");
      #endif
      return;
   } /* Endif */

   /* Check status of CBW phase and go to the next phase (Data or Status) */
   if (status == USB_OK || status == USB_STATUS_TRANSFER_QUEUED) {
      /* Verify if the length of the data transferred was correct */
      if (length_data_transfered != CBW_SIZE) {
         if (cmd_ptr->RETRY_COUNT < MAX_RETRIAL_ATTEMPTS) {
            cmd_ptr->RETRY_COUNT++;
            cmd_ptr->STATUS = STATUS_QUEUED_IN_DRIVER;
            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 */
      } else {
         /* Everything is normal, go to next phase of pending request */
         cmd_ptr->STATUS = STATUS_FINISHED_CBW_ON_USB;
         status = usb_class_mass_pass_on_usb(plocal_intf);
      } /* Endif */
   } /* Endif */

   if ((status != USB_OK) && (status != USBERR_TRANSFER_IN_PROGRESS) && (status != USB_STATUS_TRANSFER_QUEUED)) {
      /*
      ** Host must do a reset recovery for the device as per the spec. We also
      ** notify the application of the failure, remove the command from the
      ** queue and move on the the next command queued
      */
      cmd_ptr->STATUS = STATUS_CANCELLED;
      cmd_ptr->CALLBACK((USB_STATUS)USB_MASS_FAILED_IN_COMMAND, plocal_intf, cmd_ptr,
         cmd_ptr->TR_BUF_LEN);
      usb_class_mass_deleteq(plocal_intf);
      status = usb_class_mass_pass_on_usb(plocal_intf);
   } /* Endif */
   
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_call_back_cbw, SUCCESSFUL");
   #endif
   
} /* Endbody */
Esempio n. 24
0
usb_status usb_class_hub_cntrl_common
   (
      /* [IN] Class Interface structure pointer */
      hub_command_t*         com_ptr,
      /* [IN] Bitmask of the request type */
      uint8_t                  bmrequesttype,
      /* [IN] Request code */
      uint8_t                  brequest,
      /* [IN] Value to copy into wvalue field of the REQUEST */
      uint16_t                 wvalue,
      /* [IN] Length of the data associated with REQUEST */
      uint16_t                 windex,
      /* [IN] Index field of CTRL packet */
      uint16_t                 wlength,
      /* [IN] the buffer to be transfered */
      uint8_t *               data
   )
{
    usb_hub_class_struct_t*         hub_class = NULL;
    //usb_setup_t                        req;
    usb_status                       status = USB_OK;
    tr_struct_t*                    tr_ptr;

    if ((com_ptr == NULL) || (com_ptr->class_ptr == NULL))
    {
        return USBERR_ERROR;
    }

    hub_class = (usb_hub_class_struct_t*)com_ptr->class_ptr;
    if (hub_class->in_setup)
    {
        return USBERR_TRANSFER_IN_PROGRESS;
    }

    if (hub_class->dev_handle == NULL)
    {
        #ifdef _HOST_DEBUG_
           DEBUG_LOG_TRACE("usb_class_hub_cntrl_common, invalid device handle");
        #endif
        return USBERR_DEVICE_NOT_FOUND;
    }
    
    hub_class->ctrl_callback = com_ptr->callback_fn;
    hub_class->ctrl_param = com_ptr->callback_param;

    if (usb_host_get_tr(hub_class->host_handle, usb_class_hub_cntrl_callback, hub_class, &tr_ptr) != USB_OK)
    {
        USB_PRINTF("error to get tr hub\n");
        return USBERR_ERROR;
    }

    /* Set TR buffer length as required */
    if ((REQ_TYPE_IN & bmrequesttype) != 0)
    {
        tr_ptr->rx_buffer = data;
        tr_ptr->rx_length = wlength;
    }
    else
    {
        tr_ptr->tx_buffer = data;
        tr_ptr->tx_length = wlength;
    }
 
    tr_ptr->setup_packet.bmrequesttype = bmrequesttype;
    tr_ptr->setup_packet.brequest      = brequest;
    *(uint16_t*)tr_ptr->setup_packet.wvalue = USB_HOST_TO_LE_SHORT(wvalue);
    *(uint16_t*)tr_ptr->setup_packet.windex = USB_HOST_TO_LE_SHORT(windex);
    *(uint16_t*)tr_ptr->setup_packet.wlength = USB_HOST_TO_LE_SHORT(wlength);
 
    status = usb_host_send_setup(hub_class->host_handle, hub_class->control_pipe, tr_ptr);  
    if (status != USB_OK)
    {
        usb_host_release_tr(hub_class->host_handle, tr_ptr);
        return USBERR_ERROR;
    }
    hub_class->in_setup = TRUE;
    return USB_OK;
} /* Endbody */
Esempio n. 25
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 */
      pointer2          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 = utoh32(pCsw->DCSWTAG);
      tmp2 = utoh32(cmd_ptr->CBW_PTR->DCBWTAG);
      tmp3 = utoh32(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 */
Esempio n. 26
0
usb_status usb_class_hub_init
   (
      /* [IN]  the device handle related to the class driver */
        usb_device_instance_handle      dev_handle,
        /* [IN]  the interface handle related to the class driver */
        usb_interface_descriptor_handle intf_handle,
        /* [OUT] printer call struct pointer */
        class_handle*                    class_handle_ptr
   )
{ /* Body */
    usb_hub_class_struct_t*       hub_class = NULL;
    usb_device_interface_struct_t*   pDeviceIntf = NULL;
    //interface_descriptor_t*       intf = NULL;
    endpoint_descriptor_t*        ep_desc = NULL;
    uint8_t                         ep_num;
    usb_status                     status = USB_OK;
    pipe_init_struct_t               pipe_init;
    uint8_t                        level = 0xFF;
 
    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_class_hub_init");
    #endif

    level = usb_host_dev_mng_get_level(dev_handle);

    if (level > 5)
    {
        USB_PRINTF("Too many level of hub attached\n");
        *class_handle_ptr = NULL;
        return USBERR_ERROR;
    }
    
    hub_class = (usb_hub_class_struct_t*)OS_Mem_alloc_zero(sizeof(usb_hub_class_struct_t));
    if (hub_class == NULL)
    {
        USB_PRINTF("usb_class_hub_init fail on memory allocation\n");
        *class_handle_ptr = NULL;
        return USBERR_ERROR;
    }

    hub_class->dev_handle  = dev_handle;
    hub_class->intf_handle = intf_handle;
    hub_class->host_handle = usb_host_dev_mng_get_host(hub_class->dev_handle);
    hub_class->level = usb_host_dev_mng_get_level(hub_class->dev_handle);

    pDeviceIntf = (usb_device_interface_struct_t*)intf_handle;
    //intf = pDeviceIntf->lpinterfaceDesc;

    for (ep_num = 0; ep_num < pDeviceIntf->ep_count; ep_num++)
    {
        ep_desc = pDeviceIntf->ep[ep_num].lpEndpointDesc;
        if ((ep_desc->bEndpointAddress & IN_ENDPOINT) && ((ep_desc->bmAttributes & EP_TYPE_MASK) == IRRPT_ENDPOINT))
        {
            pipe_init.endpoint_number  = (ep_desc->bEndpointAddress & ENDPOINT_MASK);
            pipe_init.direction        = USB_RECV;
            pipe_init.pipetype         = USB_INTERRUPT_PIPE;
            pipe_init.max_packet_size  = (uint16_t)(USB_SHORT_UNALIGNED_LE_TO_HOST(ep_desc->wMaxPacketSize) & PACKET_SIZE_MASK);
            pipe_init.interval         = ep_desc->iInterval;
            pipe_init.flags            = 0;
            pipe_init.dev_instance     = hub_class->dev_handle;
            pipe_init.nak_count        = USBCFG_HOST_DEFAULT_MAX_NAK_COUNT;
            status = usb_host_open_pipe(hub_class->host_handle, &hub_class->interrupt_pipe, &pipe_init);
            if (status != USB_OK)
            {
                USB_PRINTF("usb_class_hid_init fail to open in pipe\n");
                *class_handle_ptr = (class_handle)hub_class;
                return USBERR_ERROR;
            }
        }
    }
    hub_class->control_pipe = usb_host_dev_mng_get_control_pipe(hub_class->dev_handle);
    *class_handle_ptr = hub_class;
    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_class_hub_init, SUCCESSFUL");
    #endif
    return USB_OK;
} /* Endbody */
Esempio n. 27
0
static void usb_class_mass_reset_callback
   (
      /* [IN] pointer to pipe */
      _usb_pipe_handle  pipe_handle,

      /* [IN] user-defined parameter */
      pointer2           user_parm,

      /* [IN] buffer address */
      uchar_ptr         buffer,

      /* [IN] length of data transferred */
      uint_32           length_data_transfered,

      /* [IN] status, hopefully USB_OK or USB_DONE */
      uint_32           status
   )
{ /* Body */

   USB_MASS_CLASS_INTF_STRUCT_PTR   plocal_intf;
   PIPE_INIT_PARAM_STRUCT_PTR       pPipe;
   COMMAND_OBJECT_PTR               cmd_ptr = NULL;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_reset_callback");
   #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_reset_callback, bad param");
      #endif
      return;
   } /* Endif */

   /* Check the status of the reset and act accordingly */
   if (status == USB_OK || status == USB_STATUS_TRANSFER_QUEUED) {
      switch (cmd_ptr->STATUS) {
         case STATUS_RESET_DEVICE:
            /* Reset the Bulk IN pipe */
            pPipe = (PIPE_INIT_PARAM_STRUCT_PTR)plocal_intf->BULK_IN_PIPE;
            if (!_usb_host_register_ch9_callback(plocal_intf->G.dev_handle,
               usb_class_mass_reset_callback, plocal_intf))
            {
               status = _usb_host_ch9_clear_feature(plocal_intf->G.dev_handle,
                  REQ_TYPE_ENDPOINT, (uint_8)(pPipe->ENDPOINT_NUMBER | REQ_TYPE_IN), ENDPOINT_HALT);
               cmd_ptr->STATUS = STATUS_RESET_BULK_IN;
            } /* Endif */
            break;

         case STATUS_RESET_BULK_IN:
            /* Reset the Bulk OUT pipe*/
            pPipe = (PIPE_INIT_PARAM_STRUCT_PTR)plocal_intf->BULK_OUT_PIPE;
            if (!_usb_host_register_ch9_callback(plocal_intf->G.dev_handle,
               usb_class_mass_reset_callback, plocal_intf))
            {
               status = _usb_host_ch9_clear_feature(plocal_intf->G.dev_handle,
                  REQ_TYPE_ENDPOINT, (uint_8)(pPipe->ENDPOINT_NUMBER | REQ_TYPE_OUT), ENDPOINT_HALT);
               cmd_ptr->STATUS   =   STATUS_RESET_BULK_OUT;
            } /* Endif */
            break;

         case STATUS_RESET_BULK_OUT:
         case  STATUS_CLEAR_BULK_PIPE:
            cmd_ptr->STATUS = cmd_ptr->PREV_STATUS; /* restore status */
            status = usb_class_mass_pass_on_usb(plocal_intf);
            break;

         default:
            status = usb_class_mass_reset_recovery_on_usb(plocal_intf);
            break;
      } /* Endswitch */

   } else if (status == USBERR_ENDPOINT_STALLED) {

      cmd_ptr->STATUS = STATUS_CANCELLED;
      cmd_ptr->CALLBACK(status, plocal_intf, cmd_ptr, cmd_ptr->TR_BUF_LEN);
      usb_class_mass_deleteq(plocal_intf);

      /* go to the next packet if any */
      usb_class_mass_pass_on_usb(plocal_intf);
   } /* Endif */

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_reset_callback, SUCCESSFUL");
   #endif
   
} /* Endbody */
Esempio n. 28
0
/*FUNCTION*----------------------------------------------------------------
*
* Function Name  : usb_class_hub_recv_bitmap
* Returned Value : None
* Comments       :
*     Starts interrupt endpoint to poll for interrupt on specified hub
*END*--------------------------------------------------------------------*/
usb_status usb_class_hub_recv_bitmap
    (
      /* [IN] Class Interface structure pointer */
      hub_command_t*            com_ptr,
       /* [IN] The buffer address */
      uint8_t *                  buffer,
      /* size of buffer to be used */
      uint8_t                      length
    )
{
    usb_hub_class_struct_t*       hub_class;
    tr_struct_t*                  tr_ptr;
    usb_status                     status = USBERR_NO_INTERFACE;

    #ifdef _HOST_DEBUG_
       DEBUG_LOG_TRACE("usb_class_hub_recv_bitmap");
    #endif
    //USB_PRINTF("r \n");

    if ((com_ptr == NULL) || (com_ptr->class_ptr == NULL))
    {
        return USBERR_ERROR;
    }

    hub_class = (usb_hub_class_struct_t*)com_ptr->class_ptr;
    
    if ((hub_class == NULL) || (buffer == NULL))
    {
        USB_PRINTF("input parameter error\n");
        return USBERR_ERROR;
    }

    hub_class->interrupt_callback = com_ptr->callback_fn;
    hub_class->interrupt_param = com_ptr->callback_param;

    if (hub_class->dev_handle == NULL)
    {
        return USBERR_ERROR;
    }

    if (hub_class->in_interrupt)
    {
        return USBERR_ERROR;
    }

    if (usb_host_get_tr(hub_class->host_handle, usb_class_hub_int_callback, hub_class, &tr_ptr) != USB_OK)
    {
        USB_PRINTF("error to get tr\n");
        return USBERR_ERROR;
    }
    
    tr_ptr->rx_buffer = buffer;
    tr_ptr->rx_length = length;                                            
    status = usb_host_recv_data(hub_class->host_handle, hub_class->interrupt_pipe, tr_ptr);
    if (status != USB_OK)
    {
        USB_PRINTF("\nError in usb_class_hub_recv_bitmap: %x", (unsigned int)status);
        usb_host_release_tr(hub_class->host_handle, tr_ptr);
        return USBERR_ERROR;
    }
    hub_class->in_interrupt = TRUE;
    return USB_OK;
}
Esempio n. 29
0
/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : usb_host_dev_mng_pre_detach
* Returned Value : 
* Comments       :
*     This function will be called when detach interrupt happens.
* 
*END*--------------------------------------------------------------------*/
usb_status  usb_host_dev_mng_pre_detach
(
    usb_host_handle    handle,
    uint8_t            hub_no,
    uint8_t            port_no
)
{ /* Body */
    usb_host_state_struct_t*            usb_host_ptr = (usb_host_state_struct_t*)handle;
    dev_instance_t*                     dev_instance_ptr;
    uint8_t                              interface_index;
    interface_descriptor_t*             intf = NULL;
    usb_device_interface_info_struct_t* lpinterface_info = NULL;
    class_map_t*                        class_map;

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

    /* search device list for the one being detached */
    USB_Host_lock();
    dev_instance_ptr = (dev_instance_t*)usb_host_dev_get_instance(handle, hub_no, port_no, (uint8_t)0);
    
    if (dev_instance_ptr == NULL)
    {
    #ifdef _HOST_DEBUG_
            DEBUG_LOG_TRACE("usb_host_dev_mng_pre_detach NULL device pointer");
    #endif
        USB_Host_unlock();
        return  USBERR_ERROR; /* No match, abandon ship! */
    }

    if (dev_instance_ptr->pre_detached == (uint8_t)TRUE)
    {
        USB_Host_unlock();
        return  USB_OK;
    }

    if (NULL != dev_instance_ptr->control_pipe)
    {
        /* Close control pipe */
        usb_host_cancel(handle, (pipe_struct_t*)dev_instance_ptr->control_pipe, (tr_struct_t*)NULL);
    }

    for (interface_index = 0; interface_index < dev_instance_ptr->configuration.interface_count; interface_index++)
    {
        intf = dev_instance_ptr->configuration.interface[interface_index].lpinterfaceDesc;
        lpinterface_info = usb_host_dev_mng_get_interface_info(dev_instance_ptr, intf);
        if (lpinterface_info == NULL)
        {
            continue;
        }

        class_map = lpinterface_info->lpClassDriverMap;
        if (class_map != NULL)
        {
            class_map->class_pre_deinit(lpinterface_info->lpClassHandle);
        }
    }
    dev_instance_ptr->pre_detached = (uint8_t)TRUE;

    USB_Host_unlock();
    if (dev_instance_ptr->state <= DEVSTATE_SET_CFG)
    {
        if (dev_instance_ptr->control_pipe != NULL)
        {
            usb_host_close_pipe(dev_instance_ptr->host, dev_instance_ptr->control_pipe);
            dev_instance_ptr->control_pipe = NULL;
        }
        if (dev_instance_ptr->lpConfiguration != NULL)
        {
            OS_Mem_free(dev_instance_ptr->lpConfiguration);
            dev_instance_ptr->lpConfiguration = NULL;
        }
    }
#ifdef _HOST_DEBUG_
        DEBUG_LOG_TRACE("usb_host_dev_mng_pre_detach SUCCESSFUL");
#endif

    return USB_OK;
} /* EndBody */
Esempio n. 30
0
void usb_class_mass_init
   (
      /* [IN] structure with USB pipe information on the interface */
      PIPE_BUNDLE_STRUCT_PTR      pbs_ptr,

      /* [IN] printer call struct pointer */
      CLASS_CALL_STRUCT_PTR       ccs_ptr
   )
{ /* Body */
   USB_MASS_CLASS_INTF_STRUCT_PTR   intf_ptr = ccs_ptr->class_intf_handle;

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

   /* Pointer validity-checking, clear memory, init header of intf_ptr */
   if (usb_host_class_intf_init(pbs_ptr, intf_ptr, &mass_anchor)) 
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_init");
      #endif
      return;
   }

   USB_lock();
   ccs_ptr->code_key = 0;
   ccs_ptr->code_key = usb_host_class_intf_validate( ccs_ptr );
   if (ccs_ptr->code_key == 0) goto Bad_Exit;

   /* Start filling up the members of interface handle (general class already filled) */
   intf_ptr->CONTROL_PIPE = usb_hostdev_get_pipe_handle(pbs_ptr,
      USB_CONTROL_PIPE, 0);
   intf_ptr->BULK_IN_PIPE = usb_hostdev_get_pipe_handle(pbs_ptr,
      USB_BULK_PIPE, USB_RECV);
   intf_ptr->BULK_OUT_PIPE = usb_hostdev_get_pipe_handle(pbs_ptr,
      USB_BULK_PIPE, USB_SEND);

   if (intf_ptr->CONTROL_PIPE    &&
      intf_ptr->BULK_IN_PIPE     &&
      intf_ptr->BULK_OUT_PIPE)  
   {
      /* Initialize the queue for storing the local copy of interface handles */
      usb_class_mass_q_init(intf_ptr);

      /* Store application handle */
      intf_ptr->APP = ccs_ptr;

      USB_unlock();
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_class_mass_init, SUCCESSFULL");
      #endif
      
      return;
   } /* Endif */

Bad_Exit:
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_class_mass_init, bad exit");
   #endif
   USB_mem_zero(intf_ptr, sizeof(USB_MASS_CLASS_INTF_STRUCT_PTR));
   ccs_ptr->class_intf_handle = NULL;
   ccs_ptr->code_key = 0;
   USB_unlock();
} /* Endbody */