📄 usb_ch9.c
字号:
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 + -