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

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

?? usbhcdsl811hslib.c

?? sl811hs_vxworks_host_driver_v1_0_13 sl811的主驅(qū)動
?? C
?? 第 1 頁 / 共 5 頁
字號:
	pPipe->speed == USB_SPEED_LOW)
	return TRUE;

    return FALSE;
    }


/***************************************************************************
*
* dirFromPid - returns USB_DIR_xxxx based on USB_PID_xxxx
*
* RETURNS: USB_DIR_xxxx
*/

LOCAL UINT16 dirFromPid
    (
    UINT16 pid
    )

    {
    switch (pid)
    {
    case USB_PID_SETUP:
    case USB_PID_OUT:	
	return USB_DIR_OUT;

    case USB_PID_IN:	
	return USB_DIR_IN;

    default:	    
	return USB_DIR_IN;
    }
    }


/***************************************************************************
*
* assignTds - assign TDs for each IRP bfrList[] entry
*
* Assigns and initializes TDs to map the next bfrList[] entry in the IRP.  
* Stops when all all bfrList[] entries have been mapped, when all TDs for 
* the IRP have been exhausted, or when buffer bandwidth calculations indicate 
* we shouldn't map any more TDs at this time.  
*
* This function also updates the pHost->nanoseconds field with the bandwidth
* required by this transfer if appropriate.
*
* This mapping has the effect of moving TDs from the free list to the "in
* use" list in the IRP_WORKSPACE.  TDs in the "in use" list are always
* linked in the order in which they should be executed.
*
* NOTE: We choose to map only one bfrList[] entry at a time to simplify the
* the handling of input underrun.  When an underrun occurs, the 
* rescheduleTds() function releases all TDs scheduled up through that point.
* We then schedule TDs for the following bfrList[] entries if any.
*
* RETURNS: N/A
*/

LOCAL VOID assignTds
    (
    pHCD_HOST pHost,
    pUSB_IRP pIrp,
    pIRP_WORKSPACE pWork
    )

    {
    pHCD_PIPE pPipe = pWork->pPipe;
    pTD_WRAPPER pTd;
    pUSB_BFR_LIST pBfrList;
    UINT32 bytesThroughFrameCount;
    UINT16 maxLen;
    UINT32 nanoseconds;
    UINT32 nanosecondsAtStart;
    UINT32 ctlSts;
    UINT32 token;


    /* Record the bus time already used by this transfer. */

    nanosecondsAtStart = pWork->nanoseconds;


    /* Assign TDs to map the current bfrList[] entry.  Stop when the buffer is 
     * fully mapped, when we run out of TDs, or when bus bandwidth calculations 
     * indicate we should not allocate more TDs at this time.
     */

    pBfrList = &pIrp->bfrList [pWork->bfrNo];

    while ((pWork->bfrOffset < pBfrList->bfrLen ||
	   (pBfrList->bfrLen == 0 && !pWork->zeroLenMapped)) && 
	   pWork->pTdFree != NULL)
	{

	/* Calculate the length of this TD. */

	if (pPipe->transferType == USB_XFRTYPE_ISOCH)
	    {
	    pWork->frameCount++;

	    bytesThroughFrameCount = pWork->frameCount 
				     * pPipe->bandwidth 
				     / 1000L;

	    maxLen = min (bytesThroughFrameCount - pWork->bytesSoFar,
	    pBfrList->bfrLen - pWork->bfrOffset);

	    maxLen = min (maxLen, pPipe->maxPacketSize);

	    if (pIrp->dataBlockSize != 0 && maxLen > pIrp->dataBlockSize)
		    maxLen = (maxLen / pIrp->dataBlockSize) 
			     * pIrp->dataBlockSize;

	    pWork->bytesSoFar += maxLen;
	    }
	else
	    {
	    /* Transfer length calculation for non-isoch pipes. */

	    maxLen = min (pBfrList->bfrLen - pWork->bfrOffset, 
			  pPipe->maxPacketSize);
	    }


	/* Determine if there are any bandwidth limitations which would prevent 
	 * scheduling this TD at this time.
	 *
	 * NOTE: Since the USBD has already checked bandwidth availability for
	 * isochronous and interrupt transfers, we need only check bandwidth
	 * availability for low speed control transfers.
	 */

	if (isBandwidthTracked (pPipe))
	    {
	    nanoseconds = usbTransferTime (pPipe->transferType, 
	    dirFromPid (pBfrList->pid), pPipe->speed, maxLen, 
	    UHC_HOST_DELAY, UHC_HUB_LS_SETUP);

	    if (pHost->nanoseconds + nanoseconds > USB_LIMIT_ALL)
		{
		/* There isn't enough bandwidth at this time.  Stop 
		 * scheduling for this transfer.
		 */
		
		break;
		}
	    }
	else
	    {
	    nanoseconds = 0;
	    }


	/* If this is the first time we've mapped a part of this bfrList[] entry,
	 * then flush the cache.  Note that we do this for input buffers as well
	 * since we don't know where the user's buffer is allocated and some CPU
	 * cache architectures may get confused near cache-line boundaries.
	 */

	if (pWork->bfrOffset == 0 && pBfrList->bfrLen > 0)
	    {
	    USER_FLUSH (pBfrList->pBfr, pBfrList->bfrLen);
	    }


	/* Unlink the TD from the free list. */

	pTd = pWork->pTdFree;
	pWork->pTdFree = pTd->sw.pNext;


	/* Initialize TD buffer pointer. */

	pTd->td.bfrPtr = TO_PCIPTR (&pBfrList->pBfr [pWork->bfrOffset]);
	pWork->bfrOffset += maxLen;

	if (maxLen == 0)
	    pWork->zeroLenMapped = TRUE;


	/* Initialize TD control/status word */ 

	ctlSts = UHCI_TDCS_SHORT | UHCI_TDCS_ERRCTR_3ERR;
	ctlSts |= (pPipe->speed == USB_SPEED_LOW) ? UHCI_TDCS_LOWSPEED : 0;
	ctlSts |= (pPipe->transferType == USB_XFRTYPE_ISOCH) ? 
		   UHCI_TDCS_ISOCH : 0;
	ctlSts |= UHCI_TDCS_STS_ACTIVE;


	/* enable IOC (interrupt on complete) if this is the last TD.  If
	 * this is an isochronous transfer, also enable IOC on a regular
	 * interval defined by ISOCH_INT_INTERVAL. 
	 */

	if (pWork->bfrOffset == pBfrList->bfrLen || pWork->pTdFree == NULL)
	    ctlSts |= UHCI_TDCS_COMPLETE;

	if (pPipe->transferType == USB_XFRTYPE_ISOCH)
	    {
	    pWork->isochTdsCreated++;

	    if (pWork->isochTdsCreated % ISOCH_INT_INTERVAL == 0)
		    ctlSts |= UHCI_TDCS_COMPLETE;
	    }

	pTd->td.ctlSts = TO_LITTLEL (ctlSts);


	/* Initialize TD token word */

	token = UHCI_TDTOK_MAXLEN_FMT (maxLen);

	if (pPipe->transferType != USB_XFRTYPE_ISOCH)
	    {
	    /* Normally, the data toggle begins with DATA0 and alternates
	     * between DATA0 and DATA1.  However, the last transfer for
	     * a control transfer - the status packet - is always a DATA1. 
	     */

	    if (pPipe->transferType == USB_XFRTYPE_CONTROL &&
		pWork->bfrNo == pIrp->bfrCount - 1)
		{
		token |= UHCI_TDTOK_DATA_TOGGLE;
		}
	    else
		{
		if (pIrp->dataToggle == USB_DATA0)
		    {
		    pIrp->dataToggle = USB_DATA1;
		    }
		else 
		    {
		    token |= UHCI_TDTOK_DATA_TOGGLE;
		    pIrp->dataToggle = USB_DATA0;
		    }
		}
	    }
	    
	token |= UHCI_TDTOK_ENDPT_FMT (pPipe->endpoint);
	token |= UHCI_TDTOK_DEVADRS_FMT (pPipe->busAddress);
	token |= UHCI_TDTOK_PID_FMT (pBfrList->pid);

	pTd->td.token = TO_LITTLEL (token);


	/* Store the time required to execute this TD */

	pTd->sw.nanoseconds = nanoseconds;
	pWork->nanoseconds += nanoseconds;


	/* put the TD at the end of the "in use" list.
	 *
	 * NOTE: If this QH is already active, then as soon as we
	 * set the linkPtr of the last TD in use we must expect
	 * that the UHC may begin executing this TD (does not apply
	 * to isochronous TDs for which there is no QH).
	 */

	pTd->td.linkPtr = UHC_END_OF_LIST;
	pTd->sw.pNext = NULL;

	if (pWork->pTdInUse == NULL)
	    {
	    pWork->pTdInUse = pTd;
	    }

	if (pPipe->transferType == USB_XFRTYPE_ISOCH &&
	    pWork->pNextIsochTd == NULL)
	    {
	    pWork->pNextIsochTd = pTd;
	    }

	DMA_FLUSH (&pTd->td, sizeof (pTd->td));

	if (pWork->pLastTdInUse != NULL)
	    {
	    pWork->pLastTdInUse->sw.pNext = pTd;

	    /* For non-isochronous transfers, append this TD to the list
	     * of TDs assigned to the IRP.	(Isochronous TDs are inserted
	     * into the schedule by calling scheduleIsochFrames().
	     */

	    if (pPipe->transferType != USB_XFRTYPE_ISOCH)
		{
		/* NOTE: Setting the "Vf" bit improves performance by 
		 * allowing the host controller to exchange data 
		 * continuously with the device until the device NAKs.
		 */
#ifdef INCLUDE_USB_PCI
		pWork->pLastTdInUse->td.linkPtr = TO_PCIPTR (pTd) 
						  | TO_LITTLEL (UHCI_LINK_VF);
#else
		pWork->pLastTdInUse->td.linkPtr = TO_PCIPTR (pTd) | UHCI_LINK_VF;
#endif

		DMA_FLUSH (&pWork->pLastTdInUse->td.linkPtr, 
			   sizeof (pWork->pLastTdInUse->td.linkPtr));
		}
	    }

	pWork->pLastTdInUse = pTd;
	}


    /* If there is a QH, we should initialize it to point to the beginning of 
     * the TD list.
     */

    if (pWork->pQh != NULL && pWork->pQh->qh.tdLink == UHC_END_OF_LIST)
	{
	/* Initialize QH "vertical" pointer */

	pWork->pQh->qh.tdLink = TO_PCIPTR (pWork->pTdInUse);
	DMA_FLUSH (&pWork->pQh->qh.tdLink, sizeof (pWork->pQh->qh.tdLink));
	}

    /* Update the bandwidth-in-use for this controller.  
     *
     * NOTE: The pWork->nanoseconds field is 0 for all transfer types
     * except low speed control transfers, so the following calculation
     * often has no effect.
     */

    pHost->nanoseconds += pWork->nanoseconds - nanosecondsAtStart;
    }


/***************************************************************************
*
* unlinkIsochTd - unlink an isochronous TD
*
* Searches the indicated <frame> for a TD which corresponds to the
* IRP_WORKSPACE <pWork> (and hence which correspond to a given TD).
* If found, the TD is unlinked.
*
* RETURNS: N/A
*/

LOCAL VOID unlinkIsochTd
    (
    pHCD_HOST pHost,
    pIRP_WORKSPACE pWork,
    UINT32 frame
    )

    {
    pUINT32 pPciPtrToTd;
    pTD_WRAPPER pTd;


    /* Search frame for a TD belonging to this IRP and remove it from the 
     * work list.  We've exhausted the list of isochronous TDs when we 
     * reach the "interrupt anchor" QH.
     */

    pPciPtrToTd = &pHost->pFrameList->linkPtr [frame];
    pTd = TD_FROM_PCIPTR (*pPciPtrToTd);

    while (pTd != (pTD_WRAPPER) &pHost->pIntAnchorQhs [frame])
	{
	if (pTd->sw.pWork == pWork)
	    {
	    /* We found a TD for this IRP.	Unlink it. */

	    *pPciPtrToTd = pTd->td.linkPtr;
	    DMA_FLUSH (pPciPtrToTd, sizeof (*pPciPtrToTd));

	    --pWork->isochCount;

	    break;
	    }

	pPciPtrToTd = (pUINT32) &pTd->td.linkPtr;
	pTd = TD_FROM_PCIPTR (pTd->td.linkPtr);
	}
    }


/***************************************************************************
*
* unscheduleIsochTransfer - removes isochronous transfer from work list
*
* RETURNS: N/A
*/

LOCAL VOID unscheduleIsochTransfer
    (
    pHCD_HOST pHost,
    pUSB_IRP pIrp,
    pIRP_WORKSPACE pWork
    )

    {
    UINT16 frame;


    /* Remove all pending isoch TDs for this IRP from the work list */

    for (frame = 0; 
         frame < UHCI_FRAME_LIST_ENTRIES && pWork->isochCount > 0; 
	 frame++)
	{
	unlinkIsochTd (pHost, pWork, frame);
	}
    }
    

/***************************************************************************
*
* scheduleIsochFrames - insert isoch frames into work list
*
* Schedules isochronous transfers into frames.
*
* RETURNS: N/A
*/

LOCAL VOID scheduleIsochFrames
    (
    pHCD_HOST pHost,
    pUSB_IRP pIrp,
    pIRP_WORKSPACE pWork
    )

    {
    pTD_WRAPPER pTd;
    UINT16 frame;

    /* Schedule all initialized TDs onto the work list */

    while ((pTd = pWork->pNextIsochTd) != NULL && 
	    pWork->isochCount < UHCI_FRAME_LIST_ENTRIES)
	{
	/* Link the TD into the work list. */

	pTd->sw.frameNo = frame = pWork->isochNext;

	pTd->td.linkPtr = pHost->pFrameList->linkPtr [frame];
	DMA_FLUSH (&pTd->td.linkPtr, sizeof (pTd->td.linkPtr));

	pHost->pFrameList->linkPtr [pWork->isochNext] = TO_PCIPTR (pTd);
	DMA_FLUSH (&pHost->pFrameList->linkPtr [frame], 
		   sizeof (pHost->pFrameList->linkPtr [frame]));


	/* Advance to the next isoch TD for this IRP. */

	pWork->pNextIsochTd = pTd->sw.pNext;

	if (++pWork->isochNext == UHCI_FRAME_LIST_ENTRIES)
	    pWork->isochNext = 0;

	pWork->isochCount++;
	}
    }


/***************************************************************************
*
* scheduleIsochTransfer - inserts isoch IRP in frame list

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品丝袜91| 26uuu另类欧美亚洲曰本| 日本美女一区二区三区视频| 精品粉嫩aⅴ一区二区三区四区| 懂色av一区二区三区蜜臀| 午夜精品爽啪视频| 国产精品网友自拍| 日韩视频一区二区三区在线播放| 成人福利视频在线看| 老司机一区二区| 伊人色综合久久天天人手人婷| 精品国产亚洲一区二区三区在线观看| 91亚洲午夜精品久久久久久| 精品综合免费视频观看| 午夜欧美一区二区三区在线播放| 国产欧美一区二区精品性色超碰| 91精品国产乱| 91福利小视频| 99综合电影在线视频| 精品在线观看免费| 日韩福利视频网| 亚洲男人的天堂一区二区| 久久久久国产免费免费| 欧美电影在线免费观看| 91看片淫黄大片一级在线观看| 国产一区二区毛片| 精品一区二区综合| 日韩电影在线观看一区| 亚洲午夜日本在线观看| 亚洲人成网站在线| 国产精品免费久久| 日本一区二区三区四区在线视频| 日韩视频中午一区| 欧美一级片免费看| 欧美一区二区久久| 一区二区三区成人| 日韩毛片一二三区| 中文字幕中文在线不卡住| 欧美国产激情二区三区| 国产午夜亚洲精品理论片色戒 | 6080亚洲精品一区二区| 一本久久a久久免费精品不卡| 国产成人精品免费在线| 国产乱子伦一区二区三区国色天香| 免费成人结看片| 美脚の诱脚舐め脚责91| 日本欧美一区二区三区乱码| 午夜不卡av免费| 污片在线观看一区二区| 亚洲韩国精品一区| 水野朝阳av一区二区三区| 天堂一区二区在线| 天堂成人免费av电影一区| 亚洲aⅴ怡春院| 石原莉奈在线亚洲二区| 精品影视av免费| 国产成人免费在线观看| voyeur盗摄精品| 色香色香欲天天天影视综合网| 色呦呦网站一区| 欧美色国产精品| 欧美大白屁股肥臀xxxxxx| 精品日产卡一卡二卡麻豆| 国产亚洲综合av| 一区二区中文视频| 亚洲一级片在线观看| 五月天激情综合| 狠狠v欧美v日韩v亚洲ⅴ| 高清不卡一二三区| 一本一本大道香蕉久在线精品| 欧亚一区二区三区| 制服丝袜中文字幕亚洲| 久久久美女艺术照精彩视频福利播放| 中文字幕高清一区| 午夜亚洲福利老司机| 极品尤物av久久免费看| 成人黄动漫网站免费app| 91福利视频久久久久| 欧美一级片免费看| 中文字幕中文字幕一区| 婷婷久久综合九色国产成人| 国内精品视频666| 成人动漫在线一区| 欧美日韩一区 二区 三区 久久精品| 欧美一区二区久久| 国产精品国产三级国产aⅴ原创| 亚洲高清免费视频| 国内成+人亚洲+欧美+综合在线| 波多野结衣中文字幕一区二区三区| 一本到不卡免费一区二区| 91精品黄色片免费大全| 欧美激情一区二区在线| 亚洲成人免费观看| 国产不卡视频一区| 欧美丰满高潮xxxx喷水动漫| 国产精品素人视频| 日本不卡视频一二三区| 99久久精品国产麻豆演员表| 日韩精品在线一区二区| 亚洲欧美日韩国产一区二区三区 | 亚洲国产一区二区三区| 韩国精品主播一区二区在线观看| 91免费观看国产| 久久综合丝袜日本网| 夜夜精品浪潮av一区二区三区| 国产精品系列在线观看| 欧美揉bbbbb揉bbbbb| 国产精品久久福利| 国产一区在线观看麻豆| 欧美日韩精品一区二区天天拍小说 | 久久女同性恋中文字幕| 亚洲成人精品一区| 波多野结衣的一区二区三区| 精品日产卡一卡二卡麻豆| 91丨九色丨尤物| 国产亚洲成aⅴ人片在线观看 | 在线不卡欧美精品一区二区三区| 中国色在线观看另类| 久久99久久99小草精品免视看| 91国内精品野花午夜精品 | 久久久久久久久99精品| 日本午夜精品一区二区三区电影| 91麻豆精品在线观看| 日本一区二区三区dvd视频在线| 人人狠狠综合久久亚洲| 欧美久久久久久久久| 亚洲美女在线国产| 91丝袜美女网| 亚洲欧美一区二区三区极速播放 | 成人sese在线| 国产精品久久久久9999吃药| 国产精品一区二区三区四区 | 中文字幕国产一区| 国产成a人无v码亚洲福利| 精品国产成人系列| 老司机精品视频在线| 91精品一区二区三区在线观看| 亚洲国产精品影院| 欧美日韩国产首页| 亚洲gay无套男同| 91精品国产综合久久香蕉的特点 | 日韩av不卡一区二区| 91精品国产色综合久久不卡蜜臀| 亚洲午夜激情网站| 欧美男人的天堂一二区| 日本午夜一本久久久综合| 精品蜜桃在线看| 国产一区二区看久久| 国产亚洲欧美一区在线观看| 国产一区 二区| 国产精品日日摸夜夜摸av| av一区二区三区四区| 中文字幕国产精品一区二区| 色综合一个色综合| 亚洲.国产.中文慕字在线| 91麻豆精品国产综合久久久久久| 日韩av一级片| 国产喂奶挤奶一区二区三区| 成人动漫一区二区在线| 一区二区三区高清在线| 91精品国产欧美一区二区| 久久精品久久综合| 国产精品人妖ts系列视频| 色一情一乱一乱一91av| 欧美影院一区二区| 丝袜美腿亚洲色图| 精品国产凹凸成av人导航| 成人在线综合网| 亚洲精品一二三区| 欧美一卡二卡三卡| 国产精品1区二区.| 亚洲线精品一区二区三区八戒| 日韩午夜精品视频| av一二三不卡影片| 午夜精品免费在线观看| 久久久影视传媒| 色菇凉天天综合网| 久久精品99国产国产精| 国产精品福利一区二区| 欧美精品久久久久久久久老牛影院| 国产一区二区在线看| 亚洲男人的天堂在线观看| 欧美一区日韩一区| 成人av资源在线观看| 青青草成人在线观看| 国产精品女人毛片| 欧美一区二区三区色| av不卡一区二区三区| 日本不卡免费在线视频| 亚洲欧美一区二区三区极速播放| 日韩午夜电影av| 色噜噜狠狠色综合欧洲selulu| 精品一区二区三区在线播放视频| 亚洲美女淫视频| 久久久精品黄色| 欧美另类z0zxhd电影| 91亚洲精品久久久蜜桃网站| 蜜桃视频第一区免费观看| 亚洲柠檬福利资源导航| 国产欧美一区二区精品仙草咪|