IN LONG PortId,
OUT PDEVICE_OBJECT *UsbChildDeviceObject);
+NTSTATUS
+DestroyUsbChildDeviceObject(
+ IN PDEVICE_OBJECT UsbHubDeviceObject,
+ IN LONG PortId);
+
NTSTATUS
SubmitRequestToRootHub(
IN PDEVICE_OBJECT RootHubDeviceObject,
{
DPRINT1("Device disconnected from port %d\n", PortId);
- //
- // FIXME: Remove the device, and deallocate memory
- //
+ Status = DestroyUsbChildDeviceObject(DeviceObject, PortId);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to delete child device object after disconnect\n");
+ }
}
else
{
}
NTSTATUS
+NTAPI
StatusChangeEndpointCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
}
WorkItemData->Context = RealDeviceObject;
DPRINT1("Initialize work item\n");
- ExInitializeWorkItem(&WorkItemData->WorkItem, (PWORKER_THREAD_ROUTINE)DeviceStatusChangeThread, (PVOID)WorkItemData);
+ ExInitializeWorkItem(&WorkItemData->WorkItem, DeviceStatusChangeThread, (PVOID)WorkItemData);
//
// Queue the work item to handle initializing the device
// Set the completion routine for when device is connected to root hub
//
IoSetCompletionRoutine(HubDeviceExtension->PendingSCEIrp,
- (PIO_COMPLETION_ROUTINE) StatusChangeEndpointCompletion,
+ StatusChangeEndpointCompletion,
DeviceObject,
TRUE,
TRUE,
return Status;
}
+NTSTATUS
+DestroyUsbChildDeviceObject(
+ IN PDEVICE_OBJECT UsbHubDeviceObject,
+ IN LONG PortId)
+{
+ PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbHubDeviceObject->DeviceExtension;
+ PHUB_CHILDDEVICE_EXTENSION UsbChildExtension = NULL;
+ PDEVICE_OBJECT ChildDeviceObject = NULL;
+ ULONG Index = 0;
+
+ DPRINT1("Removing device on port %d (Child index: %d)\n", PortId, Index);
+
+ for (Index = 0; Index < USB_MAXCHILDREN; Index++)
+ {
+ if (HubDeviceExtension->ChildDeviceObject[Index])
+ {
+ UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)HubDeviceExtension->ChildDeviceObject[Index]->DeviceExtension;
+
+ /* Check if it matches the port ID */
+ if (UsbChildExtension->PortNumber == PortId)
+ {
+ /* We found it */
+ ChildDeviceObject = HubDeviceExtension->ChildDeviceObject[Index];
+ break;
+ }
+ }
+ }
+
+ /* Fail the request if the device doesn't exist */
+ if (!ChildDeviceObject)
+ {
+ DPRINT1("Removal request for non-existant device!\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Remove the device from the table */
+ HubDeviceExtension->ChildDeviceObject[Index] = NULL;
+
+ /* Invalidate device relations for the root hub */
+ IoInvalidateDeviceRelations(HubDeviceExtension->RootHubPhysicalDeviceObject, BusRelations);
+
+ /* The rest of the removal process takes place in IRP_MN_REMOVE_DEVICE handling for the PDO */
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
CreateUsbChildDeviceObject(
IN PDEVICE_OBJECT UsbHubDeviceObject,
}
VOID
+NTAPI
RootHubInitCallbackFunction(
PVOID Context)
{
{
Status = HubDeviceExtension->HubInterface.RootHubInitNotification(HubInterfaceBusContext,
DeviceObject,
- (PRH_INIT_CALLBACK)RootHubInitCallbackFunction);
+ RootHubInitCallbackFunction);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to set callback\n");