- Unmess header files a little - create one header file (usbdriver.h) which includes all other needed headers, also splitting a bit.

Also split out the roothub driver and device manager from hub.c (which was over 4500 SLOC)
- Enable PCH usage
- Reduced a few warnings

svn path=/trunk/; revision=23668
This commit is contained in:
Aleksey Bragin 2006-08-23 12:36:08 +00:00
parent edaf50a0e7
commit 7ad1947410
26 changed files with 1746 additions and 1769 deletions

View file

@ -19,14 +19,7 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <ntddk.h>
#include "debug.h"
#include "usb.h"
#include "umss.h"
// ULONG_PTR defining hack, to use ntddsci.h from reactos
//FIXME: Move to a header file later
typedef unsigned long ULONG_PTR, *PULONG_PTR;
#include "usbdriver.h"
#include <ntddscsi.h>
#define OLYMPUS_CSW( pdev_EXT, staTUS ) \

View file

@ -19,18 +19,12 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <ntddk.h>
#include "debug.h"
#include "umss.h"
#include "usbdriver.h"
VOID umss_cbi_send_adsc_complete(PURB purb, PVOID context);
VOID umss_cbi_transfer_data(PUMSS_DEVICE_EXTENSION pdev_ext);
VOID umss_cbi_get_status(PUMSS_DEVICE_EXTENSION pdev_ext);
VOID umss_cbi_transfer_data_complete(PURB purb, PVOID context);
VOID umss_cbi_get_status_complete(PURB purb, PVOID context);
NTSTATUS

View file

@ -20,22 +20,12 @@
*/
//this driver is part of the dev manager responsible to manage if device
#include "td.h"
#include "ntddk.h"
#include "umss.h"
#include "usb.h"
#include "hub.h"
#include "debug.h"
#include "usbdriver.h"
VOID compdev_set_cfg_completion(PURB purb, PVOID context);
VOID compdev_select_driver(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
BOOL compdev_connect(PCONNECT_DATA param, DEV_HANDLE dev_handle);
BOOL compdev_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
BOOL compdev_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
BOOL

View file

@ -0,0 +1,742 @@
/**
* devmgr.c - USB driver stack project for Windows NT 4.0
*
* Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program (in the main directory of the distribution, the file
* COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "usbdriver.h"
//----------------------------------------------------------
USB_DRIVER g_driver_list[DEVMGR_MAX_DRIVERS];
USB_DEV_MANAGER g_dev_mgr;
//----------------------------------------------------------
BOOL
dev_mgr_set_if_driver(PUSB_DEV_MANAGER dev_mgr,
DEV_HANDLE if_handle,
PUSB_DRIVER pdriver,
PUSB_DEV pdev //if pdev != NULL, we use pdev instead if_handle, and must have dev_lock acquired.
)
{
ULONG i;
USE_BASIC_NON_PENDING_IRQL;
if (dev_mgr == NULL || if_handle == 0 || pdriver == NULL)
return FALSE;
i = if_idx_from_handle(if_handle);
if (pdev != NULL)
{
if (dev_state(pdev) < USB_DEV_STATE_BEFORE_ZOMB)
{
pdev->usb_config->interf[i].pif_drv = pdriver;
return TRUE;
}
return FALSE;
}
if (usb_query_and_lock_dev(dev_mgr, if_handle, &pdev) != STATUS_SUCCESS)
return FALSE;
lock_dev(pdev, TRUE);
if (dev_state(pdev) != USB_DEV_STATE_ZOMB)
{
pdev->usb_config->interf[i].pif_drv = pdriver;
}
unlock_dev(pdev, TRUE);
usb_unlock_dev(pdev);
return TRUE;
}
BOOL
dev_mgr_set_driver(PUSB_DEV_MANAGER dev_mgr,
DEV_HANDLE dev_handle,
PUSB_DRIVER pdriver,
PUSB_DEV pdev //if pdev != NULL, we use pdev instead if_handle
)
{
USE_BASIC_NON_PENDING_IRQL;
if (dev_mgr == NULL || dev_handle == 0 || pdriver == NULL)
return FALSE;
if (pdev != NULL)
{
if (dev_state(pdev) < USB_DEV_STATE_BEFORE_ZOMB)
{
pdev->dev_driver = pdriver;
return TRUE;
}
return FALSE;
}
if (usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev) != STATUS_SUCCESS)
return FALSE;
lock_dev(pdev, FALSE);
if (dev_state(pdev) < USB_DEV_STATE_BEFORE_ZOMB)
{
pdev->dev_driver = pdriver;
}
unlock_dev(pdev, FALSE);
usb_unlock_dev(pdev);
return TRUE;
}
BOOL
dev_mgr_post_event(PUSB_DEV_MANAGER dev_mgr, PUSB_EVENT event)
{
KIRQL old_irql;
if (dev_mgr == NULL || event == NULL)
return FALSE;
KeAcquireSpinLock(&dev_mgr->event_list_lock, &old_irql);
InsertTailList(&dev_mgr->event_list, &event->event_link);
KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
KeSetEvent(&dev_mgr->wake_up_event, 0, FALSE);
return TRUE;
}
VOID
dev_mgr_driver_entry_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdrvr)
{
// Device Info
RtlZeroMemory(pdrvr, sizeof(USB_DRIVER) * DEVMGR_MAX_DRIVERS);
pdrvr[RH_DRIVER_IDX].driver_init = rh_driver_init; // in fact, this routine will init the rh device rather that the driver struct.
pdrvr[RH_DRIVER_IDX].driver_destroy = rh_driver_destroy; // we do not need rh to destroy currently, since that may means fatal hardware failure
pdrvr[HUB_DRIVER_IDX].driver_init = hub_driver_init; //no need, since dev_mgr is also a hub driver
pdrvr[HUB_DRIVER_IDX].driver_destroy = hub_driver_destroy;
pdrvr[UMSS_DRIVER_IDX].driver_init = umss_if_driver_init;
pdrvr[UMSS_DRIVER_IDX].driver_destroy = umss_if_driver_destroy;
pdrvr[COMP_DRIVER_IDX].driver_init = compdev_driver_init;
pdrvr[COMP_DRIVER_IDX].driver_destroy = compdev_driver_destroy;
pdrvr[GEN_DRIVER_IDX].driver_init = gendrv_driver_init;
pdrvr[GEN_DRIVER_IDX].driver_destroy = gendrv_driver_destroy;
pdrvr[GEN_IF_DRIVER_IDX].driver_init = gendrv_if_driver_init;
pdrvr[GEN_IF_DRIVER_IDX].driver_destroy = gendrv_if_driver_destroy;
}
BOOL
dev_mgr_strobe(PUSB_DEV_MANAGER dev_mgr)
{
PUSB_EVENT pevent;
HANDLE thread_handle;
if (dev_mgr == NULL)
return FALSE;
if (dev_mgr->hcd_count == 0)
return FALSE;
dev_mgr->term_flag = FALSE;
if (dev_mgr->hcd_count == 0)
return FALSE;
KeInitializeSpinLock(&dev_mgr->event_list_lock);
InitializeListHead(&dev_mgr->event_list);
init_event_pool(&dev_mgr->event_pool);
pevent = alloc_event(&dev_mgr->event_pool, 1);
if (pevent == NULL)
{
destroy_event_pool(&dev_mgr->event_pool);
return FALSE;
}
pevent->flags = USB_EVENT_FLAG_ACTIVE;
pevent->event = USB_EVENT_INIT_DEV_MGR;
pevent->process_queue = event_list_default_process_queue;
pevent->process_event = dev_mgr_event_init;
pevent->context = (ULONG) dev_mgr;
KeInitializeEvent(&dev_mgr->wake_up_event, SynchronizationEvent, FALSE);
InsertTailList(&dev_mgr->event_list, &pevent->event_link);
if (PsCreateSystemThread(&thread_handle, 0, NULL, NULL, NULL, dev_mgr_thread, dev_mgr) != STATUS_SUCCESS)
{
destroy_event_pool(&dev_mgr->event_pool);
return FALSE;
}
ObReferenceObjectByHandle(thread_handle,
THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID *) & dev_mgr->pthread, NULL);
ZwClose(thread_handle);
return TRUE;
}
BOOL
dev_mgr_event_init(PUSB_DEV pdev, //always null. we do not use this param
ULONG event, ULONG context, ULONG param)
{
LARGE_INTEGER due_time;
PUSB_DEV_MANAGER dev_mgr;
LONG i;
usb_dbg_print(DBGLVL_MAXIMUM, ("dev_mgr_event_init(): dev_mgr=0x%x, event=0x%x\n", context, event));
dev_mgr = (PUSB_DEV_MANAGER) context;
if (dev_mgr == NULL)
return FALSE;
if (event != USB_EVENT_INIT_DEV_MGR)
return FALSE;
//dev_mgr->root_hub = NULL;
KeInitializeTimer(&dev_mgr->dev_mgr_timer);
KeInitializeDpc(&dev_mgr->dev_mgr_timer_dpc, dev_mgr_timer_dpc_callback, (PVOID) dev_mgr);
KeInitializeSpinLock(&dev_mgr->timer_svc_list_lock);
InitializeListHead(&dev_mgr->timer_svc_list);
init_timer_svc_pool(&dev_mgr->timer_svc_pool);
dev_mgr->timer_click = 0;
init_irp_list(&dev_mgr->irp_list);
KeInitializeSpinLock(&dev_mgr->dev_list_lock);
InitializeListHead(&dev_mgr->dev_list);
dev_mgr->hub_count = 0;
InitializeListHead(&dev_mgr->hub_list);
dev_mgr->conn_count = 0;
dev_mgr->driver_list = g_driver_list;
dev_mgr_driver_entry_init(dev_mgr, dev_mgr->driver_list);
for(i = 0; i < DEVMGR_MAX_DRIVERS; i++)
{
if (dev_mgr->driver_list[i].driver_init == NULL)
continue;
if (dev_mgr->driver_list[i].driver_init(dev_mgr, &dev_mgr->driver_list[i]) == FALSE)
break;
}
if (i == DEVMGR_MAX_DRIVERS)
{
due_time.QuadPart = -(DEV_MGR_TIMER_INTERVAL_NS - 10);
KeSetTimerEx(&dev_mgr->dev_mgr_timer,
due_time, DEV_MGR_TIMER_INTERVAL_MS, &dev_mgr->dev_mgr_timer_dpc);
return TRUE;
}
i--;
for(; i >= 0; i--)
{
if (dev_mgr->driver_list[i].driver_destroy)
dev_mgr->driver_list[i].driver_destroy(dev_mgr, &dev_mgr->driver_list[i]);
}
KeCancelTimer(&dev_mgr->dev_mgr_timer);
KeRemoveQueueDpc(&dev_mgr->dev_mgr_timer_dpc);
return FALSE;
}
VOID
dev_mgr_destroy(PUSB_DEV_MANAGER dev_mgr)
{
LONG i;
// oops...
KeCancelTimer(&dev_mgr->dev_mgr_timer);
KeRemoveQueueDpc(&dev_mgr->dev_mgr_timer_dpc);
for(i = DEVMGR_MAX_DRIVERS - 1; i >= 0; i--)
dev_mgr->driver_list[i].driver_destroy(dev_mgr, &dev_mgr->driver_list[i]);
destroy_irp_list(&dev_mgr->irp_list);
destroy_timer_svc_pool(&dev_mgr->timer_svc_pool);
destroy_event_pool(&dev_mgr->event_pool);
}
VOID
dev_mgr_thread(PVOID context)
{
PUSB_DEV_MANAGER dev_mgr;
PUSB_EVENT pevent;
PLIST_ENTRY pthis, pnext;
USB_EVENT usb_event;
LARGE_INTEGER time_out;
NTSTATUS status;
BOOL dev_mgr_inited;
KIRQL old_irql;
LONG i;
dev_mgr = (PUSB_DEV_MANAGER) context;
dev_mgr_inited = FALSE;
usb_cal_cpu_freq();
time_out.u.LowPart = (10 * 1000 * 1000) * 100 - 1; //1 minutes
time_out.u.HighPart = 0;
time_out.QuadPart = -time_out.QuadPart;
//usb_dbg_print( DBGLVL_MAXIMUM + 1, ( "dev_mgr_thread(): current uhci status=0x%x\n", uhci_status( dev_mgr->pdev_ext->uhci ) ) );
while (dev_mgr->term_flag == FALSE)
{
KeAcquireSpinLock(&dev_mgr->event_list_lock, &old_irql);
if (IsListEmpty(&dev_mgr->event_list) == TRUE)
{
KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
status = KeWaitForSingleObject(&dev_mgr->wake_up_event, Executive, KernelMode, TRUE, &time_out);
continue;
}
// usb_dbg_print( DBGLVL_MAXIMUM, ( "dev_mgr_thread(): current element in event list is 0x%x\n", \
// dbg_count_list( &dev_mgr->event_list ) ) );
dev_mgr_inited = TRUE; //since we have post one event, if this statement is executed, dev_mgr_event_init must be called sometime later or earlier
ListFirst(&dev_mgr->event_list, pthis);
pevent = struct_ptr(pthis, USB_EVENT, event_link);
while (pevent && ((pevent->flags & USB_EVENT_FLAG_ACTIVE) == 0))
{
//skip inactive ones
ListNext(&dev_mgr->event_list, &pevent->event_link, pnext);
pevent = struct_ptr(pnext, USB_EVENT, event_link);
}
if (pevent != NULL)
{
if (pevent->process_queue == NULL)
pevent->process_queue = event_list_default_process_queue;
pevent->process_queue(&dev_mgr->event_list, &dev_mgr->event_pool, pevent, &usb_event);
}
else
{
//no active event
KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
status = KeWaitForSingleObject(&dev_mgr->wake_up_event, Executive, KernelMode, TRUE, &time_out // 10 minutes
);
usb_dbg_print(DBGLVL_MAXIMUM, ("dev_mgr_thread(): wake up, reason=0x%x\n", status));
continue;
}
KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
if (usb_event.process_event)
{
usb_event.process_event(usb_event.pdev, usb_event.event, usb_event.context, usb_event.param);
}
else
{
event_list_default_process_event(usb_event.pdev,
usb_event.event, usb_event.context, usb_event.param);
}
}
if (dev_mgr_inited)
{
for(i = 0; i < dev_mgr->hcd_count; i++)
dev_mgr_disconnect_dev(dev_mgr->hcd_array[i]->hcd_get_root_hub(dev_mgr->hcd_array[i]));
dev_mgr_destroy(dev_mgr);
}
PsTerminateSystemThread(0);
}
VOID
dev_mgr_timer_dpc_callback(PKDPC Dpc, PVOID context, PVOID SystemArgument1, PVOID SystemArgument2)
{
PUSB_DEV_MANAGER dev_mgr;
LIST_HEAD templist;
PLIST_ENTRY pthis, pnext;
static ULONG ticks = 0;
ticks++;
dev_mgr = (PUSB_DEV_MANAGER) context;
if (dev_mgr == NULL)
return;
dev_mgr->timer_click++;
InitializeListHead(&templist);
KeAcquireSpinLockAtDpcLevel(&dev_mgr->timer_svc_list_lock);
if (IsListEmpty(&dev_mgr->timer_svc_list) == TRUE)
{
KeReleaseSpinLockFromDpcLevel(&dev_mgr->timer_svc_list_lock);
return;
}
ListFirst(&dev_mgr->timer_svc_list, pthis);
while (pthis)
{
((PTIMER_SVC) pthis)->counter++;
ListNext(&dev_mgr->timer_svc_list, pthis, pnext);
if (((PTIMER_SVC) pthis)->counter >= ((PTIMER_SVC) pthis)->threshold)
{
RemoveEntryList(pthis);
InsertTailList(&templist, pthis);
}
pthis = pnext;
}
KeReleaseSpinLockFromDpcLevel(&dev_mgr->timer_svc_list_lock);
while (IsListEmpty(&templist) == FALSE)
{
pthis = RemoveHeadList(&templist);
((PTIMER_SVC) pthis)->func(((PTIMER_SVC) pthis)->pdev, (PVOID) ((PTIMER_SVC) pthis)->context);
KeAcquireSpinLockAtDpcLevel(&dev_mgr->timer_svc_list_lock);
free_timer_svc(&dev_mgr->timer_svc_pool, (PTIMER_SVC) pthis);
KeReleaseSpinLockFromDpcLevel(&dev_mgr->timer_svc_list_lock);
}
}
BOOL
dev_mgr_request_timer_svc(PUSB_DEV_MANAGER dev_mgr,
PUSB_DEV pdev, ULONG context, ULONG due_time, TIMER_SVC_HANDLER handler)
{
PTIMER_SVC timer_svc;
KIRQL old_irql;
if (dev_mgr == NULL || pdev == NULL || due_time == 0 || handler == NULL)
return FALSE;
KeAcquireSpinLock(&dev_mgr->timer_svc_list_lock, &old_irql);
timer_svc = alloc_timer_svc(&dev_mgr->timer_svc_pool, 1);
if (timer_svc == NULL)
{
KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
return FALSE;
}
timer_svc->pdev = pdev;
timer_svc->threshold = due_time;
timer_svc->func = handler;
timer_svc->counter = 0;
InsertTailList(&dev_mgr->timer_svc_list, &timer_svc->timer_svc_link);
KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
return TRUE;
}
BYTE
dev_mgr_alloc_addr(PUSB_DEV_MANAGER dev_mgr, PHCD hcd)
{
// alloc a usb addr for the device within 1-128
if (dev_mgr == NULL || hcd == NULL)
return 0xff;
return hcd->hcd_alloc_addr(hcd);
}
BOOL
dev_mgr_free_addr(PUSB_DEV_MANAGER dev_mgr, PUSB_DEV pdev, BYTE addr)
{
PHCD hcd;
if (addr & 0x80)
return FALSE;
if (dev_mgr == NULL || pdev == NULL)
return FALSE;
hcd = pdev->hcd;
if (hcd == NULL)
return FALSE;
hcd->hcd_free_addr(hcd, addr);
return TRUE;
}
PUSB_DEV
dev_mgr_alloc_device(PUSB_DEV_MANAGER dev_mgr, PHCD hcd)
{
BYTE addr;
PUSB_DEV pdev;
if ((addr = dev_mgr_alloc_addr(dev_mgr, hcd)) == 0xff)
return NULL;
pdev = usb_alloc_mem(NonPagedPool, sizeof(USB_DEV));
if (pdev == NULL)
return NULL;
RtlZeroMemory(pdev, sizeof(USB_DEV));
KeInitializeSpinLock(&pdev->dev_lock);
dev_mgr->conn_count++;
pdev->flags = USB_DEV_STATE_RESET; //class | cur_state | low speed
pdev->ref_count = 0;
pdev->dev_addr = addr;
pdev->hcd = hcd;
pdev->dev_id = dev_mgr->conn_count; //will be used to compose dev_handle
InitializeListHead(&pdev->default_endp.urb_list);
pdev->default_endp.pusb_if = (PUSB_INTERFACE) pdev;
pdev->default_endp.flags = USB_ENDP_FLAG_DEFAULT_ENDP; //toggle | busy-count | stall | default-endp
return pdev;
}
VOID
dev_mgr_free_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DEV pdev)
{
if (pdev == NULL || dev_mgr == NULL)
return;
dev_mgr_free_addr(dev_mgr, pdev, pdev->dev_addr);
if (pdev->usb_config && pdev != pdev->hcd->hcd_get_root_hub(pdev->hcd))
{
//root hub has its config and desc buf allocated together,
//so no usb_config allocated seperately
dev_mgr_destroy_usb_config(pdev->usb_config);
pdev->usb_config = NULL;
}
if (pdev->desc_buf)
{
usb_free_mem(pdev->desc_buf);
pdev->desc_buf = NULL;
}
usb_free_mem(pdev);
pdev = NULL;
return;
}
//called when a disconnect is detected on the port
VOID
dev_mgr_disconnect_dev(PUSB_DEV pdev)
{
PLIST_ENTRY pthis, pnext;
PHUB2_EXTENSION phub_ext;
PUSB_CONFIGURATION pconfig;
PUSB_INTERFACE pif;
PUSB_DEV_MANAGER dev_mgr;
PHCD hcd;
BOOL is_hub, found;
ULONG dev_id;
int i;
USE_NON_PENDING_IRQL;
if (pdev == NULL)
return;
found = FALSE;
usb_dbg_print(DBGLVL_MAXIMUM, ("dev_mgr_disconnect_dev(): entering, pdev=0x%x\n", pdev));
lock_dev(pdev, FALSE);
pdev->flags &= ~USB_DEV_STATE_MASK;
pdev->flags |= USB_DEV_STATE_BEFORE_ZOMB;
dev_mgr = dev_mgr_from_dev(pdev);
unlock_dev(pdev, FALSE);
// notify dev_driver that the dev stops function before any operations
if (pdev->dev_driver && pdev->dev_driver->disp_tbl.dev_stop)
pdev->dev_driver->disp_tbl.dev_stop(dev_mgr, dev_handle_from_dev(pdev));
//safe to use the dev pointer in this function.
lock_dev(pdev, FALSE);
pdev->flags &= ~USB_DEV_STATE_MASK;
pdev->flags |= USB_DEV_STATE_ZOMB;
hcd = pdev->hcd;
dev_id = pdev->dev_id;
unlock_dev(pdev, FALSE);
if (dev_mgr == NULL)
return;
hcd->hcd_remove_device(hcd, pdev);
//disconnect its children
if ((pdev->flags & USB_DEV_CLASS_MASK) == USB_DEV_CLASS_HUB ||
(pdev->flags & USB_DEV_CLASS_MASK) == USB_DEV_CLASS_ROOT_HUB)
{
phub_ext = hub_ext_from_dev(pdev);
if (phub_ext)
{
for(i = 1; i <= phub_ext->port_count; i++)
{
if (phub_ext->child_dev[i])
{
dev_mgr_disconnect_dev(phub_ext->child_dev[i]);
phub_ext->child_dev[i] = NULL;
}
}
}
}
pconfig = pdev->usb_config;
//remove event belong to the dev
is_hub = ((pdev->flags & USB_DEV_CLASS_MASK) == USB_DEV_CLASS_HUB);
if (phub_ext && is_hub)
{
for(i = 1; i <= phub_ext->port_count; i++)
{
found = hub_remove_reset_event(pdev, i, FALSE);
if (found)
break;
}
}
//free event of the dev from the event list
KeAcquireSpinLock(&dev_mgr->event_list_lock, &old_irql);
ListFirst(&dev_mgr->event_list, pthis);
while (pthis)
{
ListNext(&dev_mgr->event_list, pthis, pnext);
if (((PUSB_EVENT) pthis)->pdev == pdev)
{
PLIST_ENTRY p1;
RemoveEntryList(pthis);
if ((((PUSB_EVENT) pthis)->flags & USB_EVENT_FLAG_QUE_TYPE) != USB_EVENT_FLAG_NOQUE)
{
//has a queue, re-insert the queue
if (p1 = (PLIST_ENTRY) ((PUSB_EVENT) pthis)->pnext)
{
InsertHeadList(&dev_mgr->event_list, p1);
free_event(&dev_mgr->event_pool, struct_ptr(pthis, USB_EVENT, event_link));
pthis = p1;
//note: this queue will be examined again in the next loop
//to find the matched dev in the queue
continue;
}
}
free_event(&dev_mgr->event_pool, struct_ptr(pthis, USB_EVENT, event_link));
}
else if (((((PUSB_EVENT) pthis)->flags & USB_EVENT_FLAG_QUE_TYPE)
!= USB_EVENT_FLAG_NOQUE) && ((PUSB_EVENT) pthis)->pnext)
{
//has a queue, examine the queue
PUSB_EVENT p1, p2;
p1 = (PUSB_EVENT) pthis;
p2 = p1->pnext;
while (p2)
{
if (p2->pdev == pdev)
{
p1->pnext = p2->pnext;
p2->pnext = NULL;
free_event(&dev_mgr->event_pool, p2);
p2 = p1->pnext;
}
else
{
p1 = p2;
p2 = p2->pnext;
}
}
}
pthis = pnext;
}
KeReleaseSpinLock(&dev_mgr->event_list_lock, old_irql);
// found indicates the reset event on one of the dev's port in process
if (found)
hub_start_next_reset_port(dev_mgr_from_dev(pdev), FALSE);
// remove timer-svc belonging to the dev
KeAcquireSpinLock(&dev_mgr->timer_svc_list_lock, &old_irql);
ListFirst(&dev_mgr->timer_svc_list, pthis);
i = 0;
while (pthis)
{
ListNext(&dev_mgr->timer_svc_list, pthis, pnext);
if (((PUSB_EVENT) pthis)->pdev == pdev)
{
RemoveEntryList(pthis);
free_timer_svc(&dev_mgr->timer_svc_pool, struct_ptr(pthis, TIMER_SVC, timer_svc_link));
i++;
}
pthis = pnext;
}
KeReleaseSpinLock(&dev_mgr->timer_svc_list_lock, old_irql);
// release the refcount
if (i)
{
lock_dev(pdev, FALSE);
pdev->ref_count -= i;
unlock_dev(pdev, FALSE);
}
// wait for all the reference count be released
for(;;)
{
LARGE_INTEGER interval;
lock_dev(pdev, FALSE);
if (pdev->ref_count == 0)
{
unlock_dev(pdev, FALSE);
break;
}
unlock_dev(pdev, FALSE);
// Wait two ms.
interval.QuadPart = -20000;
KeDelayExecutionThread(KernelMode, FALSE, &interval);
}
if (pdev->dev_driver && pdev->dev_driver->disp_tbl.dev_disconnect)
pdev->dev_driver->disp_tbl.dev_disconnect(dev_mgr, dev_handle_from_dev(pdev));
// we put it here to let handle valid before disconnect
KeAcquireSpinLock(&dev_mgr->dev_list_lock, &old_irql);
ListFirst(&dev_mgr->dev_list, pthis);
while (pthis)
{
if (((PUSB_DEV) pthis) == pdev)
{
RemoveEntryList(pthis);
break;
}
ListNext(&dev_mgr->dev_list, pthis, pnext);
pthis = pnext;
}
KeReleaseSpinLock(&dev_mgr->dev_list_lock, old_irql);
if (pdev != pdev->hcd->hcd_get_root_hub(pdev->hcd))
{
dev_mgr_free_device(dev_mgr, pdev);
}
else
{
//rh_destroy( pdev );
//TRAP();
//destroy it in dev_mgr_destroy
}
return;
}

View file

@ -0,0 +1,271 @@
#ifndef __DEVMGR_H__
#define __DEVMGR_H__
typedef struct _CONNECT_DATA
{
DEV_HANDLE dev_handle;
struct _USB_DRIVER *pdriver;
struct _USB_DEV_MANAGER *dev_mgr;
} CONNECT_DATA, *PCONNECT_DATA;
typedef BOOL ( *PDEV_CONNECT_EX )( PCONNECT_DATA init_param, DEV_HANDLE dev_handle );
typedef BOOL ( *PDEV_CONNECT )( struct _USB_DEV_MANAGER *dev_mgr, DEV_HANDLE dev_handle );
typedef BOOL ( *PDRVR_INIT )( struct _USB_DEV_MANAGER *dev_mgr, struct _USB_DRIVER *pdriver );
typedef struct _PNP_DISPATCH
{
ULONG version;
PDEV_CONNECT_EX dev_connect;
PDEV_CONNECT dev_reserved; //currently we do not use this entry
PDEV_CONNECT dev_stop;
PDEV_CONNECT dev_disconnect;
}PNP_DISPATCH, *PPNP_DISPATCH;
#define USB_DRIVER_FLAG_IF_CAPABLE 0x80000000
#define USB_DRIVER_FLAG_DEV_CAPABLE 0x40000000
typedef struct _USB_DRIVER_DESCRIPTION
{
// Device Info
DWORD flags;
WORD vendor_id; // USB Vendor ID
WORD product_id; // USB Product ID.
WORD release_num; // Release Number of Device
// Interface Info
BYTE config_val; // Configuration Value
BYTE if_num; // Interface Number
BYTE if_class; // Interface Class
BYTE if_sub_class; // Interface SubClass
BYTE if_protocol; // Interface Protocol
// Driver Info
PBYTE driver_name; // Driver name for Name Registry
BYTE dev_class; // Device Class (from SampleStorageDeviceID.h)
BYTE dev_sub_class; // Device Subclass
BYTE dev_protocol; // Protocol Info.
} USB_DRIVER_DESCRIPTION,*PUSB_DRIVER_DESCRIPTION;
#define DEVMGR_MAX_DRIVERS 6
#define RH_DRIVER_IDX 0
#define HUB_DRIVER_IDX 1
#define UMSS_DRIVER_IDX 2
#define COMP_DRIVER_IDX 3
#define GEN_DRIVER_IDX 4
#define GEN_IF_DRIVER_IDX 5
typedef struct _USB_DRIVER
{
USB_DRIVER_DESCRIPTION driver_desc;
PNP_DISPATCH disp_tbl;
PBYTE driver_ext;
LONG driver_ext_size;
PDRVR_INIT driver_init;
PDRVR_INIT driver_destroy;
} USB_DRIVER, *PUSB_DRIVER;
extern USB_DRIVER g_driver_list[ DEVMGR_MAX_DRIVERS ];
#define MAX_HCDS 8
#define dev_mgr_from_hcd( hCD ) ( ( hCD )->hcd_get_dev_mgr( hCD ) )
#define dev_mgr_from_dev( pdEV ) ( dev_mgr_from_hcd( pdEV->hcd ) )
typedef struct _USB_DEV_MANAGER
{
//BYTE dev_addr_map[ MAX_DEVS / 8 ]; //one bit per dev
struct _HCD *hcd_array[ MAX_HCDS ];
unsigned char hcd_count;
KSPIN_LOCK dev_list_lock;
LIST_HEAD dev_list;
//PDEVICE_EXTENSION pdev_ext;
PVOID pthread;
BOOL term_flag;
KEVENT wake_up_event;
KSPIN_LOCK event_list_lock;
LIST_HEAD event_list;
USB_EVENT_POOL event_pool;
KTIMER dev_mgr_timer;
KDPC dev_mgr_timer_dpc;
KSPIN_LOCK timer_svc_list_lock;
LIST_HEAD timer_svc_list;
TIMER_SVC_POOL timer_svc_pool;
LONG timer_click;
IRP_LIST irp_list;
PUSB_DRIVER driver_list;
LONG hub_count;
LIST_HEAD hub_list; //for reference only
//statistics
LONG conn_count; //will also be used to assign device id
PDRIVER_OBJECT usb_driver_obj; //this driver object
LONG open_count; //increment when IRP_MJ_CREATE arrives
//and decrement when IRP_MJ_CLOSE arrives
} USB_DEV_MANAGER, *PUSB_DEV_MANAGER;
BOOL
dev_mgr_post_event(
PUSB_DEV_MANAGER dev_mgr,
PUSB_EVENT event
);
BOOL
dev_mgr_init(
PUSB_DEV dev, //always null. we do not use this param
ULONG event,
ULONG dev_mgr
);
VOID
dev_mgr_destroy(
PUSB_DEV_MANAGER dev_mgr
);
VOID
dev_mgr_thread(
PVOID dev_mgr
);
VOID
dev_mgr_timer_dpc_callback(
PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2
);
BOOL
dev_mgr_request_timer_svc(
PUSB_DEV_MANAGER dev_mgr,
PUSB_DEV pdev,
ULONG context,
ULONG due_time,
TIMER_SVC_HANDLER handler
);
BYTE
dev_mgr_alloc_addr(
PUSB_DEV_MANAGER dev_mgr,
PHCD hcd
);
BOOL
dev_mgr_free_addr(
PUSB_DEV_MANAGER dev_mgr,
PUSB_DEV pdev,
BYTE addr
);
PUSB_DEV
dev_mgr_alloc_device(
PUSB_DEV_MANAGER dev_mgr,
PHCD hcd
);
VOID
dev_mgr_free_device(
PUSB_DEV_MANAGER dev_mgr,
PUSB_DEV pdev
);
VOID
dev_mgr_disconnect_dev(
PUSB_DEV pdev
);
BOOL
dev_mgr_strobe(
PUSB_DEV_MANAGER dev_mgr
);
NTSTATUS
dev_mgr_build_usb_config(
PUSB_DEV pdev,
PBYTE pbuf,
ULONG config_val,
LONG config_count
);
UCHAR
dev_mgr_register_hcd(
PUSB_DEV_MANAGER dev_mgr,
PHCD hcd
);
NTSTATUS
dev_mgr_dispatch(
IN PUSB_DEV_MANAGER dev_mgr,
IN PIRP irp
);
BOOL
dev_mgr_register_irp(
PUSB_DEV_MANAGER dev_mgr,
PIRP pirp,
PURB purb
);
PURB
dev_mgr_remove_irp(
PUSB_DEV_MANAGER dev_mgr,
PIRP pirp
);
LONG
dev_mgr_score_driver_for_if(
PUSB_DEV_MANAGER dev_mgr,
PUSB_DRIVER pdriver,
PUSB_INTERFACE_DESC pif_desc
);
BOOL
dev_mgr_set_driver(
PUSB_DEV_MANAGER dev_mgr,
DEV_HANDLE dev_handle,
PUSB_DRIVER pdriver,
PUSB_DEV pdev //if pdev != NULL, we use pdev instead if_handle
);
BOOL
dev_mgr_set_if_driver(
PUSB_DEV_MANAGER dev_mgr,
DEV_HANDLE if_handle,
PUSB_DRIVER pdriver,
PUSB_DEV pdev //if pdev != NULL, we use pdev instead if_handle
);
VOID
dev_mgr_release_hcd(
PUSB_DEV_MANAGER dev_mgr
);
VOID
dev_mgr_start_hcd(
PUSB_DEV_MANAGER dev_mgr
);
BOOL dev_mgr_start_config_dev(PUSB_DEV pdev);
BOOL dev_mgr_event_init(PUSB_DEV dev, //always null. we do not use this param
ULONG event,
ULONG context,
ULONG param);
VOID dev_mgr_get_desc_completion(PURB purb, PVOID context);
VOID dev_mgr_event_select_driver(PUSB_DEV pdev, ULONG event, ULONG context, ULONG param);
LONG dev_mgr_score_driver_for_dev(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver, PUSB_DEVICE_DESC pdev_desc);
NTSTATUS dev_mgr_destroy_usb_config(PUSB_CONFIGURATION pcfg);
BOOL dev_mgr_start_select_driver(PUSB_DEV pdev);
VOID dev_mgr_cancel_irp(PDEVICE_OBJECT pdev_obj, PIRP pirp);
#endif

View file

@ -19,11 +19,7 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <ntddk.h>
#include "usb.h"
#include "debug.h"
#include "td.h"
#include "hub.h"
#include "usbdriver.h"
VOID
disp_urb_completion(PURB purb, PVOID context)

View file

@ -19,13 +19,9 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "td.h"
#include "hub.h"
#include "debug.h"
#include "stdio.h"
#include "usb.h"
#include <ntddk.h>
#include "usbdriver.h"
#include "ehci.h"
//----------------------------------------------------------
// ehci routines
//#define DEMO

View file

@ -15,9 +15,6 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "hcd.h"
#include "usb.h"
#include "td.h"
#ifndef __EHCI_H__
#define __EHCI_H__

View file

@ -19,8 +19,8 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <usbdriver.h>
#include "ehci.h"
#include "debug.h"
#define init_elem( ptr, type, ehci_elem_type ) \
{\

View file

@ -0,0 +1,148 @@
#ifndef __EVENTS_H
#define __EVENTS_H
//event definitions
#define MAX_EVENTS 128
#define MAX_TIMER_SVCS 24
#define USB_EVENT_FLAG_ACTIVE 0x80000000
#define USB_EVENT_FLAG_QUE_TYPE 0x000000FF
#define USB_EVENT_FLAG_QUE_RESET 0x01
#define USB_EVENT_FLAG_NOQUE 0x00
#define USB_EVENT_DEFAULT 0x00 //as a placeholder
#define USB_EVENT_INIT_DEV_MGR 0x01
#define USB_EVENT_HUB_POLL 0x02
#define USB_EVENT_WAIT_RESET_PORT 0x03
#define USB_EVENT_CLEAR_TT_BUFFER 0x04
typedef VOID ( *PROCESS_QUEUE )(
PLIST_HEAD event_list,
struct _USB_EVENT_POOL *event_pool,
struct _USB_EVENT *usb_event,
struct _USB_EVENT *out_event
);
typedef VOID ( *PROCESS_EVENT )(
PUSB_DEV dev,
ULONG event,
ULONG context,
ULONG param
);
typedef struct _USB_EVENT
{
LIST_ENTRY event_link;
ULONG flags;
ULONG event;
PUSB_DEV pdev;
ULONG context;
ULONG param;
struct _USB_EVENT *pnext; //vertical queue for serialized operation
PROCESS_EVENT process_event;
PROCESS_QUEUE process_queue;
} USB_EVENT, *PUSB_EVENT;
typedef struct _USB_EVENT_POOL
{
PUSB_EVENT event_array;
LIST_HEAD free_que;
LONG free_count;
LONG total_count;
KSPIN_LOCK pool_lock;
} USB_EVENT_POOL, *PUSB_EVENT_POOL;
BOOL
init_event_pool(
PUSB_EVENT_POOL pool
);
BOOL
free_event(
PUSB_EVENT_POOL pool,
PUSB_EVENT pevent
); //add qhs till pnext == NULL
PUSB_EVENT
alloc_event(
PUSB_EVENT_POOL pool,
LONG count
); //null if failed
BOOL
destroy_event_pool(
PUSB_EVENT_POOL pool
);
VOID
lock_event_pool(
PUSB_EVENT_POOL pool
);
VOID
unlock_event_pool(
PUSB_EVENT_POOL pool
);
#define DEV_MGR_TIMER_INTERVAL_NS ( 10 * 1000 * 10 ) //unit 100 ns
#define DEV_MGR_TIMER_INTERVAL_MS 10
typedef VOID ( *TIMER_SVC_HANDLER )(PUSB_DEV dev, PVOID context);
typedef struct _TIMER_SVC
{
LIST_ENTRY timer_svc_link;
ULONG counter;
ULONG threshold;
ULONG context;
PUSB_DEV pdev;
TIMER_SVC_HANDLER func;
} TIMER_SVC, *PTIMER_SVC;
typedef struct _TIMER_SVC_POOL
{
PTIMER_SVC timer_svc_array;
LIST_HEAD free_que;
LONG free_count;
LONG total_count;
KSPIN_LOCK pool_lock;
} TIMER_SVC_POOL, *PTIMER_SVC_POOL;
BOOL
init_timer_svc_pool(
PTIMER_SVC_POOL pool
);
BOOL
free_timer_svc(
PTIMER_SVC_POOL pool,
PTIMER_SVC ptimer
);
PTIMER_SVC
alloc_timer_svc(
PTIMER_SVC_POOL pool,
LONG count
); //null if failed
BOOL
destroy_timer_svc_pool(
PTIMER_SVC_POOL pool
);
VOID
lock_timer_svc_pool(
PTIMER_SVC_POOL pool
);
VOID
unlock_timer_svc_pool(
PTIMER_SVC_POOL pool
);
#endif

View file

@ -20,15 +20,8 @@
*/
//this driver is part of the dev manager responsible to manage non-driver device
#include "td.h"
#include "ntddk.h"
#include "umss.h"
#include "usb.h"
#include "hub.h"
#include "debug.h"
#include "usbdriver.h"
#include "gendrv.h"
#include "stdio.h"
#define if_dev( dev_obj ) \
( ( ( ( PGENDRV_DEVICE_EXTENSION)dev_obj->DeviceExtension )->pdriver->driver_desc.flags & USB_DRIVER_FLAG_IF_CAPABLE ) != 0 )
@ -581,6 +574,7 @@ gendrv_load_ext_drvr(PGENDRV_DRVR_EXTENSION pdrvr_ext, PUSB_DESC_HEADER pdesc)
val_info = NULL;
RtlInitUnicodeString(&usz, L"");
gendrv_build_reg_string(pdesc, &usz);
DbgPrint("UHCI: Trying to load driver %wZ\n", &usz);
if (gendrv_open_reg_key(&handle, NULL, &usz, KEY_READ, FALSE) != STATUS_SUCCESS)
{
goto ERROR_OUT;

View file

@ -1,9 +1,6 @@
#ifndef __GENDRV_H__
#define __GENDRV_H__
#include "td.h"
#include "hub.h"
#define GENDRV_MAX_EXT_DRVR 2
#define GENDRV_DRVR_FLAG_IF_DRVR 0x01

View file

@ -1,8 +1,6 @@
#ifndef __HCD_H__
#define __HCD_H__
#include "ntddk.h"
#define HCD_TYPE_MASK 0xf0
#define HCD_TYPE_UHCI 0x10
#define HCD_TYPE_OHCI 0x20
@ -21,6 +19,12 @@
#define HCD_DISP_READ_RH_DEV_CHANGE 2 // the param is a buffer to hold conn change on all the port
// must have the rh dev_lock acquired
struct _HCD;
struct _USB_DEV_MANAGER;
struct _USB_DEV;
struct _USB_ENDPOINT;
struct _URB;
typedef VOID ( *PHCD_SET_DEV_MGR )( struct _HCD* hcd, struct _USB_DEV_MANAGER *dev_mgr );
typedef struct _USB_DEV_MANAGER* ( *PHCD_GET_DEV_MGR )( struct _HCD* hcd );
typedef ULONG ( *PHCD_GET_TYPE )( struct _HCD* hcd );

File diff suppressed because it is too large Load diff

View file

@ -2,10 +2,6 @@
#ifndef __HUB_H__
#define __HUB_H__
#include "td.h"
//#include "hcd.h"
#include "ntddk.h"
/*
* Hub Class feature numbers
*/
@ -65,204 +61,6 @@
#define HUB_DESCRIPTOR_MAX_SIZE 39 /* enough for 127 ports on a hub */
//event definitions
#define MAX_EVENTS 128
#define MAX_TIMER_SVCS 24
#define USB_EVENT_FLAG_ACTIVE 0x80000000
#define USB_EVENT_FLAG_QUE_TYPE 0x000000FF
#define USB_EVENT_FLAG_QUE_RESET 0x01
#define USB_EVENT_FLAG_NOQUE 0x00
#define USB_EVENT_DEFAULT 0x00 //as a placeholder
#define USB_EVENT_INIT_DEV_MGR 0x01
#define USB_EVENT_HUB_POLL 0x02
#define USB_EVENT_WAIT_RESET_PORT 0x03
#define USB_EVENT_CLEAR_TT_BUFFER 0x04
typedef VOID ( *PROCESS_QUEUE )(
PLIST_HEAD event_list,
struct _USB_EVENT_POOL *event_pool,
struct _USB_EVENT *usb_event,
struct _USB_EVENT *out_event
);
typedef VOID ( *PROCESS_EVENT )(
PUSB_DEV dev,
ULONG event,
ULONG context,
ULONG param
);
typedef struct _USB_EVENT
{
LIST_ENTRY event_link;
ULONG flags;
ULONG event;
PUSB_DEV pdev;
ULONG context;
ULONG param;
struct _USB_EVENT *pnext; //vertical queue for serialized operation
PROCESS_EVENT process_event;
PROCESS_QUEUE process_queue;
} USB_EVENT, *PUSB_EVENT;
typedef struct _USB_EVENT_POOL
{
PUSB_EVENT event_array;
LIST_HEAD free_que;
LONG free_count;
LONG total_count;
KSPIN_LOCK pool_lock;
} USB_EVENT_POOL, *PUSB_EVENT_POOL;
BOOL
init_event_pool(
PUSB_EVENT_POOL pool
);
BOOL
free_event(
PUSB_EVENT_POOL pool,
PUSB_EVENT pevent
); //add qhs till pnext == NULL
PUSB_EVENT
alloc_event(
PUSB_EVENT_POOL pool,
LONG count
); //null if failed
BOOL
destroy_event_pool(
PUSB_EVENT_POOL pool
);
VOID
lock_event_pool(
PUSB_EVENT_POOL pool
);
VOID
unlock_event_pool(
PUSB_EVENT_POOL pool
);
#define DEV_MGR_TIMER_INTERVAL_NS ( 10 * 1000 * 10 ) //unit 100 ns
#define DEV_MGR_TIMER_INTERVAL_MS 10
typedef VOID ( *TIMER_SVC_HANDLER )(PUSB_DEV dev, PVOID context);
typedef struct _TIMER_SVC
{
LIST_ENTRY timer_svc_link;
ULONG counter;
ULONG threshold;
ULONG context;
PUSB_DEV pdev;
TIMER_SVC_HANDLER func;
} TIMER_SVC, *PTIMER_SVC;
typedef struct _TIMER_SVC_POOL
{
PTIMER_SVC timer_svc_array;
LIST_HEAD free_que;
LONG free_count;
LONG total_count;
KSPIN_LOCK pool_lock;
} TIMER_SVC_POOL, *PTIMER_SVC_POOL;
BOOL
init_timer_svc_pool(
PTIMER_SVC_POOL pool
);
BOOL
free_timer_svc(
PTIMER_SVC_POOL pool,
PTIMER_SVC ptimer
);
PTIMER_SVC
alloc_timer_svc(
PTIMER_SVC_POOL pool,
LONG count
); //null if failed
BOOL
destroy_timer_svc_pool(
PTIMER_SVC_POOL pool
);
VOID
lock_timer_svc_pool(
PTIMER_SVC_POOL pool
);
VOID
unlock_timer_svc_pool(
PTIMER_SVC_POOL pool
);
#define MAX_IRP_LIST_SIZE 32
typedef struct _IRP_LIST_ELEMENT
{
LIST_ENTRY irp_link;
PIRP pirp;
struct _URB *purb;
} IRP_LIST_ELEMENT, *PIRP_LIST_ELEMENT;
typedef struct _IRP_LIST
{
KSPIN_LOCK irp_list_lock;
LIST_HEAD irp_busy_list;
LONG irp_free_list_count;
LIST_HEAD irp_free_list;
PIRP_LIST_ELEMENT irp_list_element_array;
} IRP_LIST, *PIRP_LIST;
BOOL
init_irp_list(
PIRP_LIST irp_list
);
VOID
destroy_irp_list(
PIRP_LIST irp_list
);
BOOL
add_irp_to_list(
PIRP_LIST irp_list,
PIRP pirp,
PURB purb
);
PURB
remove_irp_from_list(
PIRP_LIST irp_list,
PIRP pirp,
struct _USB_DEV_MANAGER *dev_mgr
);
BOOL
irp_list_empty(
PIRP_LIST irp_list
);
BOOL
irp_list_full(
PIRP_LIST irp_list
);
#define MAX_HUB_PORTS 8
#define USB_HUB_INTERVAL 0xff
@ -296,6 +94,7 @@ PIRP_LIST irp_list
&& pdev->pusb_dev_desc->bDeviceSubClass == 0 )
#define dev_handle_from_dev( pdev ) ( pdev->dev_id << 16 )
#define hub_ext_from_dev( pdEV ) ( ( PHUB2_EXTENSION )pdEV->dev_ext )
#pragma pack( push, hub_align, 1 )
typedef struct _USB_PORT_STATUS
@ -418,260 +217,6 @@ typedef struct _HUB2_EXTENSION
} HUB2_EXTENSION, *PHUB2_EXTENSION;
typedef struct _CONNECT_DATA
{
DEV_HANDLE dev_handle;
struct _USB_DRIVER *pdriver;
struct _USB_DEV_MANAGER *dev_mgr;
} CONNECT_DATA, *PCONNECT_DATA;
typedef BOOL ( *PDEV_CONNECT_EX )( PCONNECT_DATA init_param, DEV_HANDLE dev_handle );
typedef BOOL ( *PDEV_CONNECT )( struct _USB_DEV_MANAGER *dev_mgr, DEV_HANDLE dev_handle );
typedef BOOL ( *PDRVR_INIT )( struct _USB_DEV_MANAGER *dev_mgr, struct _USB_DRIVER *pdriver );
typedef struct _PNP_DISPATCH
{
ULONG version;
PDEV_CONNECT_EX dev_connect;
PDEV_CONNECT dev_reserved; //currently we do not use this entry
PDEV_CONNECT dev_stop;
PDEV_CONNECT dev_disconnect;
}PNP_DISPATCH, *PPNP_DISPATCH;
#define USB_DRIVER_FLAG_IF_CAPABLE 0x80000000
#define USB_DRIVER_FLAG_DEV_CAPABLE 0x40000000
typedef struct _USB_DRIVER_DESCRIPTION
{
// Device Info
DWORD flags;
WORD vendor_id; // USB Vendor ID
WORD product_id; // USB Product ID.
WORD release_num; // Release Number of Device
// Interface Info
BYTE config_val; // Configuration Value
BYTE if_num; // Interface Number
BYTE if_class; // Interface Class
BYTE if_sub_class; // Interface SubClass
BYTE if_protocol; // Interface Protocol
// Driver Info
PBYTE driver_name; // Driver name for Name Registry
BYTE dev_class; // Device Class (from SampleStorageDeviceID.h)
BYTE dev_sub_class; // Device Subclass
BYTE dev_protocol; // Protocol Info.
} USB_DRIVER_DESCRIPTION,*PUSB_DRIVER_DESCRIPTION;
#define DEVMGR_MAX_DRIVERS 6
#define RH_DRIVER_IDX 0
#define HUB_DRIVER_IDX 1
#define UMSS_DRIVER_IDX 2
#define COMP_DRIVER_IDX 3
#define GEN_DRIVER_IDX 4
#define GEN_IF_DRIVER_IDX 5
typedef struct _USB_DRIVER
{
USB_DRIVER_DESCRIPTION driver_desc;
PNP_DISPATCH disp_tbl;
PBYTE driver_ext;
LONG driver_ext_size;
PDRVR_INIT driver_init;
PDRVR_INIT driver_destroy;
} USB_DRIVER, *PUSB_DRIVER;
extern USB_DRIVER g_driver_list[ DEVMGR_MAX_DRIVERS ];
#define MAX_HCDS 8
#define dev_mgr_from_hcd( hCD ) ( ( hCD )->hcd_get_dev_mgr( hCD ) )
#define dev_mgr_from_dev( pdEV ) ( dev_mgr_from_hcd( pdEV->hcd ) )
typedef struct _USB_DEV_MANAGER
{
//BYTE dev_addr_map[ MAX_DEVS / 8 ]; //one bit per dev
struct _HCD *hcd_array[ MAX_HCDS ];
unsigned char hcd_count;
KSPIN_LOCK dev_list_lock;
LIST_HEAD dev_list;
//PDEVICE_EXTENSION pdev_ext;
PVOID pthread;
BOOL term_flag;
KEVENT wake_up_event;
KSPIN_LOCK event_list_lock;
LIST_HEAD event_list;
USB_EVENT_POOL event_pool;
KTIMER dev_mgr_timer;
KDPC dev_mgr_timer_dpc;
KSPIN_LOCK timer_svc_list_lock;
LIST_HEAD timer_svc_list;
TIMER_SVC_POOL timer_svc_pool;
LONG timer_click;
IRP_LIST irp_list;
PUSB_DRIVER driver_list;
LONG hub_count;
LIST_HEAD hub_list; //for reference only
//statistics
LONG conn_count; //will also be used to assign device id
PDRIVER_OBJECT usb_driver_obj; //this driver object
LONG open_count; //increment when IRP_MJ_CREATE arrives
//and decrement when IRP_MJ_CLOSE arrives
} USB_DEV_MANAGER, *PUSB_DEV_MANAGER;
BOOL
dev_mgr_post_event(
PUSB_DEV_MANAGER dev_mgr,
PUSB_EVENT event
);
BOOL
dev_mgr_init(
PUSB_DEV dev, //always null. we do not use this param
ULONG event,
ULONG dev_mgr
);
VOID
dev_mgr_destroy(
PUSB_DEV_MANAGER dev_mgr
);
VOID
dev_mgr_thread(
PVOID dev_mgr
);
VOID
dev_mgr_timer_dpc_callback(
PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2
);
BOOL
dev_mgr_request_timer_svc(
PUSB_DEV_MANAGER dev_mgr,
PUSB_DEV pdev,
ULONG context,
ULONG due_time,
TIMER_SVC_HANDLER handler
);
BYTE
dev_mgr_alloc_addr(
PUSB_DEV_MANAGER dev_mgr,
PHCD hcd
);
BOOL
dev_mgr_free_addr(
PUSB_DEV_MANAGER dev_mgr,
PUSB_DEV pdev,
BYTE addr
);
PUSB_DEV
dev_mgr_alloc_device(
PUSB_DEV_MANAGER dev_mgr,
PHCD hcd
);
VOID
dev_mgr_free_device(
PUSB_DEV_MANAGER dev_mgr,
PUSB_DEV pdev
);
VOID
dev_mgr_disconnect_dev(
PUSB_DEV pdev
);
BOOL
dev_mgr_strobe(
PUSB_DEV_MANAGER dev_mgr
);
NTSTATUS
dev_mgr_build_usb_config(
PUSB_DEV pdev,
PBYTE pbuf,
ULONG config_val,
LONG config_count
);
UCHAR
dev_mgr_register_hcd(
PUSB_DEV_MANAGER dev_mgr,
PHCD hcd
);
NTSTATUS
dev_mgr_dispatch(
IN PUSB_DEV_MANAGER dev_mgr,
IN PIRP irp
);
BOOL
dev_mgr_register_irp(
PUSB_DEV_MANAGER dev_mgr,
PIRP pirp,
PURB purb
);
PURB
dev_mgr_remove_irp(
PUSB_DEV_MANAGER dev_mgr,
PIRP pirp
);
LONG
dev_mgr_score_driver_for_if(
PUSB_DEV_MANAGER dev_mgr,
PUSB_DRIVER pdriver,
PUSB_INTERFACE_DESC pif_desc
);
BOOL
dev_mgr_set_driver(
PUSB_DEV_MANAGER dev_mgr,
DEV_HANDLE dev_handle,
PUSB_DRIVER pdriver,
PUSB_DEV pdev //if pdev != NULL, we use pdev instead if_handle
);
BOOL
dev_mgr_set_if_driver(
PUSB_DEV_MANAGER dev_mgr,
DEV_HANDLE if_handle,
PUSB_DRIVER pdriver,
PUSB_DEV pdev //if pdev != NULL, we use pdev instead if_handle
);
VOID
dev_mgr_release_hcd(
PUSB_DEV_MANAGER dev_mgr
);
VOID
dev_mgr_start_hcd(
PUSB_DEV_MANAGER dev_mgr
);
VOID
event_list_default_process_queue(
@ -789,6 +334,12 @@ gendrv_if_driver_destroy(
PUSB_DEV_MANAGER dev_mgr,
PUSB_DRIVER pdriver
);
BOOL hub_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver);
BOOL hub_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver);
BOOL hub_remove_reset_event(PUSB_DEV pdev, ULONG port_idx, BOOL from_dpc);
BOOL hub_start_next_reset_port(PUSB_DEV_MANAGER dev_mgr, BOOL from_dpc);
#endif

View file

@ -0,0 +1,58 @@
#ifndef __IRPLIST_H
#define __IRPLIST_H
#define MAX_IRP_LIST_SIZE 32
typedef struct _IRP_LIST_ELEMENT
{
LIST_ENTRY irp_link;
PIRP pirp;
struct _URB *purb;
} IRP_LIST_ELEMENT, *PIRP_LIST_ELEMENT;
typedef struct _IRP_LIST
{
KSPIN_LOCK irp_list_lock;
LIST_HEAD irp_busy_list;
LONG irp_free_list_count;
LIST_HEAD irp_free_list;
PIRP_LIST_ELEMENT irp_list_element_array;
} IRP_LIST, *PIRP_LIST;
BOOL
init_irp_list(
PIRP_LIST irp_list
);
VOID
destroy_irp_list(
PIRP_LIST irp_list
);
BOOL
add_irp_to_list(
PIRP_LIST irp_list,
PIRP pirp,
PURB purb
);
PURB
remove_irp_from_list(
PIRP_LIST irp_list,
PIRP pirp,
struct _USB_DEV_MANAGER *dev_mgr
);
BOOL
irp_list_empty(
PIRP_LIST irp_list
);
BOOL
irp_list_full(
PIRP_LIST irp_list
);
#endif

View file

@ -0,0 +1,439 @@
/**
* roothub.c - USB driver stack project for Windows NT 4.0
*
* Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program (in the main directory of the distribution, the file
* COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "usbdriver.h"
//----------------------------------------------------------
BOOL
rh_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
{
LONG i;
PHCD hcd;
if (dev_mgr == NULL)
return FALSE;
for(i = 0; i < dev_mgr->hcd_count; i++)
{
hcd = dev_mgr->hcd_array[i];
// if( hcd->hcd_get_type( hcd ) != HCD_TYPE_UHCI )
// continue;
rh_destroy(hcd->hcd_get_root_hub(hcd));
}
return TRUE;
}
BOOL
rh_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
{
PUSB_DEV rh;
PUSB_CONFIGURATION_DESC pconfig_desc;
PUSB_INTERFACE_DESC pif_desc;
PUSB_ENDPOINT_DESC pendp_desc;
PUSB_CONFIGURATION pconfig;
PUSB_INTERFACE pif;
PUSB_ENDPOINT pendp;
PHUB2_EXTENSION phub_ext;
PTIMER_SVC ptimer;
PURB purb;
NTSTATUS status;
PHCD hcd;
LONG i;
if (dev_mgr == NULL || pdriver == NULL)
return FALSE;
//init driver structure, no PNP table functions
pdriver->driver_desc.flags = USB_DRIVER_FLAG_DEV_CAPABLE;
pdriver->driver_desc.vendor_id = 0xffff; // USB Vendor ID
pdriver->driver_desc.product_id = 0xffff; // USB Product ID.
pdriver->driver_desc.release_num = 0xffff; // Release Number of Device
pdriver->driver_desc.config_val = 0; // Configuration Value
pdriver->driver_desc.if_num = 0; // Interface Number
pdriver->driver_desc.if_class = USB_CLASS_HUB; // Interface Class
pdriver->driver_desc.if_sub_class = 0; // Interface SubClass
pdriver->driver_desc.if_protocol = 0; // Interface Protocol
pdriver->driver_desc.driver_name = "USB root hub"; // Driver name for Name Registry
pdriver->driver_desc.dev_class = USB_CLASS_HUB;
pdriver->driver_desc.dev_sub_class = 0; // Device Subclass
pdriver->driver_desc.dev_protocol = 0; // Protocol Info.
//pdriver->driver_init = rh_driver_init; // initialized in dev_mgr_init_driver
//pdriver->driver_destroy = rh_driver_destroy;
pdriver->disp_tbl.version = 1; // other fields of the dispatch table is not used since rh needs no pnp
pdriver->driver_ext = 0;
pdriver->driver_ext_size = 0;
for(i = 0; i < dev_mgr->hcd_count; i++)
{
hcd = dev_mgr->hcd_array[i];
//if( hcd->hcd_get_type( hcd ) != HCD_TYPE_UHCI )
// continue;
if ((rh = dev_mgr_alloc_device(dev_mgr, hcd)) == NULL)
return FALSE;
rh->parent_dev = NULL;
rh->port_idx = 0;
rh->hcd = hcd;
rh->flags = USB_DEV_CLASS_ROOT_HUB | USB_DEV_STATE_CONFIGURED;
if (usb2(hcd))
rh->flags |= USB_DEV_FLAG_HIGH_SPEED;
rh->dev_driver = pdriver;
rh->desc_buf_size = sizeof(USB_DEVICE_DESC)
+ sizeof(USB_CONFIGURATION_DESC)
+ sizeof(USB_INTERFACE_DESC)
+ sizeof(USB_ENDPOINT_DESC) + sizeof(USB_CONFIGURATION) + sizeof(HUB2_EXTENSION);
rh->desc_buf = usb_alloc_mem(NonPagedPool, rh->desc_buf_size);
if (rh->desc_buf == NULL)
{
return FALSE;
}
else
RtlZeroMemory(rh->desc_buf, rh->desc_buf_size);
rh->pusb_dev_desc = (PUSB_DEVICE_DESC) rh->desc_buf;
rh->pusb_dev_desc->bLength = sizeof(USB_DEVICE_DESC);
rh->pusb_dev_desc->bDescriptorType = USB_DT_DEVICE;
rh->pusb_dev_desc->bcdUSB = 0x110;
if (usb2(hcd))
rh->pusb_dev_desc->bcdUSB = 0x200;
rh->pusb_dev_desc->bDeviceClass = USB_CLASS_HUB;
rh->pusb_dev_desc->bDeviceSubClass = 0;
rh->pusb_dev_desc->bDeviceProtocol = 0;
rh->pusb_dev_desc->bMaxPacketSize0 = 8;
if (usb2(hcd))
{
rh->pusb_dev_desc->bDeviceProtocol = 1;
rh->pusb_dev_desc->bMaxPacketSize0 = 64;
}
rh->pusb_dev_desc->idVendor = 0;
rh->pusb_dev_desc->idProduct = 0;
rh->pusb_dev_desc->bcdDevice = 0x100;
rh->pusb_dev_desc->iManufacturer = 0;
rh->pusb_dev_desc->iProduct = 0;
rh->pusb_dev_desc->iSerialNumber = 0;
rh->pusb_dev_desc->bNumConfigurations = 1;
pconfig_desc = (PUSB_CONFIGURATION_DESC) & rh->desc_buf[sizeof(USB_DEVICE_DESC)];
pif_desc = (PUSB_INTERFACE_DESC) & pconfig_desc[1];
pendp_desc = (PUSB_ENDPOINT_DESC) & pif_desc[1];
pconfig_desc->bLength = sizeof(USB_CONFIGURATION_DESC);
pconfig_desc->bDescriptorType = USB_DT_CONFIG;
pconfig_desc->wTotalLength = sizeof(USB_CONFIGURATION_DESC)
+ sizeof(USB_INTERFACE_DESC) + sizeof(USB_ENDPOINT_DESC);
pconfig_desc->bNumInterfaces = 1;
pconfig_desc->bConfigurationValue = 1;
pconfig_desc->iConfiguration = 0;
pconfig_desc->bmAttributes = 0Xe0; //self-powered and support remoke wakeup
pconfig_desc->MaxPower = 0;
pif_desc->bLength = sizeof(USB_INTERFACE_DESC);
pif_desc->bDescriptorType = USB_DT_INTERFACE;
pif_desc->bInterfaceNumber = 0;
pif_desc->bAlternateSetting = 0;
pif_desc->bNumEndpoints = 1;
pif_desc->bInterfaceClass = USB_CLASS_HUB;
pif_desc->bInterfaceSubClass = 0;
pif_desc->bInterfaceProtocol = 0;
pif_desc->iInterface = 0;
pendp_desc->bLength = sizeof(USB_ENDPOINT_DESC);
pendp_desc->bDescriptorType = USB_DT_ENDPOINT;
pendp_desc->bEndpointAddress = 0x81;
pendp_desc->bmAttributes = 0x03;
pendp_desc->wMaxPacketSize = 8;
pendp_desc->bInterval = USB_HUB_INTERVAL;
if (usb2(hcd))
pendp_desc->bInterval = 0x0c;
pconfig = rh->usb_config = (PUSB_CONFIGURATION) & pendp_desc[1];
rh->active_config_idx = 0;
pconfig->pusb_config_desc = pconfig_desc;
pconfig->if_count = 1;
pconfig->pusb_dev = rh;
pif = &pconfig->interf[0];
pif->endp_count = 1;
pendp = &pif->endp[0];
pif->pusb_config = pconfig;;
pif->pusb_if_desc = pif_desc;
pif->if_ext_size = 0;
pif->if_ext = NULL;
phub_ext = (PHUB2_EXTENSION) & pconfig[1];
phub_ext->port_count = 2;
if (usb2(hcd))
{
// port count is configurable in usb2
hcd->hcd_dispatch(hcd, HCD_DISP_READ_PORT_COUNT, &phub_ext->port_count);
}
{
int j;
for(j = 0; j < phub_ext->port_count; j++)
{
psq_init(&phub_ext->port_status_queue[j]);
phub_ext->child_dev[j] = NULL;
usb_dbg_print(DBGLVL_MAXIMUM, ("rh_driver_init(): port[ %d ].flag=0x%x\n",
j, phub_ext->port_status_queue[j].port_flags));
}
}
phub_ext->pif = pif;
phub_ext->hub_desc.bLength = sizeof(USB_HUB_DESCRIPTOR);
phub_ext->hub_desc.bDescriptorType = USB_DT_HUB;
phub_ext->hub_desc.bNbrPorts = (UCHAR) phub_ext->port_count;
phub_ext->hub_desc.wHubCharacteristics = 0;
phub_ext->hub_desc.bPwrOn2PwrGood = 0;
phub_ext->hub_desc.bHubContrCurrent = 50;
rh->dev_ext = (PBYTE) phub_ext;
rh->dev_ext_size = sizeof(HUB2_EXTENSION);
rh->default_endp.flags = USB_ENDP_FLAG_DEFAULT_ENDP;
InitializeListHead(&rh->default_endp.urb_list);
rh->default_endp.pusb_if = (PUSB_INTERFACE) rh;
rh->default_endp.pusb_endp_desc = NULL; //???
rh->time_out_count = 0;
rh->error_count = 0;
InitializeListHead(&pendp->urb_list);
pendp->flags = 0;
pendp->pusb_endp_desc = pendp_desc;
pendp->pusb_if = pif;
//add to device list
InsertTailList(&dev_mgr->dev_list, &rh->dev_link);
hcd->hcd_set_root_hub(hcd, rh);
status = hub_start_int_request(rh);
pdriver->driver_ext = 0;
}
return TRUE;
}
//to be the reverse of what init does, we assume that the timer is now killed
//int is disconnected and the hub thread will not process event anymore
BOOL
rh_destroy(PUSB_DEV pdev)
{
PUSB_DEV rh;
PLIST_ENTRY pthis, pnext;
PUSB_DEV_MANAGER dev_mgr;
if (pdev == NULL)
return FALSE;
dev_mgr = dev_mgr_from_dev(pdev);
//???
rh = pdev->hcd->hcd_get_root_hub(pdev->hcd);
if (rh == pdev)
{
//free all the buf
dev_mgr_free_device(dev_mgr, rh);
//dev_mgr->root_hub = NULL;
}
return TRUE;
}
VOID
rh_timer_svc_int_completion(PUSB_DEV pdev, PVOID context)
{
PUSB_EVENT pevent;
PURB purb;
ULONG status, i;
PHCD hcd;
USE_IRQL;
if (pdev == NULL || context == NULL)
return;
purb = (PURB) context;
lock_dev(pdev, TRUE);
if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
{
pdev->ref_count -= 2; // one for timer_svc and one for urb, for those rh requests
unlock_dev(pdev, TRUE);
usb_free_mem(purb);
usb_dbg_print(DBGLVL_MAXIMUM, ("rh_timer_svc_int_completion(): the dev is zomb, 0x%x\n", pdev));
return;
}
hcd = pdev->hcd;
if (purb->data_length < 1)
{
purb->status = STATUS_INVALID_PARAMETER;
unlock_dev(pdev, TRUE);
goto LBL_OUT;
}
pdev->hcd->hcd_dispatch(pdev->hcd, HCD_DISP_READ_RH_DEV_CHANGE, purb->data_buffer);
purb->status = STATUS_SUCCESS;
unlock_dev(pdev, TRUE);
LBL_OUT:
hcd->hcd_generic_urb_completion(purb, purb->context);
lock_dev(pdev, TRUE);
pdev->ref_count -= 2;
// one for timer_svc and one for urb, for those rh requests
// that completed immediately, the ref_count of the dev for
// that urb won't increment and for normal hub request
// completion, hcd_generic_urb_completion will be called
// by the xhci_dpc_callback, and the ref_count for the urb
// is maintained there. So only rh's timer-svc cares refcount
// when hcd_generic_urb_completion is called.
usb_dbg_print(DBGLVL_MAXIMUM, ("rh_timer_svc_int_completion(): rh's ref_count=0x%x\n", pdev->ref_count));
unlock_dev(pdev, TRUE);
usb_dbg_print(DBGLVL_MAXIMUM, ("rh_timer_svc_int_completion(): exitiing...\n"));
return;
}
VOID
rh_timer_svc_reset_port_completion(PUSB_DEV pdev, PVOID context)
{
PURB purb;
ULONG i;
USHORT port_num;
PHUB2_EXTENSION hub_ext;
PLIST_ENTRY pthis, pnext;
PUSB_DEV_MANAGER dev_mgr;
PUSB_CTRL_SETUP_PACKET psetup;
USE_IRQL;
if (pdev == NULL || context == NULL)
return;
dev_mgr = dev_mgr_from_dev(pdev); //readonly and hold ref_count
//block the rh polling
KeAcquireSpinLockAtDpcLevel(&dev_mgr->timer_svc_list_lock);
if (IsListEmpty(&dev_mgr->timer_svc_list) == FALSE)
{
ListFirst(&dev_mgr->timer_svc_list, pthis);
while (pthis)
{
if (((PTIMER_SVC) pthis)->pdev == pdev && ((PTIMER_SVC) pthis)->threshold == RH_INTERVAL)
{
((PTIMER_SVC) pthis)->threshold = RH_INTERVAL + 0x800000;
break;
}
ListNext(&dev_mgr->timer_svc_list, pthis, pnext);
pthis = pnext;
}
}
KeReleaseSpinLockFromDpcLevel(&dev_mgr->timer_svc_list_lock);
purb = (PURB) context;
psetup = (PUSB_CTRL_SETUP_PACKET) purb->setup_packet;
lock_dev(pdev, TRUE);
if (dev_state(pdev) == USB_DEV_STATE_ZOMB)
{
//purb->status = STATUS_ERROR;
//pdev->hcd->hcd_generic_urb_completion( purb, purb->context );
pdev->ref_count -= 2;
unlock_dev(pdev, TRUE);
usb_free_mem(purb);
return;
}
i = pdev->hcd->hcd_rh_reset_port(pdev->hcd, (UCHAR) psetup->wIndex);
hub_ext = hub_ext_from_dev(pdev);
{
USHORT temp;
PUCHAR pbuf;
if (psetup->wIndex < 16)
{
temp = 1 << psetup->wIndex;
pbuf = (PUCHAR) & temp;
if (temp > 128)
pbuf++;
hub_ext->int_data_buf[psetup->wIndex / 8] |= *pbuf;
if (i == TRUE)
hub_ext->rh_port_status[psetup->wIndex].wPortChange |= USB_PORT_STAT_C_RESET;
else // notify that is not a high speed device, will lost definitely
hub_ext->rh_port_status[psetup->wIndex].wPortChange |= USB_PORT_STAT_C_CONNECTION;
}
}
//???how to construct port status map
// decrease the timer_svc ref-count
pdev->ref_count--;
unlock_dev(pdev, TRUE);
purb->status = STATUS_SUCCESS;
//we delegate the completion to the rh_timer_svc_int_completion.
//this function is equivalent to hub_start_reset_port_completion
usb_free_mem(purb);
//expire the rh polling timer
KeAcquireSpinLockAtDpcLevel(&dev_mgr->timer_svc_list_lock);
if (IsListEmpty(&dev_mgr->timer_svc_list) == FALSE)
{
ListFirst(&dev_mgr->timer_svc_list, pthis);
while (pthis)
{
if (((PTIMER_SVC) pthis)->pdev == pdev &&
((PTIMER_SVC) pthis)->threshold == RH_INTERVAL + 0x800000)
{
((PTIMER_SVC) pthis)->counter = RH_INTERVAL;
((PTIMER_SVC) pthis)->threshold = RH_INTERVAL;
break;
}
ListNext(&dev_mgr->timer_svc_list, pthis, pnext);
pthis = pnext;
}
}
KeReleaseSpinLockFromDpcLevel(&dev_mgr->timer_svc_list_lock);
lock_dev(pdev, TRUE);
pdev->ref_count--;
unlock_dev(pdev, TRUE);
return;
}

View file

@ -19,8 +19,7 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "td.h"
#include "debug.h"
#include "usbdriver.h"
#define UHCI_MIN_TD_POOLS 4

View file

@ -5,10 +5,6 @@
#ifndef __UHCI_H__
#define __UHCI_H__
#include "usb.h"
#include "ntddk.h"
#include "hcd.h"
#define BOOL ULONG
#define LIST_HEAD LIST_ENTRY
#define PLIST_HEAD PLIST_ENTRY

View file

@ -19,13 +19,7 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "uhciver.h"
#include "td.h"
#include "hub.h"
#include "debug.h"
#include "stdio.h"
#include "usb.h"
#include <ntddk.h>
#include "usbdriver.h"
//----------------------------------------------------------
// uhci routines

View file

@ -19,18 +19,10 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "uhciver.h"
#include "ntddk.h"
#include "stdio.h"
#include "debug.h"
#include "umss.h"
#include "usb.h"
#include "hub.h"
#include "usbdriver.h"
// ULONG_PTR defining hack, to use ntddsci.h from reactos
// plus hack for __field_ecount for a new WDK
// Hack for __field_ecount for a new WDK
//FIXME: Move to a header file later
typedef unsigned long ULONG_PTR, *PULONG_PTR;
#ifndef __field_ecount
# define __field_ecount(x)
#endif

View file

@ -1,9 +1,6 @@
#ifndef __UMSS_H__
#define __UMSS_H__
#include "td.h"
#include "hub.h"
#define MAX_BULK_TRANSFER_LENGTH 0x100000
#define PROTOCOL_CBI 0x00

View file

@ -19,18 +19,13 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ntddk.h"
#include "usb.h"
#include "hub.h"
#include "debug.h"
#include "usbdriver.h"
LONG g_alloc_cnt = 0;
ULONG cpu_clock_freq = 0;
NTSTATUS usb_get_descriptor(PUSB_DEV pdev, PURB purb);
VOID usb_set_interface_completion(PURB purb, PVOID context);
NTSTATUS usb_set_interface(PURB purb);
PVOID

View file

@ -1,6 +1,5 @@
#ifndef __USBD_H__
#define __USBD_H__
#include "ntddk.h"
/*
* Some USB bandwidth allocation constants.
*/
@ -9,6 +8,8 @@
#define BOOL ULONG
#endif
typedef unsigned long ULONG_PTR, *PULONG_PTR;
#define USB2_HOST_DELAY 5 /* nsec, guess */
#define BW_HOST_DELAY 1000L /* nanoseconds */
#define BW_HUB_LS_SETUP 333L /* nanoseconds */
@ -779,8 +780,6 @@ typedef struct _CTRL_REQ_STACK
#pragma pack( pop, usb_align )
#include "td.h"
typedef struct _URB_HS_PIPE_CONTENT
{
ULONG trans_type : 2; // bit 0-1

View file

@ -0,0 +1,12 @@
#include <ntddk.h>
#include <stdio.h>
#include "debug.h"
#include "usb.h"
#include "hcd.h"
#include "td.h"
#include "irplist.h"
#include "events.h"
#include "devmgr.h"
#include "hub.h"
#include "umss.h"
#include "uhciver.h"

View file

@ -5,15 +5,18 @@
<library>hal</library>
<file>ehci.c</file>
<file>uhci.c</file>
<file>roothub.c</file>
<file>hub.c</file>
<file>td.c</file>
<file>usb.c</file>
<file>umss.c</file>
<file>bulkonly.c</file>
<file>cbi.c</file>
<file>devmgr.c</file>
<file>dmgrdisp.c</file>
<file>compdrv.c</file>
<file>etd.c</file>
<file>gendrv.c</file>
<file>usbdriver.rc</file>
<pch>usbdriver.h</pch>
</module>