[USBSTOR][USBHUB]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Mon, 22 Oct 2012 11:33:26 +0000 (11:33 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Mon, 22 Oct 2012 11:33:26 +0000 (11:33 +0000)
- Append devobj number to device id
- Delete device objects
- Core-6598

svn path=/trunk/; revision=57592

reactos/drivers/usb/usbhub/fdo.c
reactos/drivers/usb/usbhub/pdo.c
reactos/drivers/usb/usbhub/usbhub.h
reactos/drivers/usb/usbstor/fdo.c
reactos/drivers/usb/usbstor/pdo.c
reactos/drivers/usb/usbstor/usbstor.h

index ec56674..65c529c 100644 (file)
@@ -819,6 +819,7 @@ CreateDeviceIds(
     LPWSTR DeviceString;
     WCHAR Buffer[200];
     PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
+    PHUB_DEVICE_EXTENSION HubDeviceExtension;
     PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;
     PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
     PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
@@ -828,6 +829,9 @@ CreateDeviceIds(
     //
     UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)UsbChildDeviceObject->DeviceExtension;
 
+    // get hub device extension
+    HubDeviceExtension = (PHUB_DEVICE_EXTENSION) UsbChildExtension->ParentDeviceObject->DeviceExtension;
+
     //
     // get device descriptor
     //
@@ -1011,10 +1015,12 @@ CreateDeviceIds(
     //
     if (UsbChildExtension->DeviceDesc.iSerialNumber)
     {
+       LPWSTR SerialBuffer = NULL;
+
         Status = GetUsbStringDescriptor(UsbChildDeviceObject,
                                         UsbChildExtension->DeviceDesc.iSerialNumber,
                                         0,
-                                        (PVOID*)&UsbChildExtension->usInstanceId.Buffer,
+                                        (PVOID*)&SerialBuffer,
                                         &UsbChildExtension->usInstanceId.Length);
         if (!NT_SUCCESS(Status))
         {
@@ -1022,15 +1028,31 @@ CreateDeviceIds(
             return Status;
         }
 
-        UsbChildExtension->usInstanceId.MaximumLength = UsbChildExtension->usInstanceId.Length;
-        DPRINT("Usb InstanceId %wZ\n", &UsbChildExtension->usInstanceId);
+        // construct instance id buffer
+        Index = swprintf(Buffer, L"%04d&%s", HubDeviceExtension->InstanceCount, SerialBuffer) + 1;
+        UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR));
+        if (UsbChildExtension->usInstanceId.Buffer == NULL)
+        {
+            DPRINT1("Error: failed to allocate %lu bytes\n", Index * sizeof(WCHAR));
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            return Status;
+        }
+
+        //
+        // copy instance id
+        //
+        RtlCopyMemory(UsbChildExtension->usInstanceId.Buffer, Buffer, Index * sizeof(WCHAR));
+        UsbChildExtension->usInstanceId.Length = UsbChildExtension->usInstanceId.MaximumLength = Index * sizeof(WCHAR);
+        ExFreePool(SerialBuffer);
+
+        DPRINT("Usb InstanceId %wZ InstanceCount %x\n", &UsbChildExtension->usInstanceId, HubDeviceExtension->InstanceCount);
     }
     else
     {
        //
        // the device did not provide a serial number, lets create a pseudo instance id
        //
-       Index = swprintf(Buffer, L"0&%04d", UsbChildExtension->PortNumber) + 1;
+       Index = swprintf(Buffer, L"%04d&%04d", HubDeviceExtension->InstanceCount, UsbChildExtension->PortNumber) + 1;
        UsbChildExtension->usInstanceId.Buffer = (LPWSTR)ExAllocatePool(NonPagedPool, Index * sizeof(WCHAR));
        if (UsbChildExtension->usInstanceId.Buffer == NULL)
        {
@@ -1304,6 +1326,7 @@ CreateUsbChildDeviceObject(
     }
 
     HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] = NewChildDeviceObject;
+    HubDeviceExtension->InstanceCount++;
 
     IoInvalidateDeviceRelations(RootHubDeviceObject, BusRelations);
     return STATUS_SUCCESS;
index 939a9f3..6c561b9 100644 (file)
@@ -558,6 +558,7 @@ USBHUB_PdoHandlePnp(
     ULONG Index;
     ULONG bFound;
     PDEVICE_RELATIONS DeviceRelation;
+    PDEVICE_OBJECT ParentDevice;
 
     UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
     Stack = IoGetCurrentIrpStackLocation(Irp);
@@ -645,6 +646,7 @@ USBHUB_PdoHandlePnp(
         {
             PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension;
             PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface;
+            ParentDevice = UsbChildExtension->ParentDeviceObject;
 
             DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
 
@@ -671,10 +673,13 @@ USBHUB_PdoHandlePnp(
             Irp->IoStatus.Status = STATUS_SUCCESS;
             IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
+            /* delete device */
+            IoDeleteDevice(DeviceObject);
+
             if (bFound)
             {
-                /* Delete the device object */
-                IoDeleteDevice(DeviceObject);
+                /* invalidate device relations */
+                IoInvalidateDeviceRelations(ParentDevice, BusRelations);
             }
 
             return STATUS_SUCCESS;
@@ -731,6 +736,12 @@ USBHUB_PdoHandlePnp(
             IoSkipCurrentIrpStackLocation(Irp);
             return IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp);
         }
+        case IRP_MN_SURPRISE_REMOVAL:
+        {
+            DPRINT("[USBHUB] HandlePnp IRP_MN_SURPRISE_REMOVAL\n");
+            Status = STATUS_SUCCESS;
+            break;
+        }
         default:
         {
             DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
index 2333775..52d62e2 100644 (file)
@@ -103,8 +103,9 @@ typedef struct _HUB_DEVICE_EXTENSION
     PVOID RootHubHandle;
     USB_BUS_INTERFACE_USBDI_V2 DeviceInterface;
 
-
     UNICODE_STRING SymbolicLinkName;
+    ULONG InstanceCount;
+
 } HUB_DEVICE_EXTENSION, *PHUB_DEVICE_EXTENSION;
 
 // createclose.c
index 0751842..a9f408d 100644 (file)
@@ -125,10 +125,19 @@ USBSTOR_FdoHandleRemoveDevice(
     IN OUT PIRP Irp)
 {
     NTSTATUS Status;
+    ULONG Index;
 
-    DPRINT("Handling FDO removal\n");
+    DPRINT("Handling FDO removal %p\n", DeviceObject);
 
-    /* We don't need to request removal of our children here */
+    /* FIXME: wait for devices finished processing */
+    for(Index = 0; Index < 16; Index++)
+    {
+        if (DeviceExtension->ChildPDO[Index] != NULL)
+        {
+            DPRINT("Deleting PDO %p RefCount %x AttachedDevice %p \n", DeviceExtension->ChildPDO[Index], DeviceExtension->ChildPDO[Index]->ReferenceCount, DeviceExtension->ChildPDO[Index]->AttachedDevice);
+            IoDeleteDevice(DeviceExtension->ChildPDO[Index]);
+        }
+    }
 
     /* Send the IRP down the stack */
     IoSkipCurrentIrpStackLocation(Irp);
@@ -264,7 +273,7 @@ USBSTOR_FdoHandleStartDevice(
         //
         // create pdo
         //
-        Status = USBSTOR_CreatePDO(DeviceObject, Index, &DeviceExtension->ChildPDO[Index]);
+        Status = USBSTOR_CreatePDO(DeviceObject, Index);
 
         //
         // check for failure
@@ -282,6 +291,7 @@ USBSTOR_FdoHandleStartDevice(
         // increment pdo index
         //
         Index++;
+        DeviceExtension->InstanceCount++;
 
     }while(Index < DeviceExtension->MaxLUN);
 
@@ -340,8 +350,20 @@ USBSTOR_FdoHandlePnp(
 
     switch(IoStack->MinorFunction)
     {
+       case IRP_MN_SURPRISE_REMOVAL:
+       {
+           DPRINT("IRP_MN_SURPRISE_REMOVAL %p\n", DeviceObject);
+           Irp->IoStatus.Status = STATUS_SUCCESS;
+
+            //
+            // forward irp to next device object
+            //
+            IoSkipCurrentIrpStackLocation(Irp);
+            return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
+       }
        case IRP_MN_QUERY_DEVICE_RELATIONS:
        {
+           DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS %p\n", DeviceObject);
            Status = USBSTOR_FdoHandleDeviceRelations(DeviceExtension, Irp);
            break;
        }
index 9e293df..f7a2a65 100644 (file)
@@ -676,9 +676,9 @@ USBSTOR_PdoHandleQueryInstanceId(
     else
     {
         //
-        // FIXME: should use some random value
+        // use instance count and LUN
         //
-        swprintf(Buffer, L"%s&%d", L"00000000", PDODeviceExtension->LUN);
+        swprintf(Buffer, L"%04d&%d", FDODeviceExtension->InstanceCount, PDODeviceExtension->LUN);
     }
 
     //
@@ -897,7 +897,7 @@ USBSTOR_PdoHandlePnp(
                // check if no unique id
                //
                Caps = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
-               Caps->UniqueID = TRUE; //FIXME
+               Caps->UniqueID = FALSE; // no unique id is supported
                Caps->Removable = TRUE; //FIXME
            }
            break;
@@ -929,6 +929,11 @@ USBSTOR_PdoHandlePnp(
            Status = STATUS_SUCCESS;
            break;
        }
+       case IRP_MN_SURPRISE_REMOVAL:
+       {
+           Status = STATUS_SUCCESS;
+           break;
+       }
        default:
         {
             //
@@ -1256,13 +1261,19 @@ USBSTOR_SendFormatCapacityIrp(
 NTSTATUS
 USBSTOR_CreatePDO(
     IN PDEVICE_OBJECT DeviceObject,
-    IN UCHAR LUN,
-    OUT PDEVICE_OBJECT *ChildDeviceObject)
+    IN UCHAR LUN)
 {
     PDEVICE_OBJECT PDO;
     NTSTATUS Status;
     PPDO_DEVICE_EXTENSION PDODeviceExtension;
     PUFI_INQUIRY_RESPONSE Response;
+    PFDO_DEVICE_EXTENSION FDODeviceExtension;
+
+    //
+    // get device extension
+    //
+    FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
 
     //
     // create child device object
@@ -1292,7 +1303,7 @@ USBSTOR_CreatePDO(
     RtlZeroMemory(PDODeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
     PDODeviceExtension->Common.IsFDO = FALSE;
     PDODeviceExtension->LowerDeviceObject = DeviceObject;
-    PDODeviceExtension->PDODeviceObject = ChildDeviceObject;
+    PDODeviceExtension->PDODeviceObject = &FDODeviceExtension->ChildPDO[LUN];
     PDODeviceExtension->Self = PDO;
     PDODeviceExtension->LUN = LUN;
 
@@ -1309,7 +1320,7 @@ USBSTOR_CreatePDO(
     //
     // output device object
     //
-    *ChildDeviceObject = PDO;
+    FDODeviceExtension->ChildPDO[LUN] = PDO;
 
     //
     // send inquiry command by irp
index 29ef1ce..3fb4d3c 100644 (file)
@@ -71,6 +71,7 @@ typedef struct
     PSCSI_REQUEST_BLOCK LastTimerActiveSrb;                                              // last timer tick active srb
     ULONG SrbErrorHandlingActive;                                                        // error handling of srb is activated
     ULONG TimerWorkQueueEnabled;                                                         // timer work queue enabled
+    ULONG InstanceCount;                                                                 // pdo instance count
 }FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
 
 typedef struct
@@ -364,8 +365,7 @@ USBSTOR_PdoHandlePnp(
 NTSTATUS
 USBSTOR_CreatePDO(
     IN PDEVICE_OBJECT DeviceObject,
-    IN UCHAR LUN,
-    OUT PDEVICE_OBJECT *ChildDeviceObject);
+    IN UCHAR LUN);
 
 //---------------------------------------------------------------------
 //