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 );\
33 RtlZeroMemory( data_buf, ( pdEV )->desc_buf_size );\
34 for( i = 0; i < ( LONG )( puRB )->context; i++ )\
36 data_buf[ i ] = ( pdEV )->desc_buf[ i ];\
38 usb_free_mem( ( pdEV )->desc_buf );\
39 ( pdEV )->desc_buf = data_buf;\
40 ( pdEV )->pusb_dev_desc = ( PUSB_DEVICE_DESC )( pdEV )->desc_buf;\
41 ( puRB )->data_buffer = &data_buf[ ( LONG ) ( puRB )->context ];\
45 //----------------------------------------------------------
47 USB_DRIVER g_driver_list
[DEVMGR_MAX_DRIVERS
];
48 USB_DEV_MANAGER g_dev_mgr
;
51 //----------------------------------------------------------
53 dev_mgr_set_if_driver(PUSB_DEV_MANAGER dev_mgr
,
56 PUSB_DEV pdev
//if pdev != NULL, we use pdev instead if_handle, and must have dev_lock acquired.
60 USE_BASIC_NON_PENDING_IRQL
;
62 if (dev_mgr
== NULL
|| if_handle
== 0 || pdriver
== NULL
)
65 i
= if_idx_from_handle(if_handle
);
68 if (dev_state(pdev
) < USB_DEV_STATE_BEFORE_ZOMB
)
70 pdev
->usb_config
->interf
[i
].pif_drv
= pdriver
;
76 if (usb_query_and_lock_dev(dev_mgr
, if_handle
, &pdev
) != STATUS_SUCCESS
)
80 if (dev_state(pdev
) != USB_DEV_STATE_ZOMB
)
82 pdev
->usb_config
->interf
[i
].pif_drv
= pdriver
;
84 unlock_dev(pdev
, TRUE
);
90 dev_mgr_set_driver(PUSB_DEV_MANAGER dev_mgr
,
91 DEV_HANDLE dev_handle
,
93 PUSB_DEV pdev
//if pdev != NULL, we use pdev instead if_handle
96 USE_BASIC_NON_PENDING_IRQL
;
98 if (dev_mgr
== NULL
|| dev_handle
== 0 || pdriver
== NULL
)
103 if (dev_state(pdev
) < USB_DEV_STATE_BEFORE_ZOMB
)
105 pdev
->dev_driver
= pdriver
;
111 if (usb_query_and_lock_dev(dev_mgr
, dev_handle
, &pdev
) != STATUS_SUCCESS
)
114 lock_dev(pdev
, FALSE
);
115 if (dev_state(pdev
) < USB_DEV_STATE_BEFORE_ZOMB
)
117 pdev
->dev_driver
= pdriver
;
119 unlock_dev(pdev
, FALSE
);
120 usb_unlock_dev(pdev
);
126 dev_mgr_post_event(PUSB_DEV_MANAGER dev_mgr
, PUSB_EVENT event
)
130 if (dev_mgr
== NULL
|| event
== NULL
)
133 KeAcquireSpinLock(&dev_mgr
->event_list_lock
, &old_irql
);
134 InsertTailList(&dev_mgr
->event_list
, &event
->event_link
);
135 KeReleaseSpinLock(&dev_mgr
->event_list_lock
, old_irql
);
137 KeSetEvent(&dev_mgr
->wake_up_event
, 0, FALSE
);
142 dev_mgr_driver_entry_init(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdrvr
)
146 RtlZeroMemory(pdrvr
, sizeof(USB_DRIVER
) * DEVMGR_MAX_DRIVERS
);
148 pdrvr
[RH_DRIVER_IDX
].driver_init
= rh_driver_init
; // in fact, this routine will init the rh device rather that the driver struct.
149 pdrvr
[RH_DRIVER_IDX
].driver_destroy
= rh_driver_destroy
; // we do not need rh to destroy currently, since that may means fatal hardware failure
151 pdrvr
[HUB_DRIVER_IDX
].driver_init
= hub_driver_init
; //no need, since dev_mgr is also a hub driver
152 pdrvr
[HUB_DRIVER_IDX
].driver_destroy
= hub_driver_destroy
;
154 pdrvr
[UMSS_DRIVER_IDX
].driver_init
= umss_if_driver_init
;
155 pdrvr
[UMSS_DRIVER_IDX
].driver_destroy
= umss_if_driver_destroy
;
157 pdrvr
[COMP_DRIVER_IDX
].driver_init
= compdev_driver_init
;
158 pdrvr
[COMP_DRIVER_IDX
].driver_destroy
= compdev_driver_destroy
;
160 pdrvr
[GEN_DRIVER_IDX
].driver_init
= gendrv_driver_init
;
161 pdrvr
[GEN_DRIVER_IDX
].driver_destroy
= gendrv_driver_destroy
;
163 pdrvr
[GEN_IF_DRIVER_IDX
].driver_init
= gendrv_if_driver_init
;
164 pdrvr
[GEN_IF_DRIVER_IDX
].driver_destroy
= gendrv_if_driver_destroy
;
166 pdrvr
[MOUSE_DRIVER_IDX
].driver_init
= mouse_driver_init
;
167 pdrvr
[MOUSE_DRIVER_IDX
].driver_destroy
= mouse_driver_destroy
;
169 pdrvr
[KEYBOARD_DRIVER_IDX
].driver_init
= kbd_driver_init
;
170 pdrvr
[KEYBOARD_DRIVER_IDX
].driver_destroy
= kbd_driver_destroy
;
174 dev_mgr_strobe(PUSB_DEV_MANAGER dev_mgr
)
177 HANDLE thread_handle
;
181 if (dev_mgr
->hcd_count
== 0)
184 dev_mgr
->term_flag
= FALSE
;
186 if (dev_mgr
->hcd_count
== 0)
189 KeInitializeSpinLock(&dev_mgr
->event_list_lock
);
190 InitializeListHead(&dev_mgr
->event_list
);
191 init_event_pool(&dev_mgr
->event_pool
);
193 pevent
= alloc_event(&dev_mgr
->event_pool
, 1);
196 destroy_event_pool(&dev_mgr
->event_pool
);
200 pevent
->flags
= USB_EVENT_FLAG_ACTIVE
;
201 pevent
->event
= USB_EVENT_INIT_DEV_MGR
;
203 pevent
->process_queue
= event_list_default_process_queue
;
204 pevent
->process_event
= (PROCESS_EVENT
)dev_mgr_event_init
;
206 pevent
->context
= (ULONG
) dev_mgr
;
208 KeInitializeEvent(&dev_mgr
->wake_up_event
, SynchronizationEvent
, FALSE
);
209 KeInitializeEvent(&dev_mgr
->drivers_inited
, NotificationEvent
, FALSE
);
211 InsertTailList(&dev_mgr
->event_list
, &pevent
->event_link
);
213 if (PsCreateSystemThread(&thread_handle
, 0, NULL
, NULL
, NULL
, dev_mgr_thread
, dev_mgr
) != STATUS_SUCCESS
)
215 destroy_event_pool(&dev_mgr
->event_pool
);
219 ObReferenceObjectByHandle(thread_handle
,
220 THREAD_ALL_ACCESS
, NULL
, KernelMode
, (PVOID
*) & dev_mgr
->pthread
, NULL
);
222 ZwClose(thread_handle
);
228 dev_mgr_event_init(PUSB_DEV pdev
, //always null. we do not use this param
229 ULONG event
, ULONG context
, ULONG param
)
231 LARGE_INTEGER due_time
;
232 PUSB_DEV_MANAGER dev_mgr
;
235 usb_dbg_print(DBGLVL_MAXIMUM
, ("dev_mgr_event_init(): dev_mgr=0x%x, event=0x%x\n", context
, event
));
236 dev_mgr
= (PUSB_DEV_MANAGER
) context
;
240 if (event
!= USB_EVENT_INIT_DEV_MGR
)
243 //dev_mgr->root_hub = NULL;
244 KeInitializeTimer(&dev_mgr
->dev_mgr_timer
);
246 KeInitializeDpc(&dev_mgr
->dev_mgr_timer_dpc
, dev_mgr_timer_dpc_callback
, (PVOID
) dev_mgr
);
248 KeInitializeSpinLock(&dev_mgr
->timer_svc_list_lock
);
249 InitializeListHead(&dev_mgr
->timer_svc_list
);
250 init_timer_svc_pool(&dev_mgr
->timer_svc_pool
);
251 dev_mgr
->timer_click
= 0;
253 init_irp_list(&dev_mgr
->irp_list
);
255 KeInitializeSpinLock(&dev_mgr
->dev_list_lock
);
256 InitializeListHead(&dev_mgr
->dev_list
);
258 dev_mgr
->hub_count
= 0;
259 InitializeListHead(&dev_mgr
->hub_list
);
261 dev_mgr
->conn_count
= 0;
262 dev_mgr
->driver_list
= g_driver_list
;
264 dev_mgr_driver_entry_init(dev_mgr
, dev_mgr
->driver_list
);
266 for(i
= 0; i
< DEVMGR_MAX_DRIVERS
; i
++)
268 if (dev_mgr
->driver_list
[i
].driver_init
== NULL
)
271 if (dev_mgr
->driver_list
[i
].driver_init(dev_mgr
, &dev_mgr
->driver_list
[i
]) == FALSE
)
274 if (i
== DEVMGR_MAX_DRIVERS
)
276 due_time
.QuadPart
= -(DEV_MGR_TIMER_INTERVAL_NS
- 10);
278 KeSetTimerEx(&dev_mgr
->dev_mgr_timer
,
279 due_time
, DEV_MGR_TIMER_INTERVAL_MS
, &dev_mgr
->dev_mgr_timer_dpc
);
281 /* Signal we're done initing */
282 KeSetEvent(&dev_mgr
->drivers_inited
, 0, FALSE
);
291 if (dev_mgr
->driver_list
[i
].driver_destroy
)
292 dev_mgr
->driver_list
[i
].driver_destroy(dev_mgr
, &dev_mgr
->driver_list
[i
]);
295 KeCancelTimer(&dev_mgr
->dev_mgr_timer
);
296 KeRemoveQueueDpc(&dev_mgr
->dev_mgr_timer_dpc
);
297 KeSetEvent(&dev_mgr
->drivers_inited
, 0, FALSE
);
303 dev_mgr_destroy(PUSB_DEV_MANAGER dev_mgr
)
307 KeCancelTimer(&dev_mgr
->dev_mgr_timer
);
308 KeRemoveQueueDpc(&dev_mgr
->dev_mgr_timer_dpc
);
310 for(i
= DEVMGR_MAX_DRIVERS
- 1; i
>= 0; i
--)
311 dev_mgr
->driver_list
[i
].driver_destroy(dev_mgr
, &dev_mgr
->driver_list
[i
]);
313 destroy_irp_list(&dev_mgr
->irp_list
);
314 destroy_timer_svc_pool(&dev_mgr
->timer_svc_pool
);
315 destroy_event_pool(&dev_mgr
->event_pool
);
321 dev_mgr_thread(PVOID context
)
323 PUSB_DEV_MANAGER dev_mgr
;
325 PLIST_ENTRY pthis
, pnext
;
327 LARGE_INTEGER time_out
;
329 BOOLEAN dev_mgr_inited
;
333 dev_mgr
= (PUSB_DEV_MANAGER
) context
;
334 dev_mgr_inited
= FALSE
;
336 time_out
.u
.LowPart
= (10 * 1000 * 1000) * 100 - 1; //1 minutes
337 time_out
.u
.HighPart
= 0;
338 time_out
.QuadPart
= -time_out
.QuadPart
;
340 //usb_dbg_print( DBGLVL_MAXIMUM + 1, ( "dev_mgr_thread(): current uhci status=0x%x\n", uhci_status( dev_mgr->pdev_ext->uhci ) ) );
342 while (dev_mgr
->term_flag
== FALSE
)
344 KeAcquireSpinLock(&dev_mgr
->event_list_lock
, &old_irql
);
345 if (IsListEmpty(&dev_mgr
->event_list
) == TRUE
)
347 KeReleaseSpinLock(&dev_mgr
->event_list_lock
, old_irql
);
348 status
= KeWaitForSingleObject(&dev_mgr
->wake_up_event
, Executive
, KernelMode
, TRUE
, &time_out
);
353 usb_dbg_print( DBGLVL_MAXIMUM, ( "dev_mgr_thread(): current element in event list is 0x%x\n", \
354 dbg_count_list( &dev_mgr->event_list ) ) ); */
356 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
358 ListFirst(&dev_mgr
->event_list
, pthis
);
359 pevent
= struct_ptr(pthis
, USB_EVENT
, event_link
);
361 while (pevent
&& ((pevent
->flags
& USB_EVENT_FLAG_ACTIVE
) == 0))
364 ListNext(&dev_mgr
->event_list
, &pevent
->event_link
, pnext
);
365 pevent
= struct_ptr(pnext
, USB_EVENT
, event_link
);
370 if (pevent
->process_queue
== NULL
)
371 pevent
->process_queue
= event_list_default_process_queue
;
373 pevent
->process_queue(&dev_mgr
->event_list
, &dev_mgr
->event_pool
, pevent
, &usb_event
);
378 KeReleaseSpinLock(&dev_mgr
->event_list_lock
, old_irql
);
379 status
= KeWaitForSingleObject(&dev_mgr
->wake_up_event
, Executive
, KernelMode
, TRUE
, &time_out
// 10 minutes
382 usb_dbg_print(DBGLVL_MAXIMUM
, ("dev_mgr_thread(): wake up, reason=0x%x\n", status
));
386 KeReleaseSpinLock(&dev_mgr
->event_list_lock
, old_irql
);
388 if (usb_event
.process_event
)
390 usb_event
.process_event(usb_event
.pdev
, usb_event
.event
, usb_event
.context
, usb_event
.param
);
394 event_list_default_process_event(usb_event
.pdev
,
395 usb_event
.event
, usb_event
.context
, usb_event
.param
);
401 for(i
= 0; i
< dev_mgr
->hcd_count
; i
++)
402 dev_mgr_disconnect_dev(dev_mgr
->hcd_array
[i
]->hcd_get_root_hub(dev_mgr
->hcd_array
[i
]));
403 dev_mgr_destroy(dev_mgr
);
405 PsTerminateSystemThread(0);
410 dev_mgr_timer_dpc_callback(PKDPC Dpc
, PVOID context
, PVOID SystemArgument1
, PVOID SystemArgument2
)
412 PUSB_DEV_MANAGER dev_mgr
;
414 PLIST_ENTRY pthis
, pnext
;
415 static ULONG ticks
= 0;
418 dev_mgr
= (PUSB_DEV_MANAGER
) context
;
422 dev_mgr
->timer_click
++;
423 InitializeListHead(&templist
);
425 KeAcquireSpinLockAtDpcLevel(&dev_mgr
->timer_svc_list_lock
);
426 if (IsListEmpty(&dev_mgr
->timer_svc_list
) == TRUE
)
428 KeReleaseSpinLockFromDpcLevel(&dev_mgr
->timer_svc_list_lock
);
432 ListFirst(&dev_mgr
->timer_svc_list
, pthis
);
435 ((PTIMER_SVC
) pthis
)->counter
++;
436 ListNext(&dev_mgr
->timer_svc_list
, pthis
, pnext
);
437 if (((PTIMER_SVC
) pthis
)->counter
>= ((PTIMER_SVC
) pthis
)->threshold
)
439 RemoveEntryList(pthis
);
440 InsertTailList(&templist
, pthis
);
445 KeReleaseSpinLockFromDpcLevel(&dev_mgr
->timer_svc_list_lock
);
448 while (IsListEmpty(&templist
) == FALSE
)
450 pthis
= RemoveHeadList(&templist
);
451 ((PTIMER_SVC
) pthis
)->func(((PTIMER_SVC
) pthis
)->pdev
, (PVOID
) ((PTIMER_SVC
) pthis
)->context
);
452 KeAcquireSpinLockAtDpcLevel(&dev_mgr
->timer_svc_list_lock
);
453 free_timer_svc(&dev_mgr
->timer_svc_pool
, (PTIMER_SVC
) pthis
);
454 KeReleaseSpinLockFromDpcLevel(&dev_mgr
->timer_svc_list_lock
);
460 dev_mgr_request_timer_svc(PUSB_DEV_MANAGER dev_mgr
,
461 PUSB_DEV pdev
, ULONG context
, ULONG due_time
, TIMER_SVC_HANDLER handler
)
463 PTIMER_SVC timer_svc
;
466 if (dev_mgr
== NULL
|| pdev
== NULL
|| due_time
== 0 || handler
== NULL
)
469 KeAcquireSpinLock(&dev_mgr
->timer_svc_list_lock
, &old_irql
);
470 timer_svc
= alloc_timer_svc(&dev_mgr
->timer_svc_pool
, 1);
471 if (timer_svc
== NULL
)
473 KeReleaseSpinLock(&dev_mgr
->timer_svc_list_lock
, old_irql
);
476 timer_svc
->pdev
= pdev
;
477 timer_svc
->threshold
= due_time
;
478 timer_svc
->func
= handler
;
479 timer_svc
->counter
= 0;
481 InsertTailList(&dev_mgr
->timer_svc_list
, &timer_svc
->timer_svc_link
);
482 KeReleaseSpinLock(&dev_mgr
->timer_svc_list_lock
, old_irql
);
487 dev_mgr_alloc_addr(PUSB_DEV_MANAGER dev_mgr
, PHCD hcd
)
489 // alloc a usb addr for the device within 1-128
490 if (dev_mgr
== NULL
|| hcd
== NULL
)
493 return hcd
->hcd_alloc_addr(hcd
);
497 dev_mgr_free_addr(PUSB_DEV_MANAGER dev_mgr
, PUSB_DEV pdev
, BYTE addr
)
503 if (dev_mgr
== NULL
|| pdev
== NULL
)
509 hcd
->hcd_free_addr(hcd
, addr
);
514 dev_mgr_alloc_device(PUSB_DEV_MANAGER dev_mgr
, PHCD hcd
)
519 if ((addr
= dev_mgr_alloc_addr(dev_mgr
, hcd
)) == 0xff)
522 pdev
= usb_alloc_mem(NonPagedPool
, sizeof(USB_DEV
));
526 RtlZeroMemory(pdev
, sizeof(USB_DEV
));
528 KeInitializeSpinLock(&pdev
->dev_lock
);
529 dev_mgr
->conn_count
++;
531 pdev
->flags
= USB_DEV_STATE_RESET
; //class | cur_state | low speed
533 pdev
->dev_addr
= addr
;
537 pdev
->dev_id
= dev_mgr
->conn_count
; //will be used to compose dev_handle
539 InitializeListHead(&pdev
->default_endp
.urb_list
);
540 pdev
->default_endp
.pusb_if
= (PUSB_INTERFACE
) pdev
;
541 pdev
->default_endp
.flags
= USB_ENDP_FLAG_DEFAULT_ENDP
; //toggle | busy-count | stall | default-endp
547 dev_mgr_free_device(PUSB_DEV_MANAGER dev_mgr
, PUSB_DEV pdev
)
549 if (pdev
== NULL
|| dev_mgr
== NULL
)
552 dev_mgr_free_addr(dev_mgr
, pdev
, pdev
->dev_addr
);
553 if (pdev
->usb_config
&& pdev
!= pdev
->hcd
->hcd_get_root_hub(pdev
->hcd
))
555 //root hub has its config and desc buf allocated together,
556 //so no usb_config allocated seperately
557 dev_mgr_destroy_usb_config(pdev
->usb_config
);
558 pdev
->usb_config
= NULL
;
562 usb_free_mem(pdev
->desc_buf
);
563 pdev
->desc_buf
= NULL
;
570 //called when a disconnect is detected on the port
572 dev_mgr_disconnect_dev(PUSB_DEV pdev
)
574 PLIST_ENTRY pthis
, pnext
;
575 PHUB2_EXTENSION phub_ext
= NULL
;
576 PUSB_CONFIGURATION pconfig
;
577 PUSB_DEV_MANAGER dev_mgr
;
579 BOOLEAN is_hub
, found
;
583 USE_NON_PENDING_IRQL
;
590 usb_dbg_print(DBGLVL_MAXIMUM
, ("dev_mgr_disconnect_dev(): entering, pdev=0x%x\n", pdev
));
591 lock_dev(pdev
, FALSE
);
592 pdev
->flags
&= ~USB_DEV_STATE_MASK
;
593 pdev
->flags
|= USB_DEV_STATE_BEFORE_ZOMB
;
594 dev_mgr
= dev_mgr_from_dev(pdev
);
595 unlock_dev(pdev
, FALSE
);
597 // notify dev_driver that the dev stops function before any operations
598 if (pdev
->dev_driver
&& pdev
->dev_driver
->disp_tbl
.dev_stop
)
599 pdev
->dev_driver
->disp_tbl
.dev_stop(dev_mgr
, dev_handle_from_dev(pdev
));
601 //safe to use the dev pointer in this function.
602 lock_dev(pdev
, FALSE
);
603 pdev
->flags
&= ~USB_DEV_STATE_MASK
;
604 pdev
->flags
|= USB_DEV_STATE_ZOMB
;
606 dev_id
= pdev
->dev_id
;
607 unlock_dev(pdev
, FALSE
);
612 hcd
->hcd_remove_device(hcd
, pdev
);
614 //disconnect its children
615 if ((pdev
->flags
& USB_DEV_CLASS_MASK
) == USB_DEV_CLASS_HUB
||
616 (pdev
->flags
& USB_DEV_CLASS_MASK
) == USB_DEV_CLASS_ROOT_HUB
)
618 phub_ext
= hub_ext_from_dev(pdev
);
621 for(i
= 1; i
<= phub_ext
->port_count
; i
++)
623 if (phub_ext
->child_dev
[i
])
625 dev_mgr_disconnect_dev(phub_ext
->child_dev
[i
]);
626 phub_ext
->child_dev
[i
] = NULL
;
632 pconfig
= pdev
->usb_config
;
634 //remove event belong to the dev
635 is_hub
= ((pdev
->flags
& USB_DEV_CLASS_MASK
) == USB_DEV_CLASS_HUB
);
637 if (phub_ext
&& is_hub
)
639 for(i
= 1; i
<= phub_ext
->port_count
; i
++)
641 found
= hub_remove_reset_event(pdev
, i
, FALSE
);
647 //free event of the dev from the event list
648 KeAcquireSpinLock(&dev_mgr
->event_list_lock
, &old_irql
);
649 ListFirst(&dev_mgr
->event_list
, pthis
);
652 ListNext(&dev_mgr
->event_list
, pthis
, pnext
);
653 if (((PUSB_EVENT
) pthis
)->pdev
== pdev
)
656 RemoveEntryList(pthis
);
657 if ((((PUSB_EVENT
) pthis
)->flags
& USB_EVENT_FLAG_QUE_TYPE
) != USB_EVENT_FLAG_NOQUE
)
659 //has a queue, re-insert the queue
660 if ((p1
= (PLIST_ENTRY
) ((PUSB_EVENT
) pthis
)->pnext
))
662 InsertHeadList(&dev_mgr
->event_list
, p1
);
663 free_event(&dev_mgr
->event_pool
, struct_ptr(pthis
, USB_EVENT
, event_link
));
665 //note: this queue will be examined again in the next loop
666 //to find the matched dev in the queue
670 free_event(&dev_mgr
->event_pool
, struct_ptr(pthis
, USB_EVENT
, event_link
));
672 else if (((((PUSB_EVENT
) pthis
)->flags
& USB_EVENT_FLAG_QUE_TYPE
)
673 != USB_EVENT_FLAG_NOQUE
) && ((PUSB_EVENT
) pthis
)->pnext
)
675 //has a queue, examine the queue
677 p1
= (PUSB_EVENT
) pthis
;
681 if (p2
->pdev
== pdev
)
683 p1
->pnext
= p2
->pnext
;
685 free_event(&dev_mgr
->event_pool
, p2
);
697 KeReleaseSpinLock(&dev_mgr
->event_list_lock
, old_irql
);
699 // found indicates the reset event on one of the dev's port in process
701 hub_start_next_reset_port(dev_mgr_from_dev(pdev
), FALSE
);
703 // remove timer-svc belonging to the dev
704 KeAcquireSpinLock(&dev_mgr
->timer_svc_list_lock
, &old_irql
);
705 ListFirst(&dev_mgr
->timer_svc_list
, pthis
);
709 ListNext(&dev_mgr
->timer_svc_list
, pthis
, pnext
);
710 if (((PUSB_EVENT
) pthis
)->pdev
== pdev
)
712 RemoveEntryList(pthis
);
713 free_timer_svc(&dev_mgr
->timer_svc_pool
, struct_ptr(pthis
, TIMER_SVC
, timer_svc_link
));
718 KeReleaseSpinLock(&dev_mgr
->timer_svc_list_lock
, old_irql
);
720 // release the refcount
723 lock_dev(pdev
, FALSE
);
724 pdev
->ref_count
-= i
;
725 unlock_dev(pdev
, FALSE
);
728 // wait for all the reference count be released
731 LARGE_INTEGER interval
;
733 lock_dev(pdev
, FALSE
);
734 if (pdev
->ref_count
== 0)
736 unlock_dev(pdev
, FALSE
);
739 unlock_dev(pdev
, FALSE
);
741 interval
.QuadPart
= -20000;
742 KeDelayExecutionThread(KernelMode
, FALSE
, &interval
);
745 if (pdev
->dev_driver
&& pdev
->dev_driver
->disp_tbl
.dev_disconnect
)
746 pdev
->dev_driver
->disp_tbl
.dev_disconnect(dev_mgr
, dev_handle_from_dev(pdev
));
748 // we put it here to let handle valid before disconnect
749 KeAcquireSpinLock(&dev_mgr
->dev_list_lock
, &old_irql
);
750 ListFirst(&dev_mgr
->dev_list
, pthis
);
753 if (((PUSB_DEV
) pthis
) == pdev
)
755 RemoveEntryList(pthis
);
758 ListNext(&dev_mgr
->dev_list
, pthis
, pnext
);
761 KeReleaseSpinLock(&dev_mgr
->dev_list_lock
, old_irql
);
764 if (pdev
!= pdev
->hcd
->hcd_get_root_hub(pdev
->hcd
))
766 dev_mgr_free_device(dev_mgr
, pdev
);
770 //rh_destroy( pdev );
772 //destroy it in dev_mgr_destroy
778 //called in hub_set_address_completion
780 dev_mgr_start_config_dev(PUSB_DEV pdev
)
783 PUSB_CTRL_SETUP_PACKET psetup
;
786 USE_BASIC_NON_PENDING_IRQL
;
788 hcd_dbg_print(DBGLVL_MAXIMUM
, ("dev_mgr_start_config_dev: pdev=%p\n", pdev
));
793 lock_dev(pdev
, TRUE
);
794 if (dev_state(pdev
) == USB_DEV_STATE_ZOMB
)
796 unlock_dev(pdev
, TRUE
);
802 //first, get device descriptor
803 purb
= usb_alloc_mem(NonPagedPool
, sizeof(URB
));
804 data_buf
= usb_alloc_mem(NonPagedPool
, 512);
805 if (purb
== NULL
|| data_buf
== NULL
)
807 unlock_dev(pdev
, TRUE
);
811 RtlZeroMemory(purb
, sizeof(URB
));
812 RtlZeroMemory(data_buf
, 512);
814 psetup
= (PUSB_CTRL_SETUP_PACKET
) purb
->setup_packet
;
816 purb
->data_buffer
= data_buf
; // user data
817 purb
->data_length
= 8; // get partial desc
819 pdev
->desc_buf
= data_buf
;
820 pdev
->desc_buf_size
= 512;
823 purb
->pendp
= &pdev
->default_endp
; //pipe for current transfer
825 purb
->completion
= dev_mgr_get_desc_completion
;
828 InitializeListHead(&purb
->trasac_list
);
830 psetup
->bmRequestType
= 0x80;
831 psetup
->bRequest
= USB_REQ_GET_DESCRIPTOR
;
832 psetup
->wValue
= (USB_DT_DEVICE
<< 8) | 0;
834 psetup
->wLength
= 8; //sizeof( USB_DEVICE_DESC );
835 unlock_dev(pdev
, TRUE
);
837 if (hcd
->hcd_submit_urb(hcd
, pdev
, purb
->pendp
, purb
) != STATUS_PENDING
)
840 usb_free_mem(data_buf
);
847 dev_mgr_get_desc_completion(PURB purb
, PVOID context
)
850 PUSB_CONFIGURATION_DESC pconfig_desc
;
852 PUSB_DEV_MANAGER dev_mgr
;
854 PUSB_CTRL_SETUP_PACKET psetup
;
857 USE_BASIC_NON_PENDING_IRQL
;
862 hcd_dbg_print(DBGLVL_MAXIMUM
,
863 ("dev_mgr_get_desc_completion: purb->reference=%d\n", purb
->reference
));
868 if (pdev
== NULL
|| pendp
== NULL
)
875 lock_dev(pdev
, TRUE
);
876 if (dev_state(pdev
) == USB_DEV_STATE_ZOMB
)
878 unlock_dev(pdev
, TRUE
);
882 pendp
= &pdev
->default_endp
;
883 dev_mgr
= dev_mgr_from_dev(pdev
);
885 psetup
= (PUSB_CTRL_SETUP_PACKET
) purb
->setup_packet
;
887 if (usb_error(purb
->status
))
889 unlock_dev(pdev
, TRUE
);
890 hcd_dbg_print(DBGLVL_MAXIMUM
,
891 ("dev_mgr_get_desc_completion: can not get dev desc ref=0x%x, status=0x%x\n",
892 purb
->reference
, purb
->status
));
896 switch (purb
->reference
)
900 //only partial dev_desc
901 //enable the dev specific default endp maxpacketsize
902 pdev
->pusb_dev_desc
= (PUSB_DEVICE_DESC
) purb
->data_buffer
;
904 psetup
= (PUSB_CTRL_SETUP_PACKET
) purb
->setup_packet
;
905 psetup
->wLength
= sizeof(USB_DEVICE_DESC
);
907 //get the complete dev_desc
910 purb
->data_length
= sizeof(USB_DEVICE_DESC
);
912 unlock_dev(pdev
, TRUE
);
914 status
= hcd
->hcd_submit_urb(hcd
, pdev
, pendp
, purb
);
915 if (status
!= STATUS_PENDING
)
923 //let's begin to get config descriptors.
924 if (pdev
->pusb_dev_desc
->bNumConfigurations
== 0)
926 unlock_dev(pdev
, TRUE
);
930 purb
->data_buffer
+= sizeof(USB_DEVICE_DESC
);
931 purb
->data_length
= 8;
933 purb
->context
= (PVOID
) sizeof(USB_DEVICE_DESC
);
936 psetup
->wValue
= (USB_DT_CONFIG
<< 8) | 0;
938 unlock_dev(pdev
, TRUE
);
940 status
= hcd
->hcd_submit_urb(hcd
, pdev
, pendp
, purb
);
942 if (status
!= STATUS_PENDING
)
951 config_idx
= (purb
->reference
>> 1) - 1;
952 if ((purb
->reference
& 1) == 0)
954 //partial config desc is obtained.
955 pconfig_desc
= (PUSB_CONFIGURATION_DESC
) purb
->data_buffer
;
956 if (pconfig_desc
->wTotalLength
>= 1024)
959 unlock_dev(pdev
, TRUE
);
964 if (pconfig_desc
->wTotalLength
> (USHORT
) (pdev
->desc_buf_size
- (LONG
) purb
->context
))
966 //rewind the 8-byte hdr
967 *((PULONG
) & context
) -= 8;
968 realloc_buf(pdev
, purb
);
970 purb
->data_length
= pconfig_desc
->wTotalLength
;
971 psetup
->wLength
= pconfig_desc
->wTotalLength
;
973 unlock_dev(pdev
, TRUE
);
974 status
= hcd
->hcd_submit_urb(hcd
, pdev
, pendp
, purb
);
975 if (status
!= STATUS_PENDING
)
981 //complete desc is returned.
982 if (config_idx
+ 1 < pdev
->pusb_dev_desc
->bNumConfigurations
)
984 //still have configurations left
985 *((PULONG
) & context
) += psetup
->wLength
;
986 purb
->data_buffer
= &pdev
->desc_buf
[(LONG
) context
];
987 purb
->data_length
= 8;
989 psetup
->wValue
= (((USB_DT_CONFIG
) << 8) | (config_idx
+ 1));
991 purb
->context
= context
;
993 if (((LONG
) context
) + 8 > pdev
->desc_buf_size
)
994 realloc_buf(pdev
, purb
);
997 unlock_dev(pdev
, TRUE
);
998 status
= hcd
->hcd_submit_urb(hcd
, pdev
, pendp
, purb
);
999 if (status
!= STATUS_PENDING
)
1004 //config descriptors have all been fetched
1005 unlock_dev(pdev
, TRUE
);
1009 // load driver for the device
1010 dev_mgr_start_select_driver(pdev
);
1024 lock_dev(pdev
, TRUE
);
1025 if (dev_state(pdev
) != USB_DEV_STATE_ZOMB
)
1029 usb_free_mem(pdev
->desc_buf
);
1030 pdev
->desc_buf_size
= 0;
1031 pdev
->desc_buf
= NULL
;
1032 pdev
->pusb_dev_desc
= NULL
;
1033 pdev
->usb_config
= NULL
;
1036 unlock_dev(pdev
, TRUE
);
1042 dev_mgr_start_select_driver(PUSB_DEV pdev
)
1044 PUSB_DEV_MANAGER dev_mgr
;
1048 USE_BASIC_NON_PENDING_IRQL
;
1053 dev_mgr
= dev_mgr_from_dev(pdev
);
1054 KeAcquireSpinLockAtDpcLevel(&dev_mgr
->event_list_lock
);
1055 lock_dev(pdev
, TRUE
);
1057 if (dev_state(pdev
) == USB_DEV_STATE_ZOMB
)
1063 pevent
= alloc_event(&dev_mgr
->event_pool
, 1);
1069 pevent
->flags
= USB_EVENT_FLAG_ACTIVE
;
1070 pevent
->event
= USB_EVENT_DEFAULT
;
1071 pevent
->pdev
= pdev
;
1072 pevent
->context
= 0;
1074 pevent
->pnext
= 0; //vertical queue for serialized operation
1075 pevent
->process_event
= dev_mgr_event_select_driver
;
1076 pevent
->process_queue
= event_list_default_process_queue
;
1078 InsertTailList(&dev_mgr
->event_list
, &pevent
->event_link
);
1079 KeSetEvent(&dev_mgr
->wake_up_event
, 0, FALSE
);
1083 unlock_dev(pdev
, TRUE
);
1084 KeReleaseSpinLockFromDpcLevel(&dev_mgr
->event_list_lock
);
1089 dev_mgr_connect_to_dev(PVOID Parameter
)
1092 DEV_HANDLE dev_handle
;
1094 PUSB_DRIVER pdriver
;
1095 PDEV_CONNECT_DATA pcd
= (PDEV_CONNECT_DATA
) Parameter
;
1096 PUSB_DEV_MANAGER dev_mgr
;
1097 DEV_CONNECT_DATA param
;
1101 dev_handle
= pcd
->dev_handle
;
1102 pdriver
= pcd
->pdriver
;
1103 dev_mgr
= pcd
->dev_mgr
;
1105 param
.dev_mgr
= dev_mgr
;
1106 param
.pdriver
= pdriver
;
1107 param
.dev_handle
= 0; //not used
1109 status
= usb_query_and_lock_dev(dev_mgr
, dev_handle
, &pdev
);
1110 if (status
!= STATUS_SUCCESS
)
1113 usb_dbg_print(DBGLVL_MAXIMUM
, ("dev_mgr_connect_to_dev(): about to call driver's dev_connect\n"));
1114 status
= pdriver
->disp_tbl
.dev_connect(¶m
, dev_handle
);
1115 usb_unlock_dev(pdev
);
1120 dev_mgr_event_select_driver(PUSB_DEV pdev
, ULONG event
, ULONG context
, ULONG param
)
1122 PUSB_DEV_MANAGER dev_mgr
;
1123 PUSB_DRIVER pdriver
, pcand
;
1124 LONG credit
, match
, i
;
1125 DEV_HANDLE handle
= 0;
1126 DEV_CONNECT_DATA cd
;
1128 USE_BASIC_NON_PENDING_IRQL
;
1130 UNREFERENCED_PARAMETER(param
);
1131 UNREFERENCED_PARAMETER(context
);
1133 usb_dbg_print(DBGLVL_MAXIMUM
, ("dev_mgr_event_select_driver(): pdev=%p event=0x%x\n", pdev
, event
));
1138 lock_dev(pdev
, FALSE
);
1139 if (dev_state(pdev
) == USB_DEV_STATE_ZOMB
)
1141 unlock_dev(pdev
, FALSE
);
1144 dev_mgr
= dev_mgr_from_dev(pdev
);
1148 for(i
= HUB_DRIVER_IDX
; i
< DEVMGR_MAX_DRIVERS
; i
++)
1150 //bypass root-hub driver with idx zero
1151 pdriver
= (PUSB_DRIVER
) & dev_mgr
->driver_list
[i
];
1153 if (pdriver
->driver_desc
.flags
& USB_DRIVER_FLAG_DEV_CAPABLE
)
1154 credit
= dev_mgr_score_driver_for_dev(dev_mgr
, pdriver
, pdev
->pusb_dev_desc
);
1160 pcand
= pdriver
, match
= credit
;
1166 // we set class driver here
1167 // pdev->dev_driver = pcand;
1168 handle
= usb_make_handle(pdev
->dev_id
, 0, 0);
1170 unlock_dev(pdev
, FALSE
);
1175 cd
.dev_handle
= handle
;
1177 cd
.dev_mgr
= dev_mgr
;
1179 if (dev_mgr_connect_to_dev(&cd
))
1182 // ExInitializeWorkItem( pwork_item, dev_mgr_connect_to_dev, ( PVOID )pcd );
1183 // ExQueueWorkItem( pwork_item, DelayedWorkQueue );
1185 cd
.dev_handle
= handle
;
1186 cd
.pdriver
= &dev_mgr
->driver_list
[GEN_DRIVER_IDX
];
1187 cd
.dev_mgr
= dev_mgr
;
1188 dev_mgr_connect_to_dev(&cd
);
1193 dev_mgr_build_usb_endp(PUSB_INTERFACE pif
, PUSB_ENDPOINT pendp
, PUSB_ENDPOINT_DESC pendp_desc
)
1195 if (pendp
== NULL
|| pif
== NULL
|| pendp_desc
== NULL
)
1199 InitializeListHead(&pendp
->urb_list
); //pending urb queue
1200 pendp
->pusb_if
= pif
;
1201 pendp
->pusb_endp_desc
= pendp_desc
;
1206 dev_mgr_build_usb_if(PUSB_CONFIGURATION pcfg
, PUSB_INTERFACE pif
, PUSB_INTERFACE_DESC pif_desc
, BOOLEAN alt_if
)
1209 PUSB_ENDPOINT_DESC pendp_desc
;
1212 if (pcfg
== NULL
|| pif
== NULL
|| pif_desc
== NULL
)
1215 if (alt_if
== FALSE
)
1217 pif
->endp_count
= pif_desc
->bNumEndpoints
> MAX_ENDPS_PER_IF
1218 ? MAX_ENDPS_PER_IF
: pif_desc
->bNumEndpoints
;
1220 pif
->pif_drv
= NULL
;
1221 pif
->pusb_config
= pcfg
;
1222 pif
->pusb_if_desc
= pif_desc
;
1223 pif
->if_ext_size
= 0;
1226 InitializeListHead(&pif
->altif_list
);
1227 pif
->altif_count
= 0;
1229 pbuf
= &((PBYTE
) pif_desc
)[sizeof(USB_INTERFACE_DESC
)];
1232 while (i
< pif
->endp_count
)
1234 pendp_desc
= (PUSB_ENDPOINT_DESC
)pbuf
;
1236 // check if it's an endpoint descriptor
1237 if (pendp_desc
->bDescriptorType
== USB_DT_ENDPOINT
)
1240 dev_mgr_build_usb_endp(pif
, &pif
->endp
[i
], pendp_desc
);
1244 // skip to the next one
1245 pbuf
+= pendp_desc
->bLength
;
1250 PUSB_INTERFACE paltif
;
1251 PLIST_ENTRY pthis
, pnext
;
1254 paltif
= usb_alloc_mem(NonPagedPool
, sizeof(USB_INTERFACE
));
1255 if (!paltif
) return FALSE
;
1257 RtlZeroMemory(paltif
, sizeof(USB_INTERFACE
));
1258 InsertTailList(&pif
->altif_list
, &paltif
->altif_list
);
1259 paltif
->pif_drv
= NULL
;
1260 paltif
->pusb_config
= pcfg
;
1261 paltif
->pusb_if_desc
= pif_desc
;
1262 paltif
->if_ext_size
= 0;
1263 paltif
->if_ext
= NULL
;
1264 paltif
->endp_count
= pif_desc
->bNumEndpoints
> MAX_ENDPS_PER_IF
1265 ? MAX_ENDPS_PER_IF
: pif_desc
->bNumEndpoints
;
1267 ListFirst(&pif
->altif_list
, pthis
);
1271 //synchronize the altif_count;
1272 PUSB_INTERFACE pthis_if
;
1273 pthis_if
= (PUSB_INTERFACE
) (((PBYTE
) pthis
) - offsetof(USB_INTERFACE
, altif_list
));
1274 pthis_if
->altif_count
= pif
->altif_count
;
1275 ListNext(&pif
->altif_list
, pthis
, pnext
);
1284 dev_mgr_build_usb_config(PUSB_DEV pdev
, PBYTE pbuf
, ULONG config_val
, LONG config_count
)
1286 PUSB_CONFIGURATION pcfg
;
1287 PUSB_INTERFACE_DESC pif_desc
;
1292 if (pdev
== NULL
|| pbuf
== NULL
)
1293 return STATUS_INVALID_PARAMETER
;
1296 pdev
->usb_config
= usb_alloc_mem(NonPagedPool
, sizeof(USB_CONFIGURATION
));
1297 pcfg
= pdev
->usb_config
;
1299 if (pdev
->usb_config
== NULL
)
1300 return STATUS_NO_MEMORY
;
1302 RtlZeroMemory(pcfg
, sizeof(USB_CONFIGURATION
));
1303 pcfg
->pusb_config_desc
= usb_find_config_desc_by_val(pbuf
, config_val
, config_count
);
1305 if (pcfg
->pusb_config_desc
== NULL
)
1308 pdev
->usb_config
= NULL
;
1309 return STATUS_UNSUCCESSFUL
;
1311 pcfg
->if_count
= pcfg
->pusb_config_desc
->bNumInterfaces
;
1312 pcfg
->pusb_dev
= pdev
;
1313 pif_desc
= (PUSB_INTERFACE_DESC
) & ((PBYTE
) pcfg
->pusb_config_desc
)[sizeof(USB_CONFIGURATION_DESC
)];
1314 if_count
= pcfg
->if_count
;
1316 for(i
= 0; i
< if_count
; i
++, pif_desc
++)
1318 if (pif_desc
->bAlternateSetting
== 0)
1320 dev_mgr_build_usb_if(pcfg
, &pcfg
->interf
[i
], pif_desc
, FALSE
);
1324 pif
= &pcfg
->interf
[i
-1];
1325 dev_mgr_build_usb_if(pcfg
, pif
, pif_desc
, TRUE
);
1328 return STATUS_SUCCESS
;
1332 dev_mgr_destroy_usb_config(PUSB_CONFIGURATION pcfg
)
1341 for(i
= 0; i
< pcfg
->if_count
; i
++)
1343 pif
= &pcfg
->interf
[i
];
1345 if (pif
->altif_count
)
1347 ListFirst(&pif
->altif_list
, pthis
);
1350 PUSB_INTERFACE pthis_if
;
1351 pthis_if
= (PUSB_INTERFACE
) (((PBYTE
) pthis
) - offsetof(USB_INTERFACE
, altif_list
));
1352 RemoveEntryList(pthis
);
1353 usb_free_mem(pthis_if
);
1354 if (IsListEmpty(&pif
->altif_list
) == TRUE
)
1357 ListFirst(&pif
->altif_list
, pthis
);
1365 #define is_dev_product_match( pdriVER, pdev_DESC ) \
1366 ( ( pdriVER )->driver_desc.vendor_id == ( pdev_DESC )->idVendor \
1367 && ( pdriVER )->driver_desc.product_id == ( pdev_DESC )->idProduct )
1370 dev_mgr_score_driver_for_dev(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdriver
, PUSB_DEVICE_DESC pdev_desc
)
1374 UNREFERENCED_PARAMETER(dev_mgr
);
1376 //assume supports all the sub_class are supported if sub_class is zero
1377 if (pdriver
->driver_desc
.dev_class
== pdev_desc
->bDeviceClass
)
1379 if (pdriver
->driver_desc
.dev_sub_class
== 0 && pdriver
->driver_desc
.dev_protocol
== 0)
1381 else if (pdriver
->driver_desc
.dev_sub_class
== pdev_desc
->bDeviceSubClass
)
1383 if (pdriver
->driver_desc
.dev_protocol
== 0)
1385 else if (pdriver
->driver_desc
.dev_protocol
== pdev_desc
->bDeviceProtocol
)
1390 if (is_dev_product_match(pdriver
, pdev_desc
))
1397 dev_mgr_score_driver_for_if(PUSB_DEV_MANAGER dev_mgr
, PUSB_DRIVER pdriver
, PUSB_INTERFACE_DESC pif_desc
)
1402 || !(pdriver
->driver_desc
.flags
& USB_DRIVER_FLAG_IF_CAPABLE
) || pif_desc
== NULL
|| dev_mgr
== NULL
)
1405 if (is_header_match((PBYTE
) pif_desc
, USB_DT_INTERFACE
) == FALSE
)
1411 if ((pdriver
->driver_desc
.if_class
== pif_desc
->bInterfaceClass
))
1413 if (pdriver
->driver_desc
.if_sub_class
== 0 && pdriver
->driver_desc
.if_protocol
== 0)
1415 if (pdriver
->driver_desc
.if_sub_class
== pif_desc
->bInterfaceSubClass
)
1417 if (pdriver
->driver_desc
.if_protocol
== 0)
1419 if (pdriver
->driver_desc
.if_protocol
== pif_desc
->bInterfaceProtocol
)
1429 #define is_equal_driver( pd1, pd2, ret ) \
1433 PUSB_DRIVER pdr1, pdr2;\
1434 pdr1 = ( PUSB_DRIVER )( pd1 );\
1435 pdr2 = ( PUSB_DRIVER ) ( pd2 );\
1436 for( i = 0; i < 16; i++ )\
1438 if( pdr1->driver_name[ i ] != pdr2->driver_name[ i ] )\
1446 //return value is the hcd id
1448 dev_mgr_register_hcd(PUSB_DEV_MANAGER dev_mgr
, PHCD hcd
)
1450 if (dev_mgr
== NULL
|| hcd
== NULL
)
1453 if (dev_mgr
->hcd_count
>= MAX_HCDS
)
1456 dev_mgr
->hcd_array
[dev_mgr
->hcd_count
++] = hcd
;
1457 return dev_mgr
->hcd_count
- 1;
1461 dev_mgr_register_irp(PUSB_DEV_MANAGER dev_mgr
, PIRP pirp
, PURB purb
)
1463 if (dev_mgr
== NULL
)
1466 if (add_irp_to_list(&dev_mgr
->irp_list
, pirp
, purb
))
1474 //caller must guarantee that when this func is called,
1475 //the urb associated must exist.
1477 dev_mgr_remove_irp(PUSB_DEV_MANAGER dev_mgr
, PIRP pirp
)
1480 if (dev_mgr
== NULL
)
1483 purb
= remove_irp_from_list(&dev_mgr
->irp_list
, pirp
, NULL
);
1488 dev_mgr_cancel_irp(PDEVICE_OBJECT dev_obj
, PIRP pirp
)
1490 PUSB_DEV_MANAGER dev_mgr
;
1491 PDEVEXT_HEADER pdev_ext_hdr
;
1493 pdev_ext_hdr
= (PDEVEXT_HEADER
) dev_obj
->DeviceExtension
;
1494 dev_mgr
= pdev_ext_hdr
->dev_mgr
;
1496 if (dev_obj
->CurrentIrp
== pirp
)
1498 IoReleaseCancelSpinLock(pirp
->CancelIrql
);
1499 // we did not IoStartNextPacket, leave it for the urb completion
1503 KeRemoveEntryDeviceQueue(&dev_obj
->DeviceQueue
, &pirp
->Tail
.Overlay
.DeviceQueueEntry
);
1504 IoReleaseCancelSpinLock(pirp
->CancelIrql
);
1506 pirp
->IoStatus
.Information
= 0;
1507 pirp
->IoStatus
.Status
= STATUS_CANCELLED
;
1508 IoCompleteRequest(pirp
, IO_NO_INCREMENT
);
1509 // the device queue is moved on, no need to call IoStartNextPacket
1514 // remove the irp and call the dev_mgr_cancel_irp
1515 // the completion will be done in urb completion
1517 remove_irp_from_list(&dev_mgr
->irp_list
, pirp
, dev_mgr
);
1524 dev_mgr_release_hcd(PUSB_DEV_MANAGER dev_mgr
)
1528 for(i
= 0; i
< dev_mgr
->hcd_count
; i
++)
1530 hcd
= dev_mgr
->hcd_array
[i
];
1531 hcd
->hcd_release(hcd
);
1532 dev_mgr
->hcd_array
[i
] = 0;
1534 dev_mgr
->hcd_count
= 0;
1539 dev_mgr_start_hcd(PUSB_DEV_MANAGER dev_mgr
)
1543 for(i
= 0; i
< dev_mgr
->hcd_count
; i
++)
1545 hcd
= dev_mgr
->hcd_array
[i
];
1546 hcd
->hcd_start(hcd
);