Exemplo n.º 1
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 */
Exemplo n.º 2
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 */
Exemplo n.º 3
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*--------------------------------------------------------------------*/
void usb_dev_list_attach_device
   (
      _usb_host_handle  handle,
      uint_8            speed,
      uint_8            hub_no,
      uint_8            port_no
   )
{ /* Body */
   DEV_INSTANCE_PTR           dev_instance_ptr;
   PIPE_INIT_PARAM_STRUCT     ctrl_pipe_init_params;
   USB_HOST_STATE_STRUCT_PTR  usb_host_ptr;
   DEV_INSTANCE_PTR           device_root = NULL;
   // clean warning uint_32                    state;

   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_attach_device attach device");
      DEBUGMSG(USB_DBG_LEVEL, ("usb_dev_list_attach_device attach device\n"));
   #endif
      //DEBUGMSG(1,("d"));
 
	
	//DEBUGMSG(TTC_DBG_LEVEL,("usb_dev_list_attach_device attach device\r\n"));
   
   usb_host_ptr = (USB_HOST_STATE_STRUCT_PTR)handle;

   /* Allocate new device instance */
   dev_instance_ptr = (DEV_INSTANCE_PTR)\
       USB_Uncached_memalloc(sizeof(DEV_INSTANCE));

   if (dev_instance_ptr == NULL) {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_attach_device failed to malloc device handle");
      #endif
     	//DEBUGMSG(TTC_DBG_LEVEL,("usb_dev_list_attach_device failed to malloc device handle\r\n"));
      return;
   } /* EndIf */

   USB_memzero(dev_instance_ptr, sizeof(DEV_INSTANCE));

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

   USB_lock();
   /* Insert instance in pushdown list of devices */
   dev_instance_ptr->next = usb_host_ptr->DEVICE_LIST_PTR;     /* existing list */
   usb_host_ptr->DEVICE_LIST_PTR = (pointer)dev_instance_ptr;  /* root = new device */
   device_root = dev_instance_ptr;

   /* Find unused address from 1 - 127 for this host */
   device_root->address = 1;
   do {
      dev_instance_ptr = device_root->next; /* 2nd device, if any */
      while (dev_instance_ptr != NULL) {    /* step through list  */
         if (device_root->address == dev_instance_ptr->address) {
            device_root->address++;
            break;
         } /* EndIf */
         dev_instance_ptr = dev_instance_ptr->next;
      } /* EndWhile */
   } while ((dev_instance_ptr != NULL) && (device_root->address <= 127));

   dev_instance_ptr = device_root;   

   /* If all 127 addresses used up, delete instance & bail out */
   if (dev_instance_ptr->address > 127) {
      usb_host_ptr->DEVICE_LIST_PTR = (pointer)\
         dev_instance_ptr->next; /* pop off list */
      USB_unlock();
      USB_memfree((pointer)dev_instance_ptr);
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_attach_device out of addresses");
      #endif
     	//DEBUGMSG(TTC_DBG_LEVEL,("usb_dev_list_attach_device out of addresses\r\n"));
      return;
   } /* EndIf */
      
   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.DEV_INSTANCE = dev_instance_ptr;
   ctrl_pipe_init_params.PIPETYPE = USB_CONTROL_PIPE;   
   ctrl_pipe_init_params.SPEED = dev_instance_ptr->speed;

#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(dev_instance_ptr->host, 
      &ctrl_pipe_init_params, 
      &dev_instance_ptr->control_pipe))
   {
      #ifdef _HOST_DEBUG_
         DEBUG_LOG_TRACE("usb_dev_list_attach_device open pipe failed");
         DEBUGMSG(USB_DBG_LEVEL, ("usb_dev_list_attach_device attach device open pipe failed\n"));
      #endif
      	//DEBUGMSG(TTC_DBG_LEVEL,("usb_dev_list_attach_device open pipe failed\r\n"));
      return;
   } /* Endif */

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

   _usb_host_ch9_get_descriptor((pointer)dev_instance_ptr,
      DESCTYPE_DEVICE<<8, 0, 8, 
      (uchar_ptr)&dev_instance_ptr->dev_descriptor);
   #ifdef _HOST_DEBUG_
      DEBUG_LOG_TRACE("usb_dev_list_attach_device SUCCESSFUL");
      DEBUGMSG(USB_DBG_LEVEL, ("usb_dev_list_attach_device SUCCESSFUL\n"));
   #endif
   	//DEBUGMSG(TTC_DBG_LEVEL,("usb_dev_list_attach_device SUCCESSFUL\r\n"));

} /* EndBody */