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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? ehci.c

?? ReactOS是一些高手根據Windows XP的內核編寫出的類XP。內核實現機理和API函數調用幾乎相同。甚至可以兼容XP的程序。喜歡研究系統內核的人可以看一看。
?? C
?? 第 1 頁 / 共 5 頁
字號:
    PUSB_DEV pdev, dest_dev;
    PSYNC_PARAM sync_param;
    PLIST_ENTRY pthis, pnext;
    LONG count;

    sync_param = (PSYNC_PARAM) context;
    dest_dev = (PUSB_DEV) sync_param->context;
    ehci = sync_param->ehci;

    if (ehci == NULL || dest_dev == NULL)
    {
        return (UCHAR) (sync_param->ret = FALSE);
    }
    count = 0;
    ListFirst(&ehci->urb_list, pthis);
    while (pthis)
    {
        pdev = dev_from_endp(((PURB) pthis)->pendp);
        if (pdev == dest_dev)
        {
            ((PURB) pthis)->flags |= URB_FLAG_FORCE_CANCEL;
        }
        ListNext(&ehci->urb_list, pthis, pnext);
        pthis = pnext;
        count++;
    }

    if (count)
    {
        // signal an int for further process
        press_doorbell(ehci);
    }
    return (UCHAR) (sync_param->ret = TRUE);
}

BOOLEAN
ehci_remove_device(PEHCI_DEV ehci, PUSB_DEV dev)
{
    PUHCI_PENDING_ENDP ppending_endp;
    PLIST_ENTRY pthis, pnext;
    PURB purb;
    LIST_HEAD temp_list;
    int i, j, k;
    SYNC_PARAM sync_param;

    USE_BASIC_IRQL;

    if (ehci == NULL || dev == NULL)
        return FALSE;

    InitializeListHead(&temp_list);

    //free pending endp that has purb queued from pending endp list
    lock_pending_endp_list(&ehci->pending_endp_list_lock);

    ListFirst(&ehci->pending_endp_list, pthis);

    while (pthis)
    {
        ppending_endp = (PUHCI_PENDING_ENDP) pthis;
        ListNext(&ehci->pending_endp_list, pthis, pnext);
        if (dev_from_endp(ppending_endp->pendp) == dev)
        {
            RemoveEntryList(pthis);
            free_pending_endp(&ehci->pending_endp_pool, struct_ptr(pthis, UHCI_PENDING_ENDP, endp_link));
        }
        pthis = pnext;
    }
    unlock_pending_endp_list(&ehci->pending_endp_list_lock);

    //cancel all the urbs in the purb-list
    sync_param.ehci = ehci;
    sync_param.context = (PVOID) dev;

    KeSynchronizeExecution(ehci->pdev_ext->ehci_int, ehci_sync_cancel_urbs_dev, &sync_param);

    //cancel all the purb in the endp's purb-list
    k = 0;
    lock_dev(dev, FALSE);
    if (dev->usb_config)
    {
        //only for configed dev 
        for(i = 0; i < dev->usb_config->if_count; i++)
        {
            for(j = 0; j < dev->usb_config->interf[i].endp_count; j++)
            {
                ListFirst(&dev->usb_config->interf[i].endp[j].urb_list, pthis);
                while (pthis)
                {
                    ListNext(&dev->usb_config->interf[i].endp[j].urb_list, pthis, pnext);

                    RemoveEntryList(pthis);
                    InsertHeadList(&temp_list, pthis);
                    pthis = pnext;
                    k++;
                }

            }
        }
    }
    ListFirst(&dev->default_endp.urb_list, pthis);

    while (pthis)
    {
        ListNext(&dev->default_endp.urb_list, pthis, pnext);

        RemoveEntryList(pthis);
        InsertHeadList(&temp_list, pthis);
        pthis = pnext;
        k++;
    }
    unlock_dev(dev, FALSE);

    if (IsListEmpty(&temp_list) == FALSE)
    {
        for(i = 0; i < k; i++)
        {
            //complete those urbs with error
            pthis = RemoveHeadList(&temp_list);
            purb = (PURB) pthis;
            purb->status = STATUS_DEVICE_DOES_NOT_EXIST;
            {
                ehci_generic_urb_completion(purb, purb->context);
            }
        }
    }

    lock_dev(dev, FALSE) dev->ref_count -= k;
    unlock_dev(dev, FALSE);

    return TRUE;
}

static BOOLEAN
ehci_insert_urb_schedule(PEHCI_DEV ehci, PURB purb)
// must have dev_lock( ehci_process_pending_endp ) and frame_list_lock acquired
{
    PURB_HS_PIPE_CONTENT pipe_content;

    if (ehci == NULL || purb == NULL)
        return FALSE;

    pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
    switch (pipe_content->trans_type)
    {
        case USB_ENDPOINT_XFER_CONTROL:
            ehci_insert_control_schedule(ehci, purb);
            break;
        case USB_ENDPOINT_XFER_BULK:
            ehci_insert_bulk_schedule(ehci, purb);
            break;
        case USB_ENDPOINT_XFER_INT:
            ehci_insert_int_schedule(ehci, purb);
            break;
        case USB_ENDPOINT_XFER_ISOC:
            ehci_insert_iso_schedule(ehci, purb);
            break;
        default:
            return FALSE;
    }

    purb->flags &= ~URB_FLAG_STATE_MASK;
    purb->flags |= URB_FLAG_STATE_IN_PROCESS | URB_FLAG_IN_SCHEDULE;
    InsertTailList(&ehci->urb_list, (PLIST_ENTRY) purb);

    return TRUE;
}

static BOOLEAN
ehci_insert_tds_qh(PEHCI_DEV ehci, PEHCI_QH pqh, PEHCI_QTD td_chain)
{
    if (pqh == NULL || td_chain == NULL)
        return FALSE;

    UNREFERENCED_PARAMETER(ehci);

    ehci_copy_overlay((PEHCI_QH_CONTENT) pqh, (PEHCI_QTD_CONTENT) td_chain);
    InsertTailList(&td_chain->elem_head_link->elem_link, &pqh->elem_head_link->elem_link);
    return TRUE;
}

static BOOLEAN
ehci_insert_qh_urb(PURB purb, PEHCI_QH pqh)
{
    PLIST_ENTRY pthis, pnext;
    if (pqh == NULL || purb == NULL)
        return FALSE;

    InsertTailList(&pqh->elem_head_link->elem_link, &purb->trasac_list);
    ListFirst(&purb->trasac_list, pthis) while (pthis)
    {
        // note: fstn may in this chain
        struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link)->purb = purb;
        ListNext(&purb->trasac_list, pthis, pnext);
        pthis = pnext;
    }
    return TRUE;
}

#define calc_td_count( pURB, start_aDDR, td_coUNT ) \
{\
	LONG i, j, k;\
	td_coUNT = 0;\
	k = ( ( pURB )->bytes_to_transfer + max_packet_size - 1 ) / max_packet_size;\
	if( k != 0 )\
	{\
		LONG packets_per_td, packets_per_page;\
		packets_per_td = EHCI_QTD_MAX_TRANS_SIZE / max_packet_size;\
		packets_per_page = PAGE_SIZE / max_packet_size;\
		i = ( ( LONG )&( pURB )->data_buffer[ ( start_aDDR ) ] ) & ( PAGE_SIZE - 1 );\
		if( i )\
		{\
			i = PAGE_SIZE - i;\
			j = i & ( max_packet_size - 1 );\
			k -= ( EHCI_QTD_MAX_TRANS_SIZE - PAGE_SIZE + i - j ) / max_packet_size;\
			if( k < 0 )\
				td_coUNT = 1;\
			else\
			{\
				if( j )\
					i = packets_per_td - packets_per_page;\
				else\
					i = packets_per_td;\
				td_coUNT = 1 + ( k + i - 1 ) / i; \
			}\
		}\
		else\
		{\
			td_coUNT = ( k + packets_per_td - 1 ) / packets_per_td;\
		}\
	}\
}

static BOOLEAN
ehci_fill_td_buf_ptr(PURB purb, LONG start_addr,        // start idx into purb->data_buffer
                     PLIST_ENTRY td_list, LONG td_count, ULONG toggle)
// fill the tds' bytes_to_transfer and hw_buf, return next toggle value: true 1, false 0
{
    LONG i, j, k, data_load;
    LONG packets_per_td, packets_per_page, bytes_to_transfer, max_packet_size;
    PLIST_ENTRY pthis, pnext;
    PEHCI_QTD_CONTENT ptdc;
    PEHCI_QTD ptd;
    PVOID ptr;

    if (purb == NULL || td_list == NULL || td_count == 0)
        return toggle;

    max_packet_size = 1 << ((PURB_HS_PIPE_CONTENT) & purb->pipe)->max_packet_size;
    packets_per_td = EHCI_QTD_MAX_TRANS_SIZE / max_packet_size;
    packets_per_page = PAGE_SIZE / max_packet_size;

    pthis = td_list;
    bytes_to_transfer = purb->bytes_to_transfer;

    i = ((LONG) & (purb)->data_buffer[(start_addr)]) & (PAGE_SIZE - 1);
    if (i)
    {
        i = PAGE_SIZE - i;
        j = i & (max_packet_size - 1);
    }
    else
    {
        i = j = 0;
    }

    while (bytes_to_transfer)
    {
        ptd = qtd_from_list_entry(pthis);
        ptd->hw_buf[0] = MmGetPhysicalAddress(&purb->data_buffer[start_addr]).LowPart;
        ptdc = (PEHCI_QTD_CONTENT) ptd;

        if (i != 0)
        {
            data_load = (LONG) (EHCI_QTD_MAX_TRANS_SIZE - PAGE_SIZE + i - j) < bytes_to_transfer
                ? (LONG) (EHCI_QTD_MAX_TRANS_SIZE - PAGE_SIZE + i - j) : bytes_to_transfer;

            ptdc->bytes_to_transfer = (USHORT) data_load;
            ptd->bytes_to_transfer = (USHORT) data_load;

            // subtract the header part
            data_load -= (i < data_load ? i : data_load);

            for(k = 1; data_load > 0; k++)
            {
                ptr = &purb->data_buffer[start_addr + i + (k - 1) * PAGE_SIZE];
                ptr = (PVOID) (((ULONG) ptr) & ~(PAGE_SIZE - 1));
                ptd->hw_buf[k] = MmGetPhysicalAddress(ptr).LowPart;
                data_load -= PAGE_SIZE < data_load ? PAGE_SIZE : data_load;
            }
        }
        else
        {
            // aligned on page boundary
            data_load = EHCI_QTD_MAX_TRANS_SIZE < bytes_to_transfer
                ? EHCI_QTD_MAX_TRANS_SIZE : bytes_to_transfer;

            ptdc->bytes_to_transfer = (USHORT) data_load;
            ptd->bytes_to_transfer = (USHORT) data_load;

            data_load -= (PAGE_SIZE < data_load ? PAGE_SIZE : data_load);

            for(k = 1; data_load > 0; k++)
            {
                ptr = &purb->data_buffer[start_addr + k * PAGE_SIZE];
                ptr = (PVOID) (((ULONG) ptr) & ~(PAGE_SIZE - 1));
                ptd->hw_buf[k] = MmGetPhysicalAddress(ptr).LowPart;
                data_load -= PAGE_SIZE < data_load ? PAGE_SIZE : data_load;
            }
        }
        ptdc->data_toggle = toggle;
        if (((ptdc->bytes_to_transfer + max_packet_size - 1) / max_packet_size) & 1)
        {
            //only odd num of transactions has effect
            toggle ^= 1;
        }
        start_addr += ptdc->bytes_to_transfer;
        bytes_to_transfer -= ptdc->bytes_to_transfer;
        ListNext(td_list, pthis, pnext);
        pthis = pnext;
        i = j;
    }
    return toggle;
}

static NTSTATUS
ehci_internal_submit_bulk(PEHCI_DEV ehci, PURB purb)
//
// assume that the purb has its rest_bytes and bytes_to_transfer set
// and bytes_transfered is zeroed.
// dev_lock must be acquired outside
// purb comes from dev's endpoint purb-list. it is already removed from
// the endpoint purb-list.
//
{

    LONG max_packet_size, td_count, offset, bytes_to_transfer;
    PBYTE start_addr;
    PEHCI_QTD ptd;
    PEHCI_QH pqh;
    LIST_ENTRY td_list, *pthis, *pnext;
    BOOLEAN old_toggle, toggle, ret;
    UCHAR pid;
    LONG i, j;
    PURB_HS_PIPE_CONTENT pipe_content;
    PEHCI_QTD_CONTENT ptdc;
    PEHCI_QH_CONTENT pqhc;
    PEHCI_ELEM_LINKS pelnk;

    if (ehci == NULL || purb == NULL)
        return STATUS_INVALID_PARAMETER;

    max_packet_size = endp_max_packet_size(purb->pendp);
    if (purb->bytes_to_transfer == 0)
    {
        return STATUS_INVALID_PARAMETER;
    }

    start_addr = &purb->data_buffer[purb->data_length - purb->rest_bytes];
    calc_td_count(purb, purb->data_length - purb->rest_bytes, td_count);

    elem_pool_lock(qtd_pool, TRUE);
    pelnk = elem_pool_alloc_elems(qtd_pool, td_count);
    elem_pool_unlock(qtd_pool, TRUE);

    if (pelnk == NULL)
    {
        return STATUS_UNSUCCESSFUL;
    }
    ptd = (PEHCI_QTD) ((ULONG) pelnk->phys_part & PHYS_PART_ADDR_MASK);

    InitializeListHead(&td_list);
    InsertTailList(&ptd->elem_head_link->elem_link, &td_list);

    ListFirst(&td_list, pthis);
    ListNext(&td_list, pthis, pnext);

    offset = 0;

    old_toggle = toggle = (purb->pendp->flags & USB_ENDP_FLAG_DATATOGGLE) ? TRUE : FALSE;
    bytes_to_transfer = purb->bytes_to_transfer;
    ehci_dbg_print(DBGLVL_MAXIMUM, ("ehci_internal_submit_bulk():dev toggle=%d\n", toggle));

    for(i = 1; i < 16; i++)
    {
        if ((max_packet_size >> i) == 0)
            break;
    }
    i--;
    i &= 0xf;

    purb->pipe = 0;
    pipe_content = (PURB_HS_PIPE_CONTENT) & purb->pipe;
    pipe_content->max_packet_size = i;
    pipe_content->endp_addr = endp_num(purb->pendp);
    pipe_content->dev_addr = dev_from_endp(purb->pendp)->dev_addr;
    pipe_content->trans_dir = endp_dir(purb->pendp);
    pipe_content->trans_type = USB_ENDPOINT_XFER_BULK;
    pipe_content->data_toggle = toggle;
    pipe_content->speed_high = (dev_from_endp(purb->pendp)->flags & USB_DEV_FLAG_HIGH_SPEED) ? 1 : 0;
    pipe_content->speed_low = (dev_from_endp(purb->pendp)->flags & USB_DEV_FLAG_LOW_SPEED) ? 1 : 0;

    pid = (((ULONG) purb->pendp->pusb_endp_desc->bEndpointAddress & USB_DIR_IN) ? QTD_PID_IN : QTD_PID_OUT);

    i = ((ULONG) start_addr) & (PAGE_SIZE - 1); // header part within first page
    if (i)
    {

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品亚洲综合一区在线观看| 青青草国产精品97视觉盛宴| 国产午夜久久久久| 亚洲精品国产视频| 国产成人午夜片在线观看高清观看| 五月婷婷久久综合| 99久久国产免费看| 精品理论电影在线观看| 亚洲美女屁股眼交| 国产99久久久久| 日韩欧美资源站| 亚洲国产综合色| 成人国产精品免费观看动漫| 欧美成人一区二区三区| 午夜精品影院在线观看| 色综合久久99| 国产精品白丝在线| 国产成人在线视频网站| 日韩精品影音先锋| 中文字幕一区在线观看| 久久久久久久久久看片| 丰满少妇在线播放bd日韩电影| 精品一区精品二区高清| 欧美三区免费完整视频在线观看| 欧美在线免费播放| 亚洲国产精品人人做人人爽| 国产精品一区二区久激情瑜伽| 成人国产精品免费网站| 久久精品免视看| 国产成人精品亚洲777人妖 | 欧美中文字幕一区| 亚洲婷婷国产精品电影人久久| 一区二区三区av电影 | 欧美国产欧美综合| 黄色资源网久久资源365| 欧美一级高清大全免费观看| 日本不卡一区二区三区| 日韩精品在线网站| 精品影院一区二区久久久| 欧美精品一区二区三区久久久| 欧美国产丝袜视频| 不卡视频在线观看| 中文字幕日本不卡| 在线精品视频一区二区| 亚洲精品高清在线| 色偷偷成人一区二区三区91| 亚洲一区二区三区影院| 制服丝袜中文字幕一区| 国内一区二区视频| 欧美激情一区在线| 欧美亚洲精品一区| 美女视频黄久久| 国产欧美久久久精品影院| 91美女福利视频| 日韩主播视频在线| 337p日本欧洲亚洲大胆色噜噜| 亚洲欧洲精品一区二区三区 | 中文幕一区二区三区久久蜜桃| 一区二区在线看| 欧美日韩精品系列| 国产精品主播直播| 一区二区三区在线免费观看 | 日韩不卡一区二区三区| 欧美mv日韩mv国产| 成人一区二区三区| 久久欧美中文字幕| 6080午夜不卡| 国产专区综合网| 亚洲色图欧美在线| 欧美一区二区视频网站| 国产a精品视频| 亚洲欧洲制服丝袜| 精品日产卡一卡二卡麻豆| 波波电影院一区二区三区| 亚洲午夜久久久久久久久电影院| 国产91丝袜在线播放九色| 国产精品国产三级国产普通话99| 青青青爽久久午夜综合久久午夜| 色综合久久99| 久草在线在线精品观看| 亚洲精品免费在线| 久久―日本道色综合久久| 欧美性视频一区二区三区| 国产成人精品午夜视频免费| 亚洲国产日韩av| 国产精品久久午夜夜伦鲁鲁| 欧美一区二区三区小说| 一本一道波多野结衣一区二区| 国产精品大尺度| 欧美精品一区二区三区在线播放 | 欧美国产乱子伦| 91精选在线观看| 91免费在线播放| 国产麻豆成人精品| 成人午夜免费视频| 精品亚洲国产成人av制服丝袜| 欧美大片拔萝卜| 欧美四级电影网| 色呦呦网站一区| voyeur盗摄精品| 国产福利一区二区三区视频| 日韩av电影天堂| 午夜国产精品一区| 一区二区成人在线| 亚洲精品国产一区二区精华液 | 国产成人在线视频免费播放| 人人爽香蕉精品| 亚洲.国产.中文慕字在线| 中文字幕av在线一区二区三区| 色综合天天综合网国产成人综合天 | 高清不卡在线观看| 国产一区二区调教| 黄页网站大全一区二区| 免费在线观看视频一区| 视频一区视频二区中文字幕| 亚洲国产精品一区二区久久 | 欧美精品一卡二卡| 色噜噜狠狠色综合中国| 91免费小视频| 日韩精品自拍偷拍| 欧美三级中文字幕在线观看| 色噜噜狠狠色综合中国| 亚洲网友自拍偷拍| 欧美激情在线看| 香蕉久久夜色精品国产使用方法 | 精品国产免费一区二区三区四区| 国产成人综合自拍| 精品中文字幕一区二区小辣椒| 国产精品久久网站| 亚洲欧洲美洲综合色网| 国产精品不卡一区二区三区| 国产精品日日摸夜夜摸av| 亚洲乱码国产乱码精品精可以看| 精品国产伦一区二区三区观看方式| 成人av在线播放网址| 色婷婷综合激情| 色88888久久久久久影院野外| 久久99热国产| 国产成人精品综合在线观看| 99亚偷拍自图区亚洲| 欧美亚洲一区二区三区四区| 欧美美女视频在线观看| 日韩久久久精品| 中文字幕一区不卡| 午夜精品久久久| 黑人巨大精品欧美一区| www.色精品| 欧美视频三区在线播放| 精品国产乱码久久久久久浪潮 | 高清成人在线观看| 国产成人激情av| 91久久线看在观草草青青| 欧美精品乱人伦久久久久久| 欧美一区二区在线观看| 久久精品欧美一区二区三区麻豆| 欧美视频一区在线| 久久久久久久久一| 亚洲成年人影院| 久久99久久99| 日本韩国精品在线| 亚洲精品一区二区三区香蕉| 亚洲天堂网中文字| 日产国产高清一区二区三区| 成人综合婷婷国产精品久久蜜臀 | 亚洲va欧美va人人爽| 国产一区二区三区最好精华液| 日本一道高清亚洲日美韩| 国产馆精品极品| 7777精品伊人久久久大香线蕉经典版下载| 成人性生交大片| 欧美浪妇xxxx高跟鞋交| 久久久久97国产精华液好用吗| 亚洲精品在线观看网站| 一区二区三区久久| 国产精品亚洲午夜一区二区三区| 久久精品国产精品亚洲综合| 色婷婷精品久久二区二区蜜臂av| 成人av资源站| 精品国产乱码久久久久久闺蜜| 欧美精品三级日韩久久| 中文字幕在线免费不卡| 国内精品在线播放| 91精品国产全国免费观看| 亚洲精品成人a在线观看| 国产精品一区专区| 精品久久一二三区| 日韩高清国产一区在线| 欧美色图片你懂的| 一区二区三区日韩精品视频| 成人在线综合网| 国产三级一区二区| 九色|91porny| 91精品中文字幕一区二区三区| 91久久精品一区二区三| 国产精品乱人伦一区二区| 国产成人h网站| 国产欧美久久久精品影院| 国产成人激情av| 国产精品一二三| 亚洲va天堂va国产va久|