⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_ch9.c

📁 基于TI DSP/BIOS的usb网卡的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
    case USB_RECIP_INTERFACE:
        len = 2;//response len
        * buf = 0x00;
        *( buf + 1 ) = 0x00;               
        break;
    case USB_RECIP_ENDPOINT:
        len = 2;//response len
        tmp = Hal4D13_GetEndpointStatusWOInteruptClear( ( u8 )epindex );      
        if( tmp & D13REG_EPSTS_STALL )
            * buf = ENDPSTS_HALT;   /* Halt */
        else
            * buf = 0x00;
        *( buf + 1 ) = 0x00;        
        break;      
    default:
        break;
    }
    return len; 
}

static int set_configuration( struct rndis_dev * dev, u16 config )
{
    int len = - ERR_NOTSUPP; 

    if( config == DEV_CONFIG_VALUE )        
    {
        len = 0;
        dev->config = config;
        dev->usbstate = USB_STATE_CONFIGURED;
        Hal4D13_SingleTransmitEP0( 0, 0 ); 
    }
    else if( config == 0 )         
    {
        len = 0;
        dev->config = 0;
        dev->usbstate = USB_STATE_ADDRESS;     
        Hal4D13_SingleTransmitEP0( 0, 0 );    
    }
    return len; 
}

static int get_configuration( struct rndis_dev * dev, u8 * config )
{
    * config = dev->config;
    return 1;
}

#define INVALID_ENDPOINT_ID  0xff  //invalid id value sign

static u8 epindex2epid( u8 index )
{
    switch( index )
    {
    case  EP_ID_CONTROL:
        return EPINDEX4EP0_CONTROL_OUT;
    case EP_ID_INTERRUPT:
        return EPINDEX4EP01;
    case EP_ID_BULK_IN:
        return EPINDEX4EP02;
    case EP_ID_BULK_OUT:
        return EPINDEX4EP03;
    default:
        return INVALID_ENDPOINT_ID;   //invalid endpoint id
    }
}

static int clear_feature( u8 recipient, u8 index, u8 feature )
{
    u8 epid;
    int len = - ERR_NOTSUPP;
    if( ( recipient == USB_RECIP_ENDPOINT ) && ( feature == USB_ENDPOINT_HALT ) )
    {       
        epid = epindex2epid( index );
        if( INVALID_ENDPOINT_ID != epid )
        {   
            len = 0;
            Hal4D13_SetEndpointStatus( index, 0 );
            Hal4D13_SingleTransmitEP0( 0, 0 ); 
        }
    }    
    return len;
}

static int set_feature( u8 recipient, u8 index, u8 feature )
{
    u8 epid;
    int len = - ERR_NOTSUPP;    
    if( ( recipient == USB_RECIP_ENDPOINT ) && ( feature == USB_ENDPOINT_HALT ) )
    {
        epid = epindex2epid( index );
        if( INVALID_ENDPOINT_ID != epid )
        {
            len = 0;
            Hal4D13_SetEndpointStatus( index, D13REG_EPSTS_STALL );
            Hal4D13_SingleTransmitEP0( 0, 0 ); 
        }
    }
    return len;
}

static int set_address( struct rndis_dev * dev, u8 address )
{   
    Hal4D13_SetAddressEnable( address, 1 );
    dev->usbstate = USB_STATE_ADDRESS;
    Hal4D13_SingleTransmitEP0( 0, 0 ); 
    return 0;
}

static void update_ep_stall_status( struct rndis_dev * dev, u8 epIndex, u8 stall )
{
    enum ep_status status;

    if( stall )
        status = EP_STATUS_STALL;
    else
        status = EP_STATUS_IDLE;

    if( epIndex == EP_ID_BULK_IN )
        dev->in_ep.status = status;
    else if( epIndex == EP_ID_BULK_OUT )
        dev->out_ep.status = status;        
    else if( epIndex == EP_ID_INTERRUPT )
        dev->status_ep.status = status;
    else if( epIndex == 0 )
    {   /*ep0 status is controled by setup packet automaticly*/}
}

/*chap9 routines*/

/************************************************************************
handle received setup packet in ep0 transmit context,than store the 
response data in the databuff of the transmit context. 
if RNDIS send command ,return -1; else return the response data length.
************************************************************************/
#define  RNDIS_REQTYPE_MASK  (USB_TYPE_CLASS | USB_RECIP_INTERFACE)

int usb_setup( struct rndis_dev * dev )
{
    struct control_trans * trans = dev->ctrl_ep.trans;
    struct usb_ctrlrequest * ctrl = & ( trans->DeviceRequest );

    int  value = - ERR_NOTSUPP;
    u16  wIndex = le16_to_cpu( ctrl->wIndex );
    u16  wValue = le16_to_cpu( ctrl->wValue );
    u16  wLength = le16_to_cpu( ctrl->wLength ); 

    u8   dirin = ( ctrl->bRequestType & USB_DIR_IN );
    u8   recipient = ( ctrl->bRequestType & USB_RECIP_MASK );

    if( ( ( ctrl->bRequestType & RNDIS_REQTYPE_MASK ) == RNDIS_REQTYPE_MASK ) && ( wValue == 0 ) ) 
    { /*rndis data packet*/
        if( ( ctrl->bRequest == USB_CDC_SEND_ENCAPSULATED_COMMAND ) && (! dirin ))
        {
            if ( dev->config )
            {       
                Hal4D13_SingleTransmitEP0( 0, 0 );
                if( rndis_msg_parser( rndis_dev_index, trans->dataBuffer ) == 0 )
                    value = 0;
            }           
        }
        else if( ( ctrl->bRequest == USB_CDC_GET_ENCAPSULATED_RESPONSE ) && dirin )
        {
            if ( dev->config )
            {
                u32 len;
                u8 * buf = rndis_get_next_response ( rndis_dev_index,& len );
                if( buf )
                {
                    if( len < MAX_SETUP_BUFFER_SIZE )
                    {
                        memcpy( trans->dataBuffer, buf, len );
                        value = len;
                    }
                    else
                        value = 0;
                    rndis_free_response( rndis_dev_index, buf );
                }               
            }
        }        
    } 
    else
    {
        switch ( ctrl->bRequest ) 
        {
        case USB_REQ_GET_DESCRIPTOR:
            if ( dirin ) 
                value = get_descriptor( ( u8 )(( wValue >> 8 ) & 0xff ), //type
                ( u8 )( wValue & 0xff ), //index
                trans->dataBuffer,  MAX_SETUP_BUFFER_SIZE );    
            break;
        case USB_REQ_SET_CONFIGURATION:
            if( (! dirin ) && ( ctrl->bRequestType == 0 ) )
                value = set_configuration( dev, wValue );                       
            break;
        case USB_REQ_GET_CONFIGURATION:
            if ( dirin )
            {
                if( ( wValue == 0 ) && ( wLength == 1 ) )
                    value = get_configuration( dev,( u8 *)trans->dataBuffer );
            }
            break;
        case USB_REQ_SET_INTERFACE:
            if ( ! dirin )  
            {
                if( ( dev->config ) && ( recipient == USB_RECIP_INTERFACE ) 
                    && ( wIndex == 0 )  /*interface selector*/
                    && ( wValue == 0 ) ) /*alternate setting selector*/
                {
                    value = 0;
                    Hal4D13_SingleTransmitEP0( 0, 0 ); 
                }
            }
            break;
        case USB_REQ_GET_INTERFACE:
            if( dirin )
            {
                value = 1;
                * trans->dataBuffer = 0x00;
            }
            break;
        case USB_REQ_GET_STATUS:   
            if( dirin )
                value = get_status( recipient, wIndex, trans->dataBuffer );
            break;
        case USB_REQ_CLEAR_FEATURE:
            if( (! dirin ) && ( wLength == 0 ) )
            {
                u8 epindex = ( u8 )( wIndex & 0x7f );     //get target epindex
                value = clear_feature( recipient, epindex, ( u8 )wValue );
                if( ( value == 0 ) 
                    && ( recipient == USB_RECIP_ENDPOINT ) 
                    && ( wValue == USB_ENDPOINT_HALT ) )
                {
                    update_ep_stall_status( dev, epindex, 0 );              
                }
            }
            break;
        case USB_REQ_SET_FEATURE:
            if( (! dirin ) && ( wLength == 0 ) )
            {
                u8 epindex = ( u8 )( wIndex & 0x7f ); //index mask
                value = set_feature( recipient, epindex, ( u8 )wValue );
                if( ( value == 0 ) 
                    && ( recipient == USB_RECIP_ENDPOINT ) 
                    && ( wValue == USB_ENDPOINT_HALT ) )
                {
                    update_ep_stall_status( dev, epindex, 1 );  
                }
            }
            break;
        case USB_REQ_SET_ADDRESS:
            if( (! dirin ) && ( wIndex == 0 ) && ( wLength == 0 ) )
                value = set_address( dev,( u8 )( wValue & 0x7f )); //address mask
            break;
        default:
            break;
        }
    }

    return value;  
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -