[USB-BRINGUP-TRUNK]

- Implement device disconnect indication for usbehci and usbohci
- Implement device removal for FDOs and PDOs in usbstor and usbhub

svn path=/branches/usb-bringup-trunk/; revision=55080
This commit is contained in:
Cameron Gutman 2012-01-22 21:58:06 +00:00
parent a51ccbc555
commit a1bb133fae
6 changed files with 148 additions and 36 deletions

View file

@ -1131,21 +1131,28 @@ EhciDefferedRoutine(
This->m_PortStatus[i].PortStatus |= USB_PORT_STATUS_HIGH_SPEED;
This->m_PortStatus[i].PortStatus |= USB_PORT_STATUS_CONNECT;
This->m_PortStatus[i].PortChange |= USB_PORT_STATUS_CONNECT;
//
// is there a status change callback
//
if (This->m_SCECallBack != NULL)
{
//
// queue work item for processing
//
ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
}
}
else
{
DPRINT1("Device disconnected on port %d\n", i);
//
// update port status flags
//
This->m_PortStatus[i].PortStatus &= ~USB_PORT_STATUS_HIGH_SPEED;
This->m_PortStatus[i].PortStatus &= ~USB_PORT_STATUS_CONNECT;
This->m_PortStatus[i].PortChange |= USB_PORT_STATUS_CONNECT;
}
//
// is there a status change callback
//
if (This->m_SCECallBack != NULL)
{
//
// queue work item for processing
//
ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
}
//

View file

@ -21,6 +21,11 @@ CreateUsbChildDeviceObject(
IN LONG PortId,
OUT PDEVICE_OBJECT *UsbChildDeviceObject);
NTSTATUS
DestroyUsbChildDeviceObject(
IN PDEVICE_OBJECT UsbHubDeviceObject,
IN LONG PortId);
NTSTATUS
SubmitRequestToRootHub(
IN PDEVICE_OBJECT RootHubDeviceObject,
@ -304,9 +309,11 @@ DeviceStatusChangeThread(
{
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
{
@ -999,6 +1006,51 @@ Cleanup:
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,

View file

@ -582,11 +582,21 @@ USBHUB_PdoHandlePnp(
}
case IRP_MN_REMOVE_DEVICE:
{
//
// FIXME
//
Status = STATUS_SUCCESS;
break;
PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension;
PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface;
DPRINT1("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
/* Remove the device */
HubInterface->RemoveUsbDevice(HubDeviceExtension->UsbDInterface.BusContext, UsbChildExtension->UsbDeviceHandle, 0);
/* Complete the IRP */
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
/* Delete the device object */
IoDeleteDevice(DeviceObject);
return STATUS_SUCCESS;
}
default:
{

View file

@ -1447,17 +1447,6 @@ OhciDefferedRoutine(
//
This->m_PortStatus[Index].PortStatus |= USB_PORT_STATUS_LOW_SPEED;
}
//
// is there a status change callback
//
if (This->m_SCECallBack != NULL)
{
//
// queue work item for processing
//
ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
}
}
else
{
@ -1465,6 +1454,24 @@ OhciDefferedRoutine(
// device disconnected
//
DPRINT1("Device disconnected at Port %x\n", Index);
//
// update port status flags
//
This->m_PortStatus[Index].PortStatus &= ~USB_PORT_STATUS_LOW_SPEED;
This->m_PortStatus[Index].PortStatus &= ~USB_PORT_STATUS_CONNECT;
This->m_PortStatus[Index].PortChange |= USB_PORT_STATUS_CONNECT;
}
//
// is there a status change callback
//
if (This->m_SCECallBack != NULL)
{
//
// queue work item for processing
//
ExQueueWorkItem(&This->m_StatusChangeWorkItem, DelayedWorkQueue);
}
}
}

View file

@ -118,6 +118,31 @@ USBSTOR_FdoHandleDeviceRelations(
return STATUS_SUCCESS;
}
NTSTATUS
USBSTOR_FdoHandleRemoveDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PFDO_DEVICE_EXTENSION DeviceExtension,
IN OUT PIRP Irp)
{
NTSTATUS Status;
DPRINT1("Handling FDO removal\n");
/* We don't need to request removal of our children here */
/* Send the IRP down the stack */
IoSkipCurrentIrpStackLocation(Irp);
Status = IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
/* Detach from the device stack */
/* IoDetachDevice(DeviceExtension->LowerDeviceObject); */ //This crashes for some reason during unload
/* Delete the device object */
IoDeleteDevice(DeviceObject);
return Status;
}
NTSTATUS
USBSTOR_FdoHandleStartDevice(
IN PDEVICE_OBJECT DeviceObject,
@ -302,9 +327,11 @@ USBSTOR_FdoHandlePnp(
Status = STATUS_NOT_SUPPORTED;
break;
case IRP_MN_REMOVE_DEVICE:
DPRINT1("USBSTOR_FdoHandlePnp: IRP_MN_REMOVE_DEVICE unimplemented\n");
Status = STATUS_NOT_SUPPORTED;
break;
{
DPRINT1("IRP_MN_REMOVE_DEVICE\n");
return USBSTOR_FdoHandleRemoveDevice(DeviceObject, DeviceExtension, Irp);
}
case IRP_MN_QUERY_CAPABILITIES:
{
//

View file

@ -842,9 +842,18 @@ USBSTOR_PdoHandlePnp(
break;
}
case IRP_MN_REMOVE_DEVICE:
DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_REMOVE_DEVICE unimplemented\n");
Status = STATUS_SUCCESS;
break;
{
DPRINT1("IRP_MN_REMOVE_DEVICE\n");
/* Complete the IRP */
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
/* Delete the device object */
IoDeleteDevice(DeviceObject);
return STATUS_SUCCESS;
}
case IRP_MN_QUERY_CAPABILITIES:
{
//