etd.c
来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C语言 代码 · 共 644 行 · 第 1/2 页
C
644 行
LONG
elem_list_add_ref(PEHCI_ELEM_LIST plist)
{
plist->reference++;
return plist->reference;
}
LONG
elem_list_release_ref(PEHCI_ELEM_LIST plist)
{
plist->reference--;
return plist->reference;
}
LONG
elem_list_get_ref(PEHCI_ELEM_LIST plist)
{
return plist->reference;
}
//
// pool methods
//
BOOLEAN
elem_pool_init_pool(PEHCI_ELEM_POOL pool, LONG flags, PVOID context)
{
INIT_ELEM_LIST_CONTEXT init_ctx;
if (pool == NULL || context == NULL)
return FALSE;
RtlZeroMemory(pool, sizeof(EHCI_ELEM_POOL));
init_ctx.pool = pool;
init_ctx.padapter = context;
pool->elem_lists[0] = usb_alloc_mem(NonPagedPool, sizeof(EHCI_ELEM_LIST));
if (pool->elem_lists[0] == NULL)
return FALSE;
if (elem_list_init_elem_list(pool->elem_lists[0], flags, &init_ctx, 0) == FALSE)
{
usb_free_mem(pool->elem_lists[0]);
return FALSE;
}
pool->link_offset = pool->elem_lists[0]->get_link_offset(pool->elem_lists[0]);
pool->free_count = pool->elem_lists[0]->get_total_count(pool->elem_lists[0]);
pool->list_count = 1;
pool->flags = flags;
return TRUE;
}
LONG
elem_pool_get_link_offset(PEHCI_ELEM_POOL elem_pool)
{
return elem_pool->link_offset;
}
LONG
elem_pool_get_total_count(PEHCI_ELEM_POOL elem_pool)
{
return elem_pool->elem_lists[0]->get_total_count(elem_pool->elem_lists[0]) * elem_pool->list_count;
}
VOID
elem_pool_destroy_pool(PEHCI_ELEM_POOL pool)
{
LONG i;
if (pool == NULL)
return;
for(i = pool->list_count - 1; i >= 0; i--)
{
pool->elem_lists[i]->destroy_list(pool->elem_lists[i]);
usb_free_mem(pool->elem_lists[i]);
pool->elem_lists[i] = NULL;
}
RtlZeroMemory(pool, sizeof(EHCI_ELEM_POOL));
return;
}
PEHCI_ELEM_LINKS
elem_pool_alloc_elem(PEHCI_ELEM_POOL pool)
{
LONG i;
PEHCI_ELEM_LIST pel = NULL;
PLIST_HEAD lh;
PEHCI_ELEM_LINKS elnk;
if (pool == NULL)
return NULL;
for(i = 0; i < pool->list_count; i++)
{
pel = pool->elem_lists[i];
if (pel->get_ref(pel) == pel->get_total_count(pel))
continue;
break;
}
if (i == pool->list_count)
{
if (elem_pool_expand_pool(pool, pel->get_total_count(pel)) == FALSE)
return NULL;
pel = pool->elem_lists[i];
}
lh = pel->get_list_head(pel);
elnk = (PEHCI_ELEM_LINKS) RemoveHeadList(lh);
InitializeListHead(&elnk->elem_link);
InitializeListHead(&elnk->sched_link);
pel->add_ref(pel);
pool->free_count--;
return elnk;
}
VOID
elem_pool_free_elem(PEHCI_ELEM_LINKS elem_link)
{
PLIST_HEAD lh;
LONG ref;
PEHCI_ELEM_POOL pool;
if (elem_link == NULL)
return;
pool = elem_link->pool_link;
lh = elem_link->list_link->get_list_head(elem_link->list_link);
if (lh == NULL)
return;
InsertHeadList(lh, (PLIST_ENTRY) elem_link);
ref = elem_link->list_link->release_ref(elem_link->list_link);
pool->free_count++;
if (ref == 0)
elem_pool_collect_garbage(pool);
return;
}
BOOLEAN
elem_pool_is_empty(PEHCI_ELEM_POOL pool)
{
PEHCI_ELEM_LIST pel;
if (pool == NULL)
return TRUE;
pel = pool->elem_lists[0];
return (BOOLEAN) (pool->list_count == 1 && pool->free_count == pel->get_total_count(pel));
}
LONG
elem_pool_get_free_count(PEHCI_ELEM_POOL pool)
{
if (pool == NULL)
return 0;
return pool->free_count;
}
PEHCI_ELEM_LINKS
elem_pool_alloc_elems(PEHCI_ELEM_POOL pool, LONG count)
{
LIST_HEAD lh;
PLIST_ENTRY pthis;
LONG i, alloc_count, max_pool_lists;
PEHCI_ELEM_LIST pel;
PEHCI_ELEM_LINKS elnk;
// calculate to see if the count is affordable
if (pool == NULL || count <= 0)
return NULL;
get_max_lists_count(pool, max_pool_lists);
InitializeListHead(&lh);
pel = pool->elem_lists[0];
if (count <= pool->free_count)
alloc_count = 0;
else
alloc_count = count - pool->free_count;
if (alloc_count > pel->get_total_count(pel) * (max_pool_lists - pool->list_count))
return NULL;
for(i = 0; i < count; i++)
{
if ((elnk = elem_pool_alloc_elem(pool)) == NULL)
{
// undo what we have done
while (IsListEmpty(&lh) == FALSE)
{
pthis = RemoveHeadList(&lh);
elnk = struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link);
elem_pool_free_elem(elnk);
}
return NULL;
}
InsertTailList(&lh, &elnk->elem_link);
}
ListFirst(&lh, pthis);
elnk = struct_ptr(pthis, EHCI_ELEM_LINKS, elem_link);
RemoveEntryList(&lh);
return elnk;
}
BOOLEAN
elem_pool_free_elems(PEHCI_ELEM_LINKS elem_chains)
{
// note: no list head exists.
LIST_HEAD lh;
PEHCI_ELEM_LINKS elnk;
InsertTailList(&elem_chains->elem_link, &lh);
while (IsListEmpty(&lh) == FALSE)
{
elnk = (PEHCI_ELEM_LINKS) RemoveHeadList(&lh);
elem_pool_free_elem(elnk);
}
return TRUE;
}
LONG
elem_pool_get_type(PEHCI_ELEM_POOL pool)
{
if (pool == NULL)
return -1;
return (pool->flags & 0xf);
}
BOOLEAN
elem_pool_expand_pool(PEHCI_ELEM_POOL pool, LONG elem_count)
{
LONG elem_cnt_list, list_count, i, j;
INIT_ELEM_LIST_CONTEXT init_ctx;
if (pool == NULL || elem_count <= 0 || elem_count > EHCI_MAX_ELEMS_POOL)
return FALSE;
init_ctx.pool = pool;
init_ctx.padapter = pool->elem_lists[0]->padapter;
elem_cnt_list = pool->elem_lists[0]->get_total_count(pool->elem_lists[0]);
list_count = (elem_count + elem_cnt_list - 1) / elem_cnt_list;
get_max_lists_count(pool, i);
if (list_count + pool->list_count > i)
return FALSE;
for(i = pool->list_count; i < list_count + pool->list_count; i++)
{
pool->elem_lists[i] = usb_alloc_mem(NonPagedPool, sizeof(EHCI_ELEM_LIST));
if (elem_list_init_elem_list(pool->elem_lists[i], pool->flags, &init_ctx, 0) == FALSE)
break;
}
if (i < list_count + pool->list_count)
{
// undo all we have done
for(j = pool->list_count; j < pool->list_count + i; j++)
{
pool->elem_lists[j]->destroy_list(pool->elem_lists[j]);
usb_free_mem(pool->elem_lists[j]);
pool->elem_lists[j] = NULL;
}
return FALSE;
}
// update pool
pool->free_count += elem_cnt_list * list_count;
pool->list_count += list_count;
return TRUE;
}
BOOLEAN
elem_pool_collect_garbage(PEHCI_ELEM_POOL pool)
{
LONG i, j, k, fl;
LONG free_elem_lists[EHCI_MAX_LISTS_POOL - 1];
PEHCI_ELEM_LIST pel;
if (pool == NULL)
return FALSE;
for(i = 1, fl = 0; i < pool->list_count; i++)
{
if (pool->elem_lists[i]->get_ref(pool->elem_lists[i]) == 0)
{
free_elem_lists[fl++] = i;
}
}
for(j = fl - 1; j >= 0; j--)
{
pel = pool->elem_lists[free_elem_lists[j]];
pel->destroy_list(pel);
usb_free_mem(pel);
for(k = free_elem_lists[j] + 1; k < pool->list_count; k++)
{
// shrink the elem_lists
pool->elem_lists[k - 1] = pool->elem_lists[k];
}
pool->elem_lists[k] = NULL;
pel = pool->elem_lists[0];
pool->free_count -= pel->get_total_count(pel);
pool->list_count--;
}
return TRUE;
}
BOOLEAN
elem_pool_can_transfer(PEHCI_ELEM_POOL pool, LONG td_count)
{
LONG i;
if (pool == NULL || td_count <= 0)
return FALSE;
get_max_lists_count(pool, i);
if ((i - pool->list_count)
* pool->elem_lists[0]->get_total_count(pool->elem_lists[0]) + pool->free_count < td_count)
return FALSE;
return TRUE;
}
//----------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?