예제 #1
0
u8	process_nyet_on_bulk(td_t 	*result_td, 
				hc_info_t *hc_reg_data)
{
	if(result_td->parent_ed_p->ed_desc.is_ep_in)
	{
		// Error State....
		return NO_ACTION;
	}
	
	result_td->err_cnt = 0;
	
	mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
	mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
	mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
	
	clear_ch_intr(result_td->cur_stransfer.alloc_chnum,	CH_STATUS_NYET);
				
	result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data);

	if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG)
	{
		result_td->parent_ed_p->ed_status.is_ping_enable = true;
	}
	else
	{
		result_td->parent_ed_p->ed_status.is_ping_enable = false;
	}
	
	update_datatgl(hc_reg_data->hc_size.b.pid, result_td);
	
	return RE_TRANSMIT;

}
u8	process_nak_on_control(	td_t 	*result_td,
                            hc_info_t *hc_reg_data)
{
    result_td->err_cnt = 0;

    mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
    mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
    mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
    clear_ch_intr(result_td->cur_stransfer.alloc_chnum,	CH_STATUS_NAK);

    //at OUT Transfer, we must re-transmit.
    if(result_td->parent_ed_p->ed_desc.is_ep_in==false)
    {
        result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data);

        update_datatgl(hc_reg_data->hc_size.b.pid, result_td);
    }

    if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG)
    {
        if(result_td->standard_dev_req_info.conrol_transfer_stage == DATA_STAGE)
        {
            if(result_td->parent_ed_p->ed_desc.is_ep_in==false)
            {
                result_td->parent_ed_p->ed_status.is_ping_enable = true;
            }
        }
        else if(result_td->standard_dev_req_info.conrol_transfer_stage == STATUS_STAGE)
        {
            if(result_td->parent_ed_p->ed_desc.is_ep_in==true)
            {
                result_td->parent_ed_p->ed_status.is_ping_enable = true;
            }
        }
        else
        {
            result_td->parent_ed_p->ed_status.is_ping_enable = false;
        }

    }

    return RE_SCHEDULE;


}
예제 #3
0
u8	process_xacterr_on_bulk(	td_t 	*result_td, 									       
					hc_info_t *hc_reg_data)
{
	u8	ret_val = 0;

	if(result_td->err_cnt<RETRANSMIT_THRESHOLD)
	{
		result_td->cur_stransfer.hc_reg.hc_int_msk.d32 |= (CH_STATUS_ACK+CH_STATUS_NAK+CH_STATUS_DataTglErr);
		ret_val = RE_TRANSMIT;
		result_td->err_cnt++ ;
	}
	else
	{
		mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
		mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
		mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
		ret_val = DE_ALLOCATE;
		result_td->err_cnt = 0 ;
		result_td->error_code = USB_ERR_STATUS_XACTERR;
	}
	
	clear_ch_intr(result_td->cur_stransfer.alloc_chnum,	CH_STATUS_DataTglErr);
				
	result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data);

	if(result_td->parent_ed_p->ed_desc.is_ep_in==false)
	{
		if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG)
		{
			result_td->parent_ed_p->ed_status.is_ping_enable = true;
		}
		else
		{
			result_td->parent_ed_p->ed_status.is_ping_enable = false;
		}	
	}

	
	update_datatgl(hc_reg_data->hc_size.b.pid, result_td);
	
	return ret_val;

}
예제 #4
0
u8	process_stall_on_bulk(	td_t *		result_td, 
				hc_info_t *	hc_reg_data)
{
	result_td->err_cnt 	=0;
	result_td->error_code	=USB_ERR_STATUS_STALL;

	//this channel is stalled, So we don't process another interrupts.
	clear_ch_intr(result_td->cur_stransfer.alloc_chnum,	CH_STATUS_ALL);
	
	//Mask ack Interrupt..
	mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
	mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
	mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);
	
	result_td->parent_ed_p->ed_status.is_ping_enable	=	false;
	result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data);
		
	update_datatgl(DATA0, result_td);	

		
	return DE_ALLOCATE;
}
u8	process_xfercompl_on_control(td_t 		*result_td,
                                 hc_info_t 	*hc_reg_data)
{
    u8	ret_val		= 0;

    result_td->err_cnt 	= 0;

    clear_ch_intr(result_td->cur_stransfer.alloc_chnum,CH_STATUS_ALL);
    //Mask ack Interrupt..
    mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
    mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
    mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);

    result_td->parent_ed_p->ed_status.is_ping_enable	=false;

    switch(result_td->standard_dev_req_info.conrol_transfer_stage)
    {
    case SETUP_STAGE:
        if(result_td->standard_dev_req_info.is_data_stage)
        {
            result_td->standard_dev_req_info.conrol_transfer_stage = DATA_STAGE;
        }
        else
        {
            result_td->standard_dev_req_info.conrol_transfer_stage = STATUS_STAGE;
        }
        ret_val = RE_TRANSMIT;

        break;

    case DATA_STAGE:

        result_td->transferred_szie += calc_transferred_size(true,result_td, hc_reg_data);

        if(result_td->transferred_szie==result_td->buf_size)
        {   //at IN Transfer, short transfer is accepted.
            result_td->standard_dev_req_info.conrol_transfer_stage 	=STATUS_STAGE;
            result_td->error_code = USB_ERR_STATUS_COMPLETE;
        }
        else
        {
            if(result_td->parent_ed_p->ed_desc.is_ep_in&& hc_reg_data->hc_size.b.xfersize)
            {
                if(result_td->transfer_flag&USB_TRANS_FLAG_NOT_SHORT)
                {
                    result_td->error_code				=USB_ERR_STATUS_SHORTREAD;
                    result_td->standard_dev_req_info.conrol_transfer_stage=STATUS_STAGE;
                }
                else
                {
                    result_td->error_code					=USB_ERR_STATUS_COMPLETE;
                    result_td->standard_dev_req_info.conrol_transfer_stage 	=STATUS_STAGE;
                }
            }
            else
            {   // the Data Stage is not completed. So we need to continue Data Stage.
                result_td->standard_dev_req_info.conrol_transfer_stage = DATA_STAGE;
                update_datatgl(hc_reg_data->hc_size.b.pid, result_td);
            }
        }

        if(hc_reg_data->hc_int.b.nyet)
        {
            //at OUT Transfer, we must re-transmit.
            if(result_td->parent_ed_p->ed_desc.is_ep_in==false)
            {

                if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG)
                {
                    result_td->parent_ed_p->ed_status.is_ping_enable = true;
                }
                else
                {
                    result_td->parent_ed_p->ed_status.is_ping_enable = false;
                }
            }
        }
        ret_val = RE_TRANSMIT;
        break;

    case STATUS_STAGE:
        result_td->standard_dev_req_info.conrol_transfer_stage = COMPLETE_STAGE;

        if(hc_reg_data->hc_int.b.nyet)
        {
            //at OUT Transfer, we must re-transmit.
            if(result_td->parent_ed_p->ed_desc.is_ep_in==false)
            {

                if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG)
                {
                    result_td->parent_ed_p->ed_status.is_ping_enable = true;
                }
                else
                {
                    result_td->parent_ed_p->ed_status.is_ping_enable = false;
                }
            }
        }

        ret_val = DE_ALLOCATE;
        break;

    default:
        break;
    }

    return ret_val;
}
예제 #6
0
u8	process_xfercompl_on_bulk(td_t 	*result_td, 
					hc_info_t *hc_reg_data)
{
	u8	ret_val=0;
	
	result_td->err_cnt 		= 	0;	

	clear_ch_intr(result_td->cur_stransfer.alloc_chnum,	CH_STATUS_ALL);
	
	//Mask ack Interrupt..
	mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK);
	mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK);
	mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr);

	result_td->parent_ed_p->ed_status.is_ping_enable	=false;

	result_td->transferred_szie += calc_transferred_size(true,result_td, hc_reg_data);

	if(result_td->transferred_szie==result_td->buf_size)
	{//at IN Transfer, short transfer is accepted.
		result_td->error_code	=	USB_ERR_STATUS_COMPLETE;
		ret_val = DE_ALLOCATE;
	}
	else
	{
		if(result_td->parent_ed_p->ed_desc.is_ep_in&& hc_reg_data->hc_size.b.xfersize)
		{
			if(result_td->transfer_flag&USB_TRANS_FLAG_NOT_SHORT)
			{
				result_td->error_code	=USB_ERR_STATUS_SHORTREAD;	
			}
			else
			{
				result_td->error_code	=USB_ERR_STATUS_COMPLETE;		
			}
			ret_val = DE_ALLOCATE;
		}
		else
		{	
			ret_val = RE_SCHEDULE;
		}
	}	
	update_datatgl(hc_reg_data->hc_size.b.pid, result_td);	

	if(hc_reg_data->hc_int.b.nyet)
	{
		//at OUT Transfer, we must re-transmit.
		if(result_td->parent_ed_p->ed_desc.is_ep_in==false)
		{			
			
			if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG)
			{
				result_td->parent_ed_p->ed_status.is_ping_enable = true;
			}
			else
			{
				result_td->parent_ed_p->ed_status.is_ping_enable = false;
			}			
		}	
	}
	
	return ret_val;
	
}