亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? dwc_otg_hcd_intr.c

?? host usb 主設(shè)備程序 支持sd卡 mouse keyboard 的最單單的驅(qū)動程序 gcc編譯
?? C
?? 第 1 頁 / 共 4 頁
字號:
/** * Gets the actual length of a transfer after the transfer halts. _halt_status * holds the reason for the halt. * * For IN transfers where _halt_status is DWC_OTG_HC_XFER_COMPLETE, * *_short_read is set to 1 upon return if less than the requested * number of bytes were transferred. Otherwise, *_short_read is set to 0 upon * return. _short_read may also be NULL on entry, in which case it remains * unchanged. */static uint32_t get_actual_xfer_length(dwc_hc_t * _hc,				       dwc_otg_hc_regs_t * _hc_regs,				       dwc_otg_qtd_t * _qtd,				       dwc_otg_halt_status_e _halt_status,				       int *_short_read){	hctsiz_data_t hctsiz;	uint32_t length;	if (_short_read != NULL) {		*_short_read = 0;	}	hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);	if (_halt_status == DWC_OTG_HC_XFER_COMPLETE) {		if (_hc->ep_is_in) {			length = _hc->xfer_len - hctsiz.b.xfersize;			if (_short_read != NULL) {				*_short_read = (hctsiz.b.xfersize != 0);			}		} else if (_hc->qh->do_split) {			length = _qtd->ssplit_out_xfer_count;		} else {			length = _hc->xfer_len;		}	} else {		/*		 * Must use the hctsiz.pktcnt field to determine how much data		 * has been transferred. This field reflects the number of		 * packets that have been transferred via the USB. This is		 * always an integral number of packets if the transfer was		 * halted before its normal completion. (Can't use the		 * hctsiz.xfersize field because that reflects the number of		 * bytes transferred via the AHB, not the USB).		 */		length = (_hc->start_pkt_count - hctsiz.b.pktcnt) * _hc->max_packet;	}	return length;}/** * Updates the state of the URB after a Transfer Complete interrupt on the * host channel. Updates the actual_length field of the URB based on the * number of bytes transferred via the host channel. Sets the URB status * if the data transfer is finished. * * @return 1 if the data transfer specified by the URB is completely finished, * 0 otherwise. */static int update_urb_state_xfer_comp(dwc_hc_t * _hc,				      dwc_otg_hc_regs_t * _hc_regs,				      struct urb *_urb, dwc_otg_qtd_t * _qtd){	int xfer_done = 0;	int short_read = 0;	_urb->actual_length += get_actual_xfer_length(_hc, _hc_regs, _qtd,						      DWC_OTG_HC_XFER_COMPLETE,						      &short_read);#if 1 //orig	if (short_read || (_urb->actual_length == _urb->transfer_buffer_length)) {		xfer_done = 1;		if (short_read && (_urb->transfer_flags & URB_SHORT_NOT_OK)) {			_urb->status = -EREMOTEIO;		} else {			_urb->status = 0;		}	}#else	if (short_read) {		xfer_done = 1;		if (_urb->transfer_flags & URB_SHORT_NOT_OK) {			_urb->status = -EREMOTEIO;		} else {			_urb->status = 0;		}	}	if (_urb->actual_length == _urb->transfer_buffer_length) {		xfer_done = 1;	}#endif	{		hctsiz_data_t hctsiz;		hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);		dbg_otg("DWC_otg: %s: %s, channel %d\n",			    __FUNCTION__, (_hc->ep_is_in ? "IN" : "OUT"), _hc->hc_num);		dbg_otg("  hc->xfer_len %d\n", _hc->xfer_len);		dbg_otg("  hctsiz.xfersize %d\n", hctsiz.b.xfersize);		dbg_otg("  urb->transfer_buffer_length %d\n",			    _urb->transfer_buffer_length);		dbg_otg("  urb->actual_length %d\n", _urb->actual_length);		dbg_otg("  short_read %d, xfer_done %d\n", short_read, xfer_done);	}	return xfer_done;}/* * Save the starting data toggle for the next transfer. The data toggle is * saved in the QH for non-control transfers and it's saved in the QTD for * control transfers. */static void save_data_toggle(dwc_hc_t * _hc, dwc_otg_hc_regs_t * _hc_regs, dwc_otg_qtd_t * _qtd){	hctsiz_data_t hctsiz;	hctsiz.d32 = dwc_read_reg32(&_hc_regs->hctsiz);	if (_hc->ep_type != DWC_OTG_EP_TYPE_CONTROL) {		dwc_otg_qh_t *qh = _hc->qh;		if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) {			qh->data_toggle = DWC_OTG_HC_PID_DATA0;		} else {			qh->data_toggle = DWC_OTG_HC_PID_DATA1;		}	} else {		if (hctsiz.b.pid == DWC_HCTSIZ_DATA0) {			_qtd->data_toggle = DWC_OTG_HC_PID_DATA0;		} else {			_qtd->data_toggle = DWC_OTG_HC_PID_DATA1;		}	}}/** * Frees the first QTD in the QH's list if free_qtd is 1. For non-periodic * QHs, removes the QH from the active non-periodic schedule. If any QTDs are * still linked to the QH, the QH is added to the end of the inactive * non-periodic schedule. For periodic QHs, removes the QH from the periodic * schedule if no more QTDs are linked to the QH. */static void deactivate_qh(dwc_otg_hcd_t * _hcd, dwc_otg_qh_t * _qh, int free_qtd){	int continue_split = 0;	dwc_otg_qtd_t *qtd;	DWC_DEBUGPL(DBG_HCDV, "  %s(%p,%p,%d)\n", __func__, _hcd, _qh, free_qtd);	qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry);	if (qtd->complete_split) {		continue_split = 1;	} else if ((qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_MID) ||		   (qtd->isoc_split_pos == DWC_HCSPLIT_XACTPOS_END)) {		continue_split = 1;	}	if (free_qtd) {		dwc_otg_hcd_qtd_remove_and_free(qtd);		continue_split = 0;	}	_qh->channel = NULL;	_qh->qtd_in_process = NULL;	dwc_otg_hcd_qh_deactivate(_hcd, _qh, continue_split);}/** * Updates the state of an Isochronous URB when the transfer is stopped for * any reason. The fields of the current entry in the frame descriptor array * are set based on the transfer state and the input _halt_status. Completes * the Isochronous URB if all the URB frames have been completed. * * @return DWC_OTG_HC_XFER_COMPLETE if there are more frames remaining to be * transferred in the URB. Otherwise return DWC_OTG_HC_XFER_URB_COMPLETE. */static dwc_otg_halt_status_eupdate_isoc_urb_state(dwc_otg_hcd_t * _hcd,		      dwc_hc_t * _hc,		      dwc_otg_hc_regs_t * _hc_regs,		      dwc_otg_qtd_t * _qtd, dwc_otg_halt_status_e _halt_status){	struct urb *urb = _qtd->urb;	dwc_otg_halt_status_e ret_val = _halt_status;	struct usb_iso_packet_descriptor *frame_desc;	frame_desc = &urb->iso_frame_desc[_qtd->isoc_frame_index];	switch (_halt_status) {	case DWC_OTG_HC_XFER_COMPLETE:		frame_desc->status = 0;		frame_desc->actual_length =			get_actual_xfer_length(_hc, _hc_regs, _qtd, _halt_status, NULL);		break;	case DWC_OTG_HC_XFER_FRAME_OVERRUN:		urb->error_count++;		if (_hc->ep_is_in) {			frame_desc->status = -ENOSR;		} else {			frame_desc->status = -ECOMM;		}		frame_desc->actual_length = 0;		break;	case DWC_OTG_HC_XFER_BABBLE_ERR:		urb->error_count++;		frame_desc->status = -EOVERFLOW;		/* Don't need to update actual_length in this case. */		break;	case DWC_OTG_HC_XFER_XACT_ERR:		urb->error_count++;		frame_desc->status = -EPROTO;		frame_desc->actual_length =			get_actual_xfer_length(_hc, _hc_regs, _qtd, _halt_status, NULL);	default:		DWC_ERROR("%s: Unhandled _halt_status (%d)\n", __func__, _halt_status);		BUG();		break;	}	if (++_qtd->isoc_frame_index == urb->number_of_packets) {		/*		 * urb->status is not used for isoc transfers.		 * The individual frame_desc statuses are used instead.		 */		dwc_otg_hcd_complete_urb(_hcd, urb, 0);		ret_val = DWC_OTG_HC_XFER_URB_COMPLETE;	} else {		ret_val = DWC_OTG_HC_XFER_COMPLETE;	}	return ret_val;}/** * Releases a host channel for use by other transfers. Attempts to select and * queue more transactions since at least one host channel is available. * * @param _hcd The HCD state structure. * @param _hc The host channel to release. * @param _qtd The QTD associated with the host channel. This QTD may be freed * if the transfer is complete or an error has occurred. * @param _halt_status Reason the channel is being released. This status * determines the actions taken by this function. */static void release_channel(dwc_otg_hcd_t * _hcd,			    dwc_hc_t * _hc,			    dwc_otg_qtd_t * _qtd, dwc_otg_halt_status_e _halt_status){	dwc_otg_transaction_type_e tr_type;	int free_qtd;	DWC_DEBUGPL(DBG_HCDV, "  %s: channel %d, halt_status %d\n",		    __func__, _hc->hc_num, _halt_status);	switch (_halt_status) {	case DWC_OTG_HC_XFER_URB_COMPLETE:		free_qtd = 1;		break;	case DWC_OTG_HC_XFER_AHB_ERR:	case DWC_OTG_HC_XFER_STALL:	case DWC_OTG_HC_XFER_BABBLE_ERR:		free_qtd = 1;		break;	case DWC_OTG_HC_XFER_XACT_ERR:		if (_qtd->error_count >= 3) {			DWC_DEBUGPL(DBG_HCDV, "  Complete URB with transaction error\n");			free_qtd = 1;			_qtd->urb->status = -EPROTO;			dwc_otg_hcd_complete_urb(_hcd, _qtd->urb, -EPROTO);		} else {			free_qtd = 0;		}		break;	case DWC_OTG_HC_XFER_URB_DEQUEUE:		/*		 * The QTD has already been removed and the QH has been		 * deactivated. Don't want to do anything except release the		 * host channel and try to queue more transfers.		 */		goto cleanup;	case DWC_OTG_HC_XFER_NO_HALT_STATUS:		DWC_ERROR("%s: No halt_status, channel %d\n", __func__, _hc->hc_num);		free_qtd = 0;		break;	default:		free_qtd = 0;		break;	}	deactivate_qh(_hcd, _hc->qh, free_qtd);      cleanup:	/*	 * Release the host channel for use by other transfers. The cleanup	 * function clears the channel interrupt enables and conditions, so	 * there's no need to clear the Channel Halted interrupt separately.	 */	dwc_otg_hc_cleanup(_hcd->core_if, _hc);	list_add_tail(&_hc->hc_list_entry, &_hcd->free_hc_list);	switch (_hc->ep_type) {	case DWC_OTG_EP_TYPE_CONTROL:	case DWC_OTG_EP_TYPE_BULK:		_hcd->non_periodic_channels--;		break;	default:		/*		 * Don't release reservations for periodic channels here.		 * That's done when a periodic transfer is descheduled (i.e.		 * when the QH is removed from the periodic schedule).		 */		break;	}	/* Try to queue more transfers now that there's a free channel. */	tr_type = dwc_otg_hcd_select_transactions(_hcd);	if (tr_type != DWC_OTG_TRANSACTION_NONE) {		dwc_otg_hcd_queue_transactions(_hcd, tr_type);	}}/** * Halts a host channel. If the channel cannot be halted immediately because * the request queue is full, this function ensures that the FIFO empty * interrupt for the appropriate queue is enabled so that the halt request can * be queued when there is space in the request queue. * * This function may also be called in DMA mode. In that case, the channel is * simply released since the core always halts the channel automatically in * DMA mode. */static void halt_channel(dwc_otg_hcd_t * _hcd,			 dwc_hc_t * _hc, dwc_otg_qtd_t * _qtd, dwc_otg_halt_status_e _halt_status){	if (_hcd->core_if->dma_enable) {		release_channel(_hcd, _hc, _qtd, _halt_status);		return;	}	/* Slave mode processing... */	dwc_otg_hc_halt(_hcd->core_if, _hc, _halt_status);	if (_hc->halt_on_queue) {		gintmsk_data_t gintmsk = {.d32 = 0 };		dwc_otg_core_global_regs_t *global_regs;		global_regs = _hcd->core_if->core_global_regs;		if (_hc->ep_type == DWC_OTG_EP_TYPE_CONTROL || _hc->ep_type == DWC_OTG_EP_TYPE_BULK) {			/*			 * Make sure the Non-periodic Tx FIFO empty interrupt			 * is enabled so that the non-periodic schedule will			 * be processed.			 */			gintmsk.b.nptxfempty = 1;			dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);		} else {			/*			 * Move the QH from the periodic queued schedule to			 * the periodic assigned schedule. This allows the			 * halt to be queued when the periodic schedule is			 * processed.			 */			list_move(&_hc->qh->qh_list_entry, &_hcd->periodic_sched_assigned);			/*			 * Make sure the Periodic Tx FIFO Empty interrupt is			 * enabled so that the periodic schedule will be			 * processed.			 */			gintmsk.b.ptxfempty = 1;			dwc_modify_reg32(&global_regs->gintmsk, 0, gintmsk.d32);		}	}}/** * Performs common cleanup for non-periodic transfers after a Transfer * Complete interrupt. This function should be called after any endpoint type * specific handling is finished to release the host channel. */static void complete_non_periodic_xfer(dwc_otg_hcd_t * _hcd,				       dwc_hc_t * _hc,				       dwc_otg_hc_regs_t * _hc_regs,				       dwc_otg_qtd_t * _qtd,				       dwc_otg_halt_status_e _halt_status){	hcint_data_t hcint;	_qtd->error_count = 0;	hcint.d32 = dwc_read_reg32(&_hc_regs->hcint);	if (hcint.b.nyet) {		/*		 * Got a NYET on the last transaction of the transfer. This		 * means that the endpoint should be in the PING state at the		 * beginning of the next transfer.		 */		_hc->qh->ping_state = 1;		clear_hc_int(_hc_regs, nyet);	}	/*	 * Always halt and release the host channel to make it available for	 * more transfers. There may still be more phases for a control	 * transfer or more data packets for a bulk transfer at this point,	 * but the host channel is still halted. A channel will be reassigned	 * to the transfer when the non-periodic schedule is processed after	 * the channel is released. This allows transactions to be queued	 * properly via dwc_otg_hcd_queue_transactions, which also enables the	 * Tx FIFO Empty interrupt if necessary.	 */	if (_hc->ep_is_in) {		/*		 * IN transfers in Slave mode require an explicit disable to		 * halt the channel. (In DMA mode, this call simply releases		 * the channel.)		 */		halt_channel(_hcd, _hc, _qtd, _halt_status);	} else {		/*		 * The channel is automatically disabled by the core for OUT		 * transfers in Slave mode.		 */		release_channel(_hcd, _hc, _qtd, _halt_status);	}}/** * Performs common cleanup for periodic transfers after a Transfer Complete * interrupt. This function should be called after any endpoint type specific * handling is finished to release the host channel. */static void complete_periodic_xfer(dwc_otg_hcd_t * _hcd,				   dwc_hc_t * _hc,				   dwc_otg_hc_regs_t * _hc_regs,				   dwc_otg_qtd_t * _qtd, dwc_otg_halt_status_e _halt_status){	hctsiz_data_t hctsiz;	_qtd->error_count = 0;

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
天堂在线亚洲视频| 欧美日本在线视频| 国产精品系列在线| 粉嫩欧美一区二区三区高清影视 | 精品国产乱码久久久久久老虎 | 国产精品三级视频| av不卡免费电影| 一区二区三区国产| 91精品综合久久久久久| 久久超碰97人人做人人爱| 精品少妇一区二区三区| 精彩视频一区二区| 国产色91在线| 欧美三级一区二区| 狠狠色2019综合网| 亚洲精品写真福利| 日韩欧美精品在线| 成人福利视频在线看| 亚洲一区二区av电影| 欧美一区二区三区视频免费| 国产激情视频一区二区三区欧美 | 国产盗摄一区二区三区| 亚洲激情五月婷婷| 久久久久久免费毛片精品| 色哟哟在线观看一区二区三区| 婷婷开心激情综合| 国产精品久久免费看| 欧美日韩高清一区二区| 国产福利精品导航| 美女看a上一区| 亚洲美腿欧美偷拍| 国产精品福利在线播放| 欧美一区二区三区日韩视频| 色综合久久中文综合久久牛| 精品一区二区三区免费毛片爱| 国产精品久久久久影院| 精品国产成人在线影院| 欧美群妇大交群的观看方式| 一本色道久久综合亚洲aⅴ蜜桃| 国产一区二区网址| 久草精品在线观看| 久久国产精品72免费观看| 天天综合色天天综合色h| 亚洲男人的天堂网| 亚洲免费视频成人| 亚洲欧美日韩一区二区| 亚洲人成影院在线观看| 亚洲欧洲一区二区三区| 亚洲激情图片小说视频| 一区二区三区 在线观看视频| 国产精品成人一区二区三区夜夜夜| 久久亚洲综合色一区二区三区| 欧美xxxxxxxxx| 中文字幕免费不卡在线| 亚洲伊人伊色伊影伊综合网| 亚洲最新在线观看| 日本在线不卡视频一二三区| 日本强好片久久久久久aaa| 久久成人18免费观看| 国产精品一区一区三区| 菠萝蜜视频在线观看一区| 不卡的av电影在线观看| 欧美日韩免费电影| 欧美色综合网站| 久久综合狠狠综合久久综合88| 国产精品国产精品国产专区不片| 一区二区三区视频在线观看| 日本中文一区二区三区| 国产激情精品久久久第一区二区| 不卡一卡二卡三乱码免费网站| 欧美日韩国产小视频| 国产亚洲欧美色| 日本麻豆一区二区三区视频| 高清av一区二区| 欧美草草影院在线视频| 91麻豆精品国产91久久久| 亚洲国产精品v| 日韩av一区二区在线影视| 国产精品69毛片高清亚洲| 欧美日本精品一区二区三区| 国产精品私人影院| 日本欧美久久久久免费播放网| av不卡在线观看| 国产精品伦一区二区三级视频| 蜜桃av一区二区三区| 欧美艳星brazzers| 夜夜操天天操亚洲| 91蜜桃网址入口| 综合激情网...| 91在线一区二区| 亚洲美女少妇撒尿| 91在线视频观看| 成人欧美一区二区三区| 亚洲视频每日更新| 国产成人久久精品77777最新版本| 在线不卡免费av| 亚洲精品国产高清久久伦理二区| 国产精品一区一区三区| 精品福利二区三区| 久久99最新地址| 一本色道久久综合亚洲aⅴ蜜桃 | 婷婷中文字幕综合| 国产精品羞羞答答xxdd| 欧美videossexotv100| 午夜精品福利在线| 欧美一区二区三区啪啪| 青青草国产精品97视觉盛宴| 欧美乱妇15p| 五月激情六月综合| 欧美一级片在线| 激情六月婷婷综合| 久久久国际精品| 99riav久久精品riav| 国产精品色噜噜| 色婷婷综合五月| 日日夜夜免费精品视频| 日韩一区二区三区视频| 久久se这里有精品| 国产精品欧美一级免费| 99九九99九九九视频精品| 亚洲人精品午夜| 欧美一区二区三区公司| 国产精品一区三区| 亚洲美女免费在线| 色欧美片视频在线观看| 日韩高清国产一区在线| 久久伊99综合婷婷久久伊| 96av麻豆蜜桃一区二区| caoporm超碰国产精品| 婷婷久久综合九色国产成人| 久久久精品影视| 欧美日韩卡一卡二| 成人h动漫精品| 人人爽香蕉精品| 一区二区三区在线免费播放| 日韩一区二区在线观看视频| 91无套直看片红桃| 国产剧情在线观看一区二区 | 国产成人精品亚洲777人妖 | 欧美一区二区三区视频免费播放| 懂色av一区二区三区免费观看| 日韩高清一区在线| 亚洲国产裸拍裸体视频在线观看乱了| 久久先锋影音av鲁色资源网| 欧美精品自拍偷拍动漫精品| 一本色道久久加勒比精品| 国产精品一区二区三区乱码| 免费在线看成人av| 亚洲gay无套男同| 亚洲综合小说图片| 综合色天天鬼久久鬼色| 日本一区二区三区四区| 国产亚洲精品免费| 欧美一区二区精品| 欧美日韩国产首页| 91在线视频在线| 日本韩国精品在线| 色婷婷亚洲精品| 91国偷自产一区二区开放时间 | av电影在线观看一区| 成人av免费观看| 日本高清不卡视频| 精品视频1区2区3区| 欧美无乱码久久久免费午夜一区 | 一二三区精品视频| 丝袜美腿高跟呻吟高潮一区| 男男gaygay亚洲| 成人久久视频在线观看| caoporm超碰国产精品| 色综合久久88色综合天天6 | 亚洲国产精品一区二区久久恐怖片| 亚洲一本大道在线| 性做久久久久久| 日韩成人午夜电影| 懂色av一区二区三区免费观看| 91成人网在线| 国产日韩精品一区二区浪潮av| 一区二区三区影院| 狠狠狠色丁香婷婷综合久久五月| 九九九精品视频| 在线日韩av片| 国产无人区一区二区三区| 亚洲欧美影音先锋| 午夜精品久久久久久久| 顶级嫩模精品视频在线看| 欧美日韩午夜影院| 日韩伦理免费电影| 国产精品影视在线| 91福利国产成人精品照片| 久久九九久久九九| 亚洲国产综合色| 91一区一区三区| 国产欧美一区二区三区沐欲 | 中文字幕一区二区三区不卡在线| 视频一区国产视频| 欧美日韩国产高清一区| 综合激情网...| 91麻豆国产福利精品| 欧美精品一区二区三区高清aⅴ| 91一区二区在线观看|