2 * devmgr.c - USB driver stack project for Windows NT 4.0
4 * Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
6 * This program/include file is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program/include file is distributed in the hope that it will be
12 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * this program (in the main directory of the distribution, the file
18 * COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "usbdriver.h"
24 #define realloc_buf( pdEV, puRB ) \
28 data_buf = usb_alloc_mem( NonPagedPool, ( pdEV )->desc_buf_size += 1024 );\
29 RtlZeroMemory( data_buf, ( pdEV )->desc_buf_size );\
30 for( i = 0; i < ( LONG )( puRB )->context; i++ )\
32 data_buf[ i ] = ( pdEV )->desc_buf[ i ];\
34 usb_free_mem( ( pdEV )->desc_buf );\
35 ( pdEV )->desc_buf = data_buf;\
36 ( pdEV )->pusb_dev_desc = ( PUSB_DEVICE_DESC )( pdEV )->desc_buf;\
37 ( puRB )->data_buffer = &data_buf[ ( LONG ) ( puRB )->context ];\
41 //----------------------------------------------------------
43 USB_DRIVER g_driver_list
[DEVMGR_MAX_DRIVERS
];
44 USB_DEV_MANAGER g_dev_mgr
;
47 //----------------------------------------------------------
49 dev_mgr_set_if_driver(PUSB_DEV_MANAGER dev_mgr
,
52 PUSB_DEV pdev
//if pdev != NULL, we use pdev instead if_handle, and must have dev_lock acquired.
56 USE_BASIC_NON_PENDING_IRQL
;
58 if (dev_mgr
== NULL
|| if_handle
== 0 || pdriver
== NULL
)
61 i
= if_idx_from_handle(if_handle
);
64 if (dev_state(pdev
) < USB_DEV_STATE_BEFORE_ZOMB
)
66 pdev
->usb_config
->interf
[i
].pif_drv
= pdriver
;
72 if (usb_query_and_lock_dev(dev_mgr
, if_handle
, &pdev
) != STATUS_SUCCESS
)
76 if (dev_state(pdev
) != USB_DEV_STATE_ZOMB
)
78 pdev
->usb_config
->interf
[i
].pif_drv
= pdriver
;
80 unlock_dev(pdev
, TRUE
);
86 dev_mgr_set_driver(PUSB_DEV_MANAGER dev_mgr
,
87 DEV_HANDLE dev_handle
,
89 PUSB_DEV pdev
//if pdev != NULL, we use pdev instead if_handle
92 USE_BASIC_NON_PENDING_IRQL
;
94 if (dev_mgr
== NULL
|| dev_handle
== 0 || pdriver
== NULL
)
99 if (dev_state(pdev
) < USB_DEV_STATE_BEFORE_ZOMB
)
101 pdev
->dev_driver
= pdriver
;
107 if (usb_query_and_lock_dev(dev_mgr
, dev_handle
, &pdev
) != STATUS_SUCCESS
)
110 lock_dev(pdev
, FALSE
);
111 if (dev_state(pdev
) < USB_DEV_STATE_BEFORE_ZOMB
)
113 pdev
->dev_driver
= pdriver
;
115 unlock_dev(pdev
, FALSE
);
116 usb_unlock_dev(pdev
);
122 dev_mgr_post_event(PUSB_DEV_MANAGER dev_mgr
, PUSB_EVENT event
)
126 if (dev_mgr
== NULL
|| event
== NULL
)
129 KeAcquireSpinLock(&dev_mgr
->event_list_lock
, &old_irql
);
130 InsertTailList(&dev_mgr
->event_list
, &event
->event_link
);
131 KeReleaseSpinLock(&dev_mgr
->event_list_lock
, old_irql
);
133 KeSetEvent(&dev_mgr
->wake_up_event
, 0, FALSE
);
138 dev_mgr_driver_entry_init(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdrvr
)
142 RtlZeroMemory(pdrvr
, sizeof(USB_DRIVER
) * DEVMGR_MAX_DRIVERS
);
144 pdrvr
[RH_DRIVER_IDX
].driver_init
= rh_driver_init
; // in fact, this routine will init the rh device rather that the driver struct.
145 pdrvr
[RH_DRIVER_IDX
].driver_destroy
= rh_driver_destroy
; // we do not need rh to destroy currently, since that may means fatal hardware failure
147 pdrvr
[HUB_DRIVER_IDX
].driver_init
= hub_driver_init
; //no need, since dev_mgr is also a hub driver
148 pdrvr
[HUB_DRIVER_IDX
].driver_destroy
= hub_driver_destroy
;
150 pdrvr
[UMSS_DRIVER_IDX
].driver_init
= umss_if_driver_init
;
151 pdrvr
[UMSS_DRIVER_IDX
].driver_destroy
= umss_if_driver_destroy
;
153 pdrvr
[COMP_DRIVER_IDX
].driver_init
= compdev_driver_init
;
154 pdrvr
[COMP_DRIVER_IDX
].driver_destroy
= compdev_driver_destroy
;
156 pdrvr
[GEN_DRIVER_IDX
].driver_init
= gendrv_driver_init
;
157 pdrvr
[GEN_DRIVER_IDX
].driver_destroy
= gendrv_driver_destroy
;
159 pdrvr
[GEN_IF_DRIVER_IDX
].driver_init
= gendrv_if_driver_init
;
160 pdrvr
[GEN_IF_DRIVER_IDX
].driver_destroy
= gendrv_if_driver_destroy
;
162 pdrvr
[MOUSE_DRIVER_IDX
].driver_init
= mouse_driver_init
;
163 pdrvr
[MOUSE_DRIVER_IDX
].driver_destroy
= mouse_driver_destroy
;
165 //pdrvr[KEYBOARD_DRIVER_IDX].driver_init = gendrv_if_driver_init;
166 //pdrvr[KEYBOARD_DRIVER_IDX].driver_destroy = gendrv_if_driver_destroy;
170 dev_mgr_strobe(PUSB_DEV_MANAGER dev_mgr
)
173 HANDLE thread_handle
;
177 if (dev_mgr
->hcd_count
== 0)
180 dev_mgr
->term_flag
= FALSE
;
182 if (dev_mgr
->hcd_count
== 0)
185 KeInitializeSpinLock(&dev_mgr
->event_list_lock
);
186 InitializeListHead(&dev_mgr
->event_list
);
187 init_event_pool(&dev_mgr
->event_pool
);
189 pevent
= alloc_event(&dev_mgr
->event_pool
, 1);
192 destroy_event_pool(&dev_mgr
->event_pool
);
196 pevent
->flags
= USB_EVENT_FLAG_ACTIVE
;
197 pevent
->event
= USB_EVENT_INIT_DEV_MGR
;
199 pevent
->process_queue
= event_list_default_process_queue
;
200 pevent
->process_event
= (PROCESS_EVENT
)dev_mgr_event_init
;
202 pevent
->context
= (ULONG
) dev_mgr
;
204 KeInitializeEvent(&dev_mgr
->wake_up_event
, SynchronizationEvent
, FALSE
);
206 InsertTailList(&dev_mgr
->event_list
, &pevent
->event_link
);
208 if (PsCreateSystemThread(&thread_handle
, 0, NULL
, NULL
, NULL
, dev_mgr_thread
, dev_mgr
) != STATUS_SUCCESS
)
210 destroy_event_pool(&dev_mgr
->event_pool
);
214 ObReferenceObjectByHandle(thread_handle
,
215 THREAD_ALL_ACCESS
, NULL
, KernelMode
, (PVOID
*) & dev_mgr
->pthread
, NULL
);
217 ZwClose(thread_handle
);
223 dev_mgr_event_init(PUSB_DEV pdev
, //always null. we do not use this param
224 ULONG event
, ULONG context
, ULONG param
)
226 LARGE_INTEGER due_time
;
227 PUSB_DEV_MANAGER dev_mgr
;
230 usb_dbg_print(DBGLVL_MAXIMUM
, ("dev_mgr_event_init(): dev_mgr=0x%x, event=0x%x\n", context
, event
));
231 dev_mgr
= (PUSB_DEV_MANAGER
) context
;
235 if (event
!= USB_EVENT_INIT_DEV_MGR
)
238 //dev_mgr->root_hub = NULL;
239 KeInitializeTimer(&dev_mgr
->dev_mgr_timer
);
241 KeInitializeDpc(&dev_mgr
->dev_mgr_timer_dpc
, dev_mgr_timer_dpc_callback
, (PVOID
) dev_mgr
);
243 KeInitializeSpinLock(&dev_mgr
->timer_svc_list_lock
);
244 InitializeListHead(&dev_mgr
->timer_svc_list
);
245 init_timer_svc_pool(&dev_mgr
->timer_svc_pool
);
246 dev_mgr
->timer_click
= 0;
248 init_irp_list(&dev_mgr
->irp_list
);
250 KeInitializeSpinLock(&dev_mgr
->dev_list_lock
);
251 InitializeListHead(&dev_mgr
->dev_list
);
253 dev_mgr
->hub_count
= 0;
254 InitializeListHead(&dev_mgr
->hub_list
);
256 dev_mgr
->conn_count
= 0;
257 dev_mgr
->driver_list
= g_driver_list
;
259 dev_mgr_driver_entry_init(dev_mgr
, dev_mgr
->driver_list
);
261 for(i
= 0; i
< DEVMGR_MAX_DRIVERS
; i
++)
263 if (dev_mgr
->driver_list
[i
].driver_init
== NULL
)
266 if (dev_mgr
->driver_list
[i
].driver_init(dev_mgr
, &dev_mgr
->driver_list
[i
]) == FALSE
)
269 if (i
== DEVMGR_MAX_DRIVERS
)
271 due_time
.QuadPart
= -(DEV_MGR_TIMER_INTERVAL_NS
- 10);
273 KeSetTimerEx(&dev_mgr
->dev_mgr_timer
,
274 due_time
, DEV_MGR_TIMER_INTERVAL_MS
, &dev_mgr
->dev_mgr_timer_dpc
);
283 if (dev_mgr
->driver_list
[i
].driver_destroy
)
284 dev_mgr
->driver_list
[i
].driver_destroy(dev_mgr
, &dev_mgr
->driver_list
[i
]);
287 KeCancelTimer(&dev_mgr
->dev_mgr_timer
);
288 KeRemoveQueueDpc(&dev_mgr
->dev_mgr_timer_dpc
);
294 dev_mgr_destroy(PUSB_DEV_MANAGER dev_mgr
)
298 KeCancelTimer(&dev_mgr
->dev_mgr_timer
);
299 KeRemoveQueueDpc(&dev_mgr
->dev_mgr_timer_dpc
);
301 for(i
= DEVMGR_MAX_DRIVERS
- 1; i
>= 0; i
--)
302 dev_mgr
->driver_list
[i
].driver_destroy(dev_mgr
, &dev_mgr
->driver_list
[i
]);
304 destroy_irp_list(&dev_mgr
->irp_list
);
305 destroy_timer_svc_pool(&dev_mgr
->timer_svc_pool
);
306 destroy_event_pool(&dev_mgr
->event_pool
);
312 dev_mgr_thread(PVOID context
)
314 PUSB_DEV_MANAGER dev_mgr
;
316 PLIST_ENTRY pthis
, pnext
;
318 LARGE_INTEGER time_out
;
320 BOOLEAN dev_mgr_inited
;
324 dev_mgr
= (PUSB_DEV_MANAGER
) context
;
325 dev_mgr_inited
= FALSE
;
327 time_out
.u
.LowPart
= (10 * 1000 * 1000) * 100 - 1; //1 minutes
328 time_out
.u
.HighPart
= 0;
329 time_out
.QuadPart
= -time_out
.QuadPart
;
331 //usb_dbg_print( DBGLVL_MAXIMUM + 1, ( "dev_mgr_thread(): current uhci status=0x%x\n", uhci_status( dev_mgr->pdev_ext->uhci ) ) );
333 while (dev_mgr
->term_flag
== FALSE
)
335 KeAcquireSpinLock(&dev_mgr
->event_list_lock
, &old_irql
);
336 if (IsListEmpty(&dev_mgr
->event_list
) == TRUE
)
338 KeReleaseSpinLock(&dev_mgr
->event_list_lock
, old_irql
);
339 status
= KeWaitForSingleObject(&dev_mgr
->wake_up_event
, Executive
, KernelMode
, TRUE
, &time_out
);
344 usb_dbg_print( DBGLVL_MAXIMUM, ( "dev_mgr_thread(): current element in event list is 0x%x\n", \
345 dbg_count_list( &dev_mgr->event_list ) ) ); */
347 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
349 ListFirst(&dev_mgr
->event_list
, pthis
);
350 pevent
= struct_ptr(pthis
, USB_EVENT
, event_link
);
352 while (pevent
&& ((pevent
->flags
& USB_EVENT_FLAG_ACTIVE
) == 0))
355 ListNext(&dev_mgr
->event_list
, &pevent
->event_link
, pnext
);
356 pevent
= struct_ptr(pnext
, USB_EVENT
, event_link
);
361 if (pevent
->process_queue
== NULL
)
362 pevent
->process_queue
= event_list_default_process_queue
;
364 pevent
->process_queue(&dev_mgr
->event_list
, &dev_mgr
->event_pool
, pevent
, &usb_event
);
369 KeReleaseSpinLock(&dev_mgr
->event_list_lock
, old_irql
);
370 status
= KeWaitForSingleObject(&dev_mgr
->wake_up_event
, Executive
, KernelMode
, TRUE
, &time_out
// 10 minutes
373 usb_dbg_print(DBGLVL_MAXIMUM
, ("dev_mgr_thread(): wake up, reason=0x%x\n", status
));
377 KeReleaseSpinLock(&dev_mgr
->event_list_lock
, old_irql
);
379 if (usb_event
.process_event
)
381 usb_event
.process_event(usb_event
.pdev
, usb_event
.event
, usb_event
.context
, usb_event
.param
);
385 event_list_default_process_event(usb_event
.pdev
,
386 usb_event
.event
, usb_event
.context
, usb_event
.param
);
392 for(i
= 0; i
< dev_mgr
->hcd_count
; i
++)
393 dev_mgr_disconnect_dev(dev_mgr
->hcd_array
[i
]->hcd_get_root_hub(dev_mgr
->hcd_array
[i
]));
394 dev_mgr_destroy(dev_mgr
);
396 PsTerminateSystemThread(0);
401 dev_mgr_timer_dpc_callback(PKDPC Dpc
, PVOID context
, PVOID SystemArgument1
, PVOID SystemArgument2
)
403 PUSB_DEV_MANAGER dev_mgr
;
405 PLIST_ENTRY pthis
, pnext
;
406 static ULONG ticks
= 0;
409 dev_mgr
= (PUSB_DEV_MANAGER
) context
;
413 dev_mgr
->timer_click
++;
414 InitializeListHead(&templist
);
416 KeAcquireSpinLockAtDpcLevel(&dev_mgr
->timer_svc_list_lock
);
417 if (IsListEmpty(&dev_mgr
->timer_svc_list
) == TRUE
)
419 KeReleaseSpinLockFromDpcLevel(&dev_mgr
->timer_svc_list_lock
);
423 ListFirst(&dev_mgr
->timer_svc_list
, pthis
);
426 ((PTIMER_SVC
) pthis
)->counter
++;
427 ListNext(&dev_mgr
->timer_svc_list
, pthis
, pnext
);
428 if (((PTIMER_SVC
) pthis
)->counter
>= ((PTIMER_SVC
) pthis
)->threshold
)
430 RemoveEntryList(pthis
);
431 InsertTailList(&templist
, pthis
);
436 KeReleaseSpinLockFromDpcLevel(&dev_mgr
->timer_svc_list_lock
);
439 while (IsListEmpty(&templist
) == FALSE
)
441 pthis
= RemoveHeadList(&templist
);
442 ((PTIMER_SVC
) pthis
)->func(((PTIMER_SVC
) pthis
)->pdev
, (PVOID
) ((PTIMER_SVC
) pthis
)->context
);
443 KeAcquireSpinLockAtDpcLevel(&dev_mgr
->timer_svc_list_lock
);
444 free_timer_svc(&dev_mgr
->timer_svc_pool
, (PTIMER_SVC
) pthis
);
445 KeReleaseSpinLockFromDpcLevel(&dev_mgr
->timer_svc_list_lock
);
451 dev_mgr_request_timer_svc(PUSB_DEV_MANAGER dev_mgr
,
452 PUSB_DEV pdev
, ULONG context
, ULONG due_time
, TIMER_SVC_HANDLER handler
)
454 PTIMER_SVC timer_svc
;
457 if (dev_mgr
== NULL
|| pdev
== NULL
|| due_time
== 0 || handler
== NULL
)
460 KeAcquireSpinLock(&dev_mgr
->timer_svc_list_lock
, &old_irql
);
461 timer_svc
= alloc_timer_svc(&dev_mgr
->timer_svc_pool
, 1);
462 if (timer_svc
== NULL
)
464 KeReleaseSpinLock(&dev_mgr
->timer_svc_list_lock
, old_irql
);
467 timer_svc
->pdev
= pdev
;
468 timer_svc
->threshold
= due_time
;
469 timer_svc
->func
= handler
;
470 timer_svc
->counter
= 0;
472 InsertTailList(&dev_mgr
->timer_svc_list
, &timer_svc
->timer_svc_link
);
473 KeReleaseSpinLock(&dev_mgr
->timer_svc_list_lock
, old_irql
);
478 dev_mgr_alloc_addr(PUSB_DEV_MANAGER dev_mgr
, PHCD hcd
)
480 // alloc a usb addr for the device within 1-128
481 if (dev_mgr
== NULL
|| hcd
== NULL
)
484 return hcd
->hcd_alloc_addr(hcd
);
488 dev_mgr_free_addr(PUSB_DEV_MANAGER dev_mgr
, PUSB_DEV pdev
, BYTE addr
)
494 if (dev_mgr
== NULL
|| pdev
== NULL
)
500 hcd
->hcd_free_addr(hcd
, addr
);
505 dev_mgr_alloc_device(PUSB_DEV_MANAGER dev_mgr
, PHCD hcd
)
510 if ((addr
= dev_mgr_alloc_addr(dev_mgr
, hcd
)) == 0xff)
513 pdev
= usb_alloc_mem(NonPagedPool
, sizeof(USB_DEV
));
517 RtlZeroMemory(pdev
, sizeof(USB_DEV
));
519 KeInitializeSpinLock(&pdev
->dev_lock
);
520 dev_mgr
->conn_count
++;
522 pdev
->flags
= USB_DEV_STATE_RESET
; //class | cur_state | low speed
524 pdev
->dev_addr
= addr
;
528 pdev
->dev_id
= dev_mgr
->conn_count
; //will be used to compose dev_handle
530 InitializeListHead(&pdev
->default_endp
.urb_list
);
531 pdev
->default_endp
.pusb_if
= (PUSB_INTERFACE
) pdev
;
532 pdev
->default_endp
.flags
= USB_ENDP_FLAG_DEFAULT_ENDP
; //toggle | busy-count | stall | default-endp
538 dev_mgr_free_device(PUSB_DEV_MANAGER dev_mgr
, PUSB_DEV pdev
)
540 if (pdev
== NULL
|| dev_mgr
== NULL
)
543 dev_mgr_free_addr(dev_mgr
, pdev
, pdev
->dev_addr
);
544 if (pdev
->usb_config
&& pdev
!= pdev
->hcd
->hcd_get_root_hub(pdev
->hcd
))
546 //root hub has its config and desc buf allocated together,
547 //so no usb_config allocated seperately
548 dev_mgr_destroy_usb_config(pdev
->usb_config
);
549 pdev
->usb_config
= NULL
;
553 usb_free_mem(pdev
->desc_buf
);
554 pdev
->desc_buf
= NULL
;
561 //called when a disconnect is detected on the port
563 dev_mgr_disconnect_dev(PUSB_DEV pdev
)
565 PLIST_ENTRY pthis
, pnext
;
566 PHUB2_EXTENSION phub_ext
= NULL
;
567 PUSB_CONFIGURATION pconfig
;
568 PUSB_DEV_MANAGER dev_mgr
;
570 BOOLEAN is_hub
, found
;
574 USE_NON_PENDING_IRQL
;
581 usb_dbg_print(DBGLVL_MAXIMUM
, ("dev_mgr_disconnect_dev(): entering, pdev=0x%x\n", pdev
));
582 lock_dev(pdev
, FALSE
);
583 pdev
->flags
&= ~USB_DEV_STATE_MASK
;
584 pdev
->flags
|= USB_DEV_STATE_BEFORE_ZOMB
;
585 dev_mgr
= dev_mgr_from_dev(pdev
);
586 unlock_dev(pdev
, FALSE
);
588 // notify dev_driver that the dev stops function before any operations
589 if (pdev
->dev_driver
&& pdev
->dev_driver
->disp_tbl
.dev_stop
)
590 pdev
->dev_driver
->disp_tbl
.dev_stop(dev_mgr
, dev_handle_from_dev(pdev
));
592 //safe to use the dev pointer in this function.
593 lock_dev(pdev
, FALSE
);
594 pdev
->flags
&= ~USB_DEV_STATE_MASK
;
595 pdev
->flags
|= USB_DEV_STATE_ZOMB
;
597 dev_id
= pdev
->dev_id
;
598 unlock_dev(pdev
, FALSE
);
603 hcd
->hcd_remove_device(hcd
, pdev
);
605 //disconnect its children
606 if ((pdev
->flags
& USB_DEV_CLASS_MASK
) == USB_DEV_CLASS_HUB
||
607 (pdev
->flags
& USB_DEV_CLASS_MASK
) == USB_DEV_CLASS_ROOT_HUB
)
609 phub_ext
= hub_ext_from_dev(pdev
);
612 for(i
= 1; i
<= phub_ext
->port_count
; i
++)
614 if (phub_ext
->child_dev
[i
])
616 dev_mgr_disconnect_dev(phub_ext
->child_dev
[i
]);
617 phub_ext
->child_dev
[i
] = NULL
;
623 pconfig
= pdev
->usb_config
;
625 //remove event belong to the dev
626 is_hub
= ((pdev
->flags
& USB_DEV_CLASS_MASK
) == USB_DEV_CLASS_HUB
);
628 if (phub_ext
&& is_hub
)
630 for(i
= 1; i
<= phub_ext
->port_count
; i
++)
632 found
= hub_remove_reset_event(pdev
, i
, FALSE
);
638 //free event of the dev from the event list
639 KeAcquireSpinLock(&dev_mgr
->event_list_lock
, &old_irql
);
640 ListFirst(&dev_mgr
->event_list
, pthis
);
643 ListNext(&dev_mgr
->event_list
, pthis
, pnext
);
644 if (((PUSB_EVENT
) pthis
)->pdev
== pdev
)
647 RemoveEntryList(pthis
);
648 if ((((PUSB_EVENT
) pthis
)->flags
& USB_EVENT_FLAG_QUE_TYPE
) != USB_EVENT_FLAG_NOQUE
)
650 //has a queue, re-insert the queue
651 if ((p1
= (PLIST_ENTRY
) ((PUSB_EVENT
) pthis
)->pnext
))
653 InsertHeadList(&dev_mgr
->event_list
, p1
);
654 free_event(&dev_mgr
->event_pool
, struct_ptr(pthis
, USB_EVENT
, event_link
));
656 //note: this queue will be examined again in the next loop
657 //to find the matched dev in the queue
661 free_event(&dev_mgr
->event_pool
, struct_ptr(pthis
, USB_EVENT
, event_link
));
663 else if (((((PUSB_EVENT
) pthis
)->flags
& USB_EVENT_FLAG_QUE_TYPE
)
664 != USB_EVENT_FLAG_NOQUE
) && ((PUSB_EVENT
) pthis
)->pnext
)
666 //has a queue, examine the queue
668 p1
= (PUSB_EVENT
) pthis
;
672 if (p2
->pdev
== pdev
)
674 p1
->pnext
= p2
->pnext
;
676 free_event(&dev_mgr
->event_pool
, p2
);
688 KeReleaseSpinLock(&dev_mgr
->event_list_lock
, old_irql
);
690 // found indicates the reset event on one of the dev's port in process
692 hub_start_next_reset_port(dev_mgr_from_dev(pdev
), FALSE
);
694 // remove timer-svc belonging to the dev
695 KeAcquireSpinLock(&dev_mgr
->timer_svc_list_lock
, &old_irql
);
696 ListFirst(&dev_mgr
->timer_svc_list
, pthis
);
700 ListNext(&dev_mgr
->timer_svc_list
, pthis
, pnext
);
701 if (((PUSB_EVENT
) pthis
)->pdev
== pdev
)
703 RemoveEntryList(pthis
);
704 free_timer_svc(&dev_mgr
->timer_svc_pool
, struct_ptr(pthis
, TIMER_SVC
, timer_svc_link
));
709 KeReleaseSpinLock(&dev_mgr
->timer_svc_list_lock
, old_irql
);
711 // release the refcount
714 lock_dev(pdev
, FALSE
);
715 pdev
->ref_count
-= i
;
716 unlock_dev(pdev
, FALSE
);
719 // wait for all the reference count be released
722 LARGE_INTEGER interval
;
724 lock_dev(pdev
, FALSE
);
725 if (pdev
->ref_count
== 0)
727 unlock_dev(pdev
, FALSE
);
730 unlock_dev(pdev
, FALSE
);
732 interval
.QuadPart
= -20000;
733 KeDelayExecutionThread(KernelMode
, FALSE
, &interval
);
736 if (pdev
->dev_driver
&& pdev
->dev_driver
->disp_tbl
.dev_disconnect
)
737 pdev
->dev_driver
->disp_tbl
.dev_disconnect(dev_mgr
, dev_handle_from_dev(pdev
));
739 // we put it here to let handle valid before disconnect
740 KeAcquireSpinLock(&dev_mgr
->dev_list_lock
, &old_irql
);
741 ListFirst(&dev_mgr
->dev_list
, pthis
);
744 if (((PUSB_DEV
) pthis
) == pdev
)
746 RemoveEntryList(pthis
);
749 ListNext(&dev_mgr
->dev_list
, pthis
, pnext
);
752 KeReleaseSpinLock(&dev_mgr
->dev_list_lock
, old_irql
);
755 if (pdev
!= pdev
->hcd
->hcd_get_root_hub(pdev
->hcd
))
757 dev_mgr_free_device(dev_mgr
, pdev
);
761 //rh_destroy( pdev );
763 //destroy it in dev_mgr_destroy
769 //called in hub_set_address_completion
771 dev_mgr_start_config_dev(PUSB_DEV pdev
)
774 PUSB_CTRL_SETUP_PACKET psetup
;
777 USE_BASIC_NON_PENDING_IRQL
;
779 hcd_dbg_print(DBGLVL_MAXIMUM
, ("dev_mgr_start_config_dev: pdev=%p\n", pdev
));
784 lock_dev(pdev
, TRUE
);
785 if (dev_state(pdev
) == USB_DEV_STATE_ZOMB
)
787 unlock_dev(pdev
, TRUE
);
793 //first, get device descriptor
794 purb
= usb_alloc_mem(NonPagedPool
, sizeof(URB
));
795 data_buf
= usb_alloc_mem(NonPagedPool
, 512);
798 unlock_dev(pdev
, TRUE
);
802 RtlZeroMemory(purb
, sizeof(URB
));
803 RtlZeroMemory(data_buf
, 512);
805 psetup
= (PUSB_CTRL_SETUP_PACKET
) purb
->setup_packet
;
807 purb
->data_buffer
= data_buf
; // user data
808 purb
->data_length
= 8; // get partial desc
810 pdev
->desc_buf
= data_buf
;
811 pdev
->desc_buf_size
= 512;
814 purb
->pendp
= &pdev
->default_endp
; //pipe for current transfer
816 purb
->completion
= dev_mgr_get_desc_completion
;
819 InitializeListHead(&purb
->trasac_list
);
821 psetup
->bmRequestType
= 0x80;
822 psetup
->bRequest
= USB_REQ_GET_DESCRIPTOR
;
823 psetup
->wValue
= (USB_DT_DEVICE
<< 8) | 0;
825 psetup
->wLength
= 8; //sizeof( USB_DEVICE_DESC );
826 unlock_dev(pdev
, TRUE
);
828 if (hcd
->hcd_submit_urb(hcd
, pdev
, purb
->pendp
, purb
) != STATUS_PENDING
)
831 usb_free_mem(data_buf
);
838 dev_mgr_get_desc_completion(PURB purb
, PVOID context
)
841 PUSB_CONFIGURATION_DESC pconfig_desc
;
843 PUSB_DEV_MANAGER dev_mgr
;
845 PUSB_CTRL_SETUP_PACKET psetup
;
848 USE_BASIC_NON_PENDING_IRQL
;;
853 hcd_dbg_print(DBGLVL_MAXIMUM
,
854 ("dev_mgr_get_desc_completion: purb->reference=%d\n", purb
->reference
));
859 if (pdev
== NULL
|| pendp
== NULL
)
866 lock_dev(pdev
, TRUE
);
867 if (dev_state(pdev
) == USB_DEV_STATE_ZOMB
)
869 unlock_dev(pdev
, TRUE
);
873 pendp
= &pdev
->default_endp
;
874 dev_mgr
= dev_mgr_from_dev(pdev
);
876 psetup
= (PUSB_CTRL_SETUP_PACKET
) purb
->setup_packet
;
878 if (usb_error(purb
->status
))
880 unlock_dev(pdev
, TRUE
);
881 hcd_dbg_print(DBGLVL_MAXIMUM
,
882 ("dev_mgr_get_desc_completion: can not get dev desc ref=0x%x, status=0x%x\n",
883 purb
->reference
, purb
->status
));
887 switch (purb
->reference
)
891 //only partial dev_desc
892 //enable the dev specific default endp maxpacketsize
893 pdev
->pusb_dev_desc
= (PUSB_DEVICE_DESC
) purb
->data_buffer
;
895 psetup
= (PUSB_CTRL_SETUP_PACKET
) purb
->setup_packet
;
896 psetup
->wLength
= sizeof(USB_DEVICE_DESC
);
898 //get the complete dev_desc
901 purb
->data_length
= sizeof(USB_DEVICE_DESC
);
903 unlock_dev(pdev
, TRUE
);
905 status
= hcd
->hcd_submit_urb(hcd
, pdev
, pendp
, purb
);
906 if (status
!= STATUS_PENDING
)
914 //let's begin to get config descriptors.
915 if (pdev
->pusb_dev_desc
->bNumConfigurations
== 0)
917 unlock_dev(pdev
, TRUE
);
921 purb
->data_buffer
+= sizeof(USB_DEVICE_DESC
);
922 purb
->data_length
= 8;
924 purb
->context
= (PVOID
) sizeof(USB_DEVICE_DESC
);
927 psetup
->wValue
= (USB_DT_CONFIG
<< 8) | 0;
929 unlock_dev(pdev
, TRUE
);
931 status
= hcd
->hcd_submit_urb(hcd
, pdev
, pendp
, purb
);
933 if (status
!= STATUS_PENDING
)
942 config_idx
= (purb
->reference
>> 1) - 1;
943 if ((purb
->reference
& 1) == 0)
945 //partial config desc is obtained.
946 pconfig_desc
= (PUSB_CONFIGURATION_DESC
) purb
->data_buffer
;
947 if (pconfig_desc
->wTotalLength
>= 1024)
950 unlock_dev(pdev
, TRUE
);
955 if (pconfig_desc
->wTotalLength
> (USHORT
) (pdev
->desc_buf_size
- (LONG
) purb
->context
))
957 //rewind the 8-byte hdr
958 *((PULONG
) & context
) -= 8;
959 realloc_buf(pdev
, purb
);
961 purb
->data_length
= pconfig_desc
->wTotalLength
;
962 psetup
->wLength
= pconfig_desc
->wTotalLength
;
964 unlock_dev(pdev
, TRUE
);
965 status
= hcd
->hcd_submit_urb(hcd
, pdev
, pendp
, purb
);
966 if (status
!= STATUS_PENDING
)
972 //complete desc is returned.
973 if (config_idx
+ 1 < pdev
->pusb_dev_desc
->bNumConfigurations
)
975 //still have configurations left
976 *((PULONG
) & context
) += psetup
->wLength
;
977 purb
->data_buffer
= &pdev
->desc_buf
[(LONG
) context
];
978 purb
->data_length
= 8;
980 psetup
->wValue
= (((USB_DT_CONFIG
) << 8) | (config_idx
+ 1));
982 purb
->context
= context
;
984 if (((LONG
) context
) + 8 > pdev
->desc_buf_size
)
985 realloc_buf(pdev
, purb
);
988 unlock_dev(pdev
, TRUE
);
989 status
= hcd
->hcd_submit_urb(hcd
, pdev
, pendp
, purb
);
990 if (status
!= STATUS_PENDING
)
995 //config descriptors have all been fetched
996 unlock_dev(pdev
, TRUE
);
1000 // load driver for the device
1001 dev_mgr_start_select_driver(pdev
);
1012 lock_dev(pdev
, TRUE
);
1013 if (dev_state(pdev
) != USB_DEV_STATE_ZOMB
)
1017 usb_free_mem(pdev
->desc_buf
);
1018 pdev
->desc_buf_size
= 0;
1019 pdev
->desc_buf
= NULL
;
1020 pdev
->pusb_dev_desc
= NULL
;
1021 pdev
->usb_config
= NULL
;
1024 unlock_dev(pdev
, TRUE
);
1030 dev_mgr_start_select_driver(PUSB_DEV pdev
)
1032 PUSB_DEV_MANAGER dev_mgr
;
1036 USE_BASIC_NON_PENDING_IRQL
;;
1041 dev_mgr
= dev_mgr_from_dev(pdev
);
1042 KeAcquireSpinLockAtDpcLevel(&dev_mgr
->event_list_lock
);
1043 lock_dev(pdev
, TRUE
);
1045 if (dev_state(pdev
) == USB_DEV_STATE_ZOMB
)
1051 pevent
= alloc_event(&dev_mgr
->event_pool
, 1);
1057 pevent
->flags
= USB_EVENT_FLAG_ACTIVE
;
1058 pevent
->event
= USB_EVENT_DEFAULT
;
1059 pevent
->pdev
= pdev
;
1060 pevent
->context
= 0;
1062 pevent
->pnext
= 0; //vertical queue for serialized operation
1063 pevent
->process_event
= dev_mgr_event_select_driver
;
1064 pevent
->process_queue
= event_list_default_process_queue
;
1066 InsertTailList(&dev_mgr
->event_list
, &pevent
->event_link
);
1067 KeSetEvent(&dev_mgr
->wake_up_event
, 0, FALSE
);
1071 unlock_dev(pdev
, TRUE
);
1072 KeReleaseSpinLockFromDpcLevel(&dev_mgr
->event_list_lock
);
1077 dev_mgr_connect_to_dev(PVOID Parameter
)
1080 DEV_HANDLE dev_handle
;
1082 PUSB_DRIVER pdriver
;
1083 PDEV_CONNECT_DATA pcd
= (PDEV_CONNECT_DATA
) Parameter
;
1084 PUSB_DEV_MANAGER dev_mgr
;
1085 DEV_CONNECT_DATA param
;
1089 dev_handle
= pcd
->dev_handle
;
1090 pdriver
= pcd
->pdriver
;
1091 dev_mgr
= pcd
->dev_mgr
;
1093 param
.dev_mgr
= dev_mgr
;
1094 param
.pdriver
= pdriver
;
1095 param
.dev_handle
= 0; //not used
1097 status
= usb_query_and_lock_dev(dev_mgr
, dev_handle
, &pdev
);
1098 if (status
!= STATUS_SUCCESS
)
1101 usb_dbg_print(DBGLVL_MAXIMUM
, ("dev_mgr_connect_to_dev(): about to call driver's dev_connect\n"));
1102 status
= pdriver
->disp_tbl
.dev_connect(¶m
, dev_handle
);
1103 usb_unlock_dev(pdev
);
1108 dev_mgr_event_select_driver(PUSB_DEV pdev
, ULONG event
, ULONG context
, ULONG param
)
1110 PUSB_DEV_MANAGER dev_mgr
;
1111 PUSB_DRIVER pdriver
, pcand
;
1112 LONG credit
, match
, i
;
1113 DEV_HANDLE handle
= 0;
1114 DEV_CONNECT_DATA cd
;
1116 USE_BASIC_NON_PENDING_IRQL
;
1118 UNREFERENCED_PARAMETER(param
);
1119 UNREFERENCED_PARAMETER(context
);
1121 usb_dbg_print(DBGLVL_MAXIMUM
, ("dev_mgr_event_select_driver(): pdev=%p event=0x%x\n", pdev
, event
));
1126 lock_dev(pdev
, FALSE
);
1127 if (dev_state(pdev
) == USB_DEV_STATE_ZOMB
)
1129 unlock_dev(pdev
, FALSE
);
1132 dev_mgr
= dev_mgr_from_dev(pdev
);
1136 for(i
= HUB_DRIVER_IDX
; i
< DEVMGR_MAX_DRIVERS
; i
++)
1138 //bypass root-hub driver with idx zero
1139 pdriver
= (PUSB_DRIVER
) & dev_mgr
->driver_list
[i
];
1141 if (pdriver
->driver_desc
.flags
& USB_DRIVER_FLAG_DEV_CAPABLE
)
1142 credit
= dev_mgr_score_driver_for_dev(dev_mgr
, pdriver
, pdev
->pusb_dev_desc
);
1148 pcand
= pdriver
, match
= credit
;
1154 // we set class driver here
1155 // pdev->dev_driver = pcand;
1156 handle
= usb_make_handle(pdev
->dev_id
, 0, 0);
1158 unlock_dev(pdev
, FALSE
);
1163 cd
.dev_handle
= handle
;
1165 cd
.dev_mgr
= dev_mgr
;
1167 if (dev_mgr_connect_to_dev(&cd
))
1170 // ExInitializeWorkItem( pwork_item, dev_mgr_connect_to_dev, ( PVOID )pcd );
1171 // ExQueueWorkItem( pwork_item, DelayedWorkQueue );
1173 cd
.dev_handle
= handle
;
1174 cd
.pdriver
= &dev_mgr
->driver_list
[GEN_DRIVER_IDX
];
1175 cd
.dev_mgr
= dev_mgr
;
1176 dev_mgr_connect_to_dev(&cd
);
1181 dev_mgr_build_usb_endp(PUSB_INTERFACE pif
, PUSB_ENDPOINT pendp
, PUSB_ENDPOINT_DESC pendp_desc
)
1183 if (pendp
== NULL
|| pif
== NULL
|| pendp_desc
== NULL
)
1187 InitializeListHead(&pendp
->urb_list
); //pending urb queue
1188 pendp
->pusb_if
= pif
;
1189 pendp
->pusb_endp_desc
= pendp_desc
;
1194 dev_mgr_build_usb_if(PUSB_CONFIGURATION pcfg
, PUSB_INTERFACE pif
, PUSB_INTERFACE_DESC pif_desc
, BOOLEAN alt_if
)
1197 PUSB_ENDPOINT_DESC pendp_desc
;
1199 if (pcfg
== NULL
|| pif
== NULL
|| pif_desc
== NULL
)
1202 if (alt_if
== FALSE
)
1204 pif
->endp_count
= pif_desc
->bNumEndpoints
> MAX_ENDPS_PER_IF
1205 ? MAX_ENDPS_PER_IF
: pif_desc
->bNumEndpoints
;
1207 pif
->pif_drv
= NULL
;
1208 pif
->pusb_config
= pcfg
;
1209 pif
->pusb_if_desc
= pif_desc
;
1210 pif
->if_ext_size
= 0;
1213 InitializeListHead(&pif
->altif_list
);
1214 pif
->altif_count
= 0;
1216 pendp_desc
= (PUSB_ENDPOINT_DESC
) (&((PBYTE
) pif_desc
)[sizeof(USB_INTERFACE_DESC
)]);
1218 for(i
= 0; i
< pif
->endp_count
; i
++, pendp_desc
++)
1220 dev_mgr_build_usb_endp(pif
, &pif
->endp
[i
], pendp_desc
);
1225 PUSB_INTERFACE paltif
;
1226 PLIST_ENTRY pthis
, pnext
;
1229 paltif
= usb_alloc_mem(NonPagedPool
, sizeof(USB_INTERFACE
));
1230 RtlZeroMemory(paltif
, sizeof(USB_INTERFACE
));
1231 InsertTailList(&pif
->altif_list
, &paltif
->altif_list
);
1232 paltif
->pif_drv
= NULL
;
1233 paltif
->pusb_config
= pcfg
;
1234 paltif
->pusb_if_desc
= pif_desc
;
1235 paltif
->if_ext_size
= 0;
1236 paltif
->if_ext
= NULL
;
1237 paltif
->endp_count
= pif_desc
->bNumEndpoints
> MAX_ENDPS_PER_IF
1238 ? MAX_ENDPS_PER_IF
: pif_desc
->bNumEndpoints
;
1240 ListFirst(&pif
->altif_list
, pthis
);
1244 //synchronize the altif_count;
1245 PUSB_INTERFACE pthis_if
;
1246 pthis_if
= (PUSB_INTERFACE
) (((PBYTE
) pthis
) - offsetof(USB_INTERFACE
, altif_list
));
1247 pthis_if
->altif_count
= pif
->altif_count
;
1248 ListNext(&pif
->altif_list
, pthis
, pnext
);
1256 dev_mgr_build_usb_config(PUSB_DEV pdev
, PBYTE pbuf
, ULONG config_val
, LONG config_count
)
1258 PUSB_CONFIGURATION pcfg
;
1259 PUSB_INTERFACE_DESC pif_desc
;
1264 if (pdev
== NULL
|| pbuf
== NULL
)
1265 return STATUS_INVALID_PARAMETER
;
1268 pdev
->usb_config
= usb_alloc_mem(NonPagedPool
, sizeof(USB_CONFIGURATION
));
1269 pcfg
= pdev
->usb_config
;
1271 if (pdev
->usb_config
== NULL
)
1272 return STATUS_NO_MEMORY
;
1274 RtlZeroMemory(pcfg
, sizeof(USB_CONFIGURATION
));
1275 pcfg
->pusb_config_desc
= usb_find_config_desc_by_val(pbuf
, config_val
, config_count
);
1277 if (pcfg
->pusb_config_desc
== NULL
)
1280 pdev
->usb_config
= NULL
;
1281 return STATUS_UNSUCCESSFUL
;
1283 pcfg
->if_count
= pcfg
->pusb_config_desc
->bNumInterfaces
;
1284 pcfg
->pusb_dev
= pdev
;
1285 pif_desc
= (PUSB_INTERFACE_DESC
) & ((PBYTE
) pcfg
->pusb_config_desc
)[sizeof(USB_CONFIGURATION_DESC
)];
1286 if_count
= pcfg
->if_count
;
1288 for(i
= 0; i
< if_count
; i
++, pif_desc
++)
1290 if (pif_desc
->bAlternateSetting
== 0)
1292 dev_mgr_build_usb_if(pcfg
, &pcfg
->interf
[i
], pif_desc
, FALSE
);
1297 pif
= &pcfg
->interf
[i
];
1298 dev_mgr_build_usb_if(pcfg
, pif
, pif_desc
, TRUE
);
1301 return STATUS_SUCCESS
;
1305 dev_mgr_destroy_usb_config(PUSB_CONFIGURATION pcfg
)
1314 for(i
= 0; i
< pcfg
->if_count
; i
++)
1316 pif
= &pcfg
->interf
[i
];
1318 if (pif
->altif_count
)
1320 ListFirst(&pif
->altif_list
, pthis
);
1323 PUSB_INTERFACE pthis_if
;
1324 pthis_if
= (PUSB_INTERFACE
) (((PBYTE
) pthis
) - offsetof(USB_INTERFACE
, altif_list
));
1325 RemoveEntryList(pthis
);
1326 usb_free_mem(pthis_if
);
1327 if (IsListEmpty(&pif
->altif_list
) == TRUE
)
1330 ListFirst(&pif
->altif_list
, pthis
);
1338 #define is_dev_product_match( pdriVER, pdev_DESC ) \
1339 ( ( pdriVER )->driver_desc.vendor_id == ( pdev_DESC )->idVendor \
1340 && ( pdriVER )->driver_desc.product_id == ( pdev_DESC )->idProduct )
1343 dev_mgr_score_driver_for_dev(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdriver
, PUSB_DEVICE_DESC pdev_desc
)
1347 UNREFERENCED_PARAMETER(dev_mgr
);
1349 //assume supports all the sub_class are supported if sub_class is zero
1350 if (pdriver
->driver_desc
.dev_class
== pdev_desc
->bDeviceClass
)
1352 if (pdriver
->driver_desc
.dev_sub_class
== 0 && pdriver
->driver_desc
.dev_protocol
== 0)
1354 else if (pdriver
->driver_desc
.dev_sub_class
== pdev_desc
->bDeviceSubClass
)
1356 if (pdriver
->driver_desc
.dev_protocol
== 0)
1358 else if (pdriver
->driver_desc
.dev_protocol
== pdev_desc
->bDeviceProtocol
)
1363 if (is_dev_product_match(pdriver
, pdev_desc
))
1370 dev_mgr_score_driver_for_if(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdriver
, PUSB_INTERFACE_DESC pif_desc
)
1375 || !(pdriver
->driver_desc
.flags
& USB_DRIVER_FLAG_IF_CAPABLE
) || pif_desc
== NULL
|| dev_mgr
== NULL
)
1378 if (is_header_match((PBYTE
) pif_desc
, USB_DT_INTERFACE
) == FALSE
)
1384 if ((pdriver
->driver_desc
.if_class
== pif_desc
->bInterfaceClass
))
1386 if (pdriver
->driver_desc
.if_sub_class
== 0 && pdriver
->driver_desc
.if_protocol
== 0)
1388 if (pdriver
->driver_desc
.if_sub_class
== pif_desc
->bInterfaceSubClass
)
1390 if (pdriver
->driver_desc
.if_protocol
== 0)
1392 if (pdriver
->driver_desc
.if_protocol
== pif_desc
->bInterfaceProtocol
)
1402 #define is_equal_driver( pd1, pd2, ret ) \
1406 PUSB_DRIVER pdr1, pdr2;\
1407 pdr1 = ( PUSB_DRIVER )( pd1 );\
1408 pdr2 = ( PUSB_DRIVER ) ( pd2 );\
1409 for( i = 0; i < 16; i++ )\
1411 if( pdr1->driver_name[ i ] != pdr2->driver_name[ i ] )\
1419 //return value is the hcd id
1421 dev_mgr_register_hcd(PUSB_DEV_MANAGER dev_mgr
, PHCD hcd
)
1423 if (dev_mgr
== NULL
|| hcd
== NULL
)
1426 if (dev_mgr
->hcd_count
>= MAX_HCDS
)
1429 dev_mgr
->hcd_array
[dev_mgr
->hcd_count
++] = hcd
;
1430 return dev_mgr
->hcd_count
- 1;
1434 dev_mgr_register_irp(PUSB_DEV_MANAGER dev_mgr
, PIRP pirp
, PURB purb
)
1436 if (dev_mgr
== NULL
)
1439 if (add_irp_to_list(&dev_mgr
->irp_list
, pirp
, purb
))
1447 //caller must guarantee that when this func is called,
1448 //the urb associated must exist.
1450 dev_mgr_remove_irp(PUSB_DEV_MANAGER dev_mgr
, PIRP pirp
)
1453 if (dev_mgr
== NULL
)
1456 purb
= remove_irp_from_list(&dev_mgr
->irp_list
, pirp
, NULL
);
1461 dev_mgr_cancel_irp(PDEVICE_OBJECT dev_obj
, PIRP pirp
)
1463 PUSB_DEV_MANAGER dev_mgr
;
1464 PDEVEXT_HEADER pdev_ext_hdr
;
1466 pdev_ext_hdr
= (PDEVEXT_HEADER
) dev_obj
->DeviceExtension
;
1467 dev_mgr
= pdev_ext_hdr
->dev_mgr
;
1469 if (dev_obj
->CurrentIrp
== pirp
)
1471 IoReleaseCancelSpinLock(pirp
->CancelIrql
);
1472 // we did not IoStartNextPacket, leave it for the urb completion
1476 KeRemoveEntryDeviceQueue(&dev_obj
->DeviceQueue
, &pirp
->Tail
.Overlay
.DeviceQueueEntry
);
1477 IoReleaseCancelSpinLock(pirp
->CancelIrql
);
1479 pirp
->IoStatus
.Information
= 0;
1480 pirp
->IoStatus
.Status
= STATUS_CANCELLED
;
1481 IoCompleteRequest(pirp
, IO_NO_INCREMENT
);
1482 // the device queue is moved on, no need to call IoStartNextPacket
1487 // remove the irp and call the dev_mgr_cancel_irp
1488 // the completion will be done in urb completion
1490 remove_irp_from_list(&dev_mgr
->irp_list
, pirp
, dev_mgr
);
1497 dev_mgr_release_hcd(PUSB_DEV_MANAGER dev_mgr
)
1501 for(i
= 0; i
< dev_mgr
->hcd_count
; i
++)
1503 hcd
= dev_mgr
->hcd_array
[i
];
1504 hcd
->hcd_release(hcd
);
1505 dev_mgr
->hcd_array
[i
] = 0;
1507 dev_mgr
->hcd_count
= 0;
1512 dev_mgr_start_hcd(PUSB_DEV_MANAGER dev_mgr
)
1516 for(i
= 0; i
< dev_mgr
->hcd_count
; i
++)
1518 hcd
= dev_mgr
->hcd_array
[i
];
1519 hcd
->hcd_start(hcd
);