[USB]
[reactos.git] / reactos / drivers / usb / usbstor / usbstor.c
index ef8cd7e..50fb0bf 100644 (file)
@@ -5,6 +5,7 @@
  * PURPOSE:     USB block storage device driver.
  * PROGRAMMERS:
  *              James Tabor
+                Johannes Anderwald
  */
 
 /* INCLUDES ******************************************************************/
 
 /* PUBLIC AND PRIVATE FUNCTIONS **********************************************/
 
-NTSTATUS NTAPI
-IrpStub(IN PDEVICE_OBJECT DeviceObject,
-        IN PIRP Irp)
+NTSTATUS
+NTAPI
+USBSTOR_AddDevice(
+    IN PDRIVER_OBJECT DriverObject,
+    IN PDEVICE_OBJECT PhysicalDeviceObject)
 {
-    NTSTATUS Status = STATUS_NOT_SUPPORTED;
-    Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return Status;
-}
+    NTSTATUS Status;
+    PDEVICE_OBJECT DeviceObject;
+    PFDO_DEVICE_EXTENSION DeviceExtension;
 
-NTSTATUS NTAPI
-AddDevice(IN PDRIVER_OBJECT DriverObject,
-          IN PDEVICE_OBJECT pdo)
-{
-    return STATUS_SUCCESS;
-}
+    //
+    // lets create the device
+    //
+    Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), 0, FILE_DEVICE_BUS_EXTENDER, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject);
 
-VOID NTAPI
-DriverUnload(PDRIVER_OBJECT DriverObject)
-{
+    //
+    // check for success
+    //
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("USBSTOR_AddDevice: Failed to create FDO Status %x\n", Status);
+        return Status;
+    }
+
+    //
+    // get device extension
+    //
+    DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    ASSERT(DeviceExtension);
+
+    //
+    // zero device extension
+    //
+    RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
+
+    //
+    // initialize device extension
+    //
+    DeviceExtension->Common.IsFDO = TRUE;
+    DeviceExtension->FunctionalDeviceObject = DeviceObject;
+    DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
+    DeviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
+
+    //
+    // did attaching fail
+    //
+    if (!DeviceExtension->LowerDeviceObject)
+    {
+        //
+        // device removed
+        //
+        IoDeleteDevice(DeviceObject);
+
+        return STATUS_DEVICE_REMOVED;
+    }
+
+    //
+    // set device flags
+    //
+    DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
+
+    //
+    // device is initialized
+    //
+    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+
+
+    //
+    // done
+    //
+    return STATUS_SUCCESS;
 }
 
-VOID NTAPI
-StartIo(PUSBSTOR_DEVICE_EXTENSION DeviceExtension,
-        PIRP Irp)
+VOID
+NTAPI
+USBSTOR_Unload(
+    PDRIVER_OBJECT DriverObject)
 {
+    //
+    // no-op
+    //
 }
 
-static NTSTATUS NTAPI
-DispatchClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+NTSTATUS
+NTAPI
+USBSTOR_DispatchClose(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
 {
+    //
+    // function always succeeds ;)
+    //
+    DPRINT("USBSTOR_DispatchClose\n");
     Irp->IoStatus.Information = 0;
     Irp->IoStatus.Status = STATUS_SUCCESS;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
     return STATUS_SUCCESS;
 }
 
-static NTSTATUS NTAPI
-DispatchCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
-{
-    return STATUS_SUCCESS;
-}
 
-static NTSTATUS NTAPI
-DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+NTSTATUS
+NTAPI
+USBSTOR_DispatchDeviceControl(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
 {
-    return STATUS_SUCCESS;
-}
+    NTSTATUS Status;
 
+    //
+    // handle requests
+    //
+    Status = USBSTOR_HandleDeviceControl(DeviceObject, Irp);
 
-static NTSTATUS NTAPI
-DispatchScsi(PDEVICE_OBJECT DeviceObject, PIRP Irp)
-{
-    return STATUS_SUCCESS;
+    //
+    // complete request
+    //
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    //
+    // done
+    //
+    return Status;
 }
 
-static NTSTATUS NTAPI
-DispatchReadWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+
+NTSTATUS
+NTAPI
+USBSTOR_DispatchScsi(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
 {
-    return STATUS_SUCCESS;
+    //
+    // handle requests
+    //
+    return USBSTOR_HandleInternalDeviceControl(DeviceObject, Irp);
 }
 
-static NTSTATUS NTAPI
-DispatchSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+NTSTATUS
+NTAPI
+USBSTOR_DispatchReadWrite(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
 {
-    return STATUS_SUCCESS;
+    //
+    // read write ioctl is not supported
+    //
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_INVALID_PARAMETER;
 }
 
-static NTSTATUS NTAPI
-DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+NTSTATUS
+NTAPI
+USBSTOR_DispatchPnp(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
 {
-    return STATUS_SUCCESS;
+    PUSBSTOR_COMMON_DEVICE_EXTENSION DeviceExtension;
+
+    //
+    // get common device extension
+    //
+    DeviceExtension = (PUSBSTOR_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    //
+    // is it for the FDO
+    //
+    if (DeviceExtension->IsFDO)
+    {
+        //
+        // dispatch pnp request to fdo pnp handler
+        //
+        return USBSTOR_FdoHandlePnp(DeviceObject, Irp);
+    }
+    else
+    {
+        //
+        // dispatch request to pdo pnp handler
+        //
+        return USBSTOR_PdoHandlePnp(DeviceObject, Irp);
+    }
 }
 
-static NTSTATUS NTAPI
-DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
+NTSTATUS
+NTAPI
+USBSTOR_DispatchPower(
+    PDEVICE_OBJECT DeviceObject,
+    PIRP Irp)
 {
-    DPRINT1("USBSTOR: IRP_MJ_POWER unimplemented\n");
+    UNIMPLEMENTED
+
     Irp->IoStatus.Information = 0;
     Irp->IoStatus.Status = STATUS_SUCCESS;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
@@ -101,37 +217,61 @@ DispatchPower(PDEVICE_OBJECT fido, PIRP Irp)
 
 
 
-/*
- * Standard DriverEntry method.
- */
-NTSTATUS NTAPI
-DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath)
+NTSTATUS
+NTAPI
+DriverEntry(
+    IN PDRIVER_OBJECT DriverObject,
+    IN PUNICODE_STRING RegPath)
 {
-    ULONG i;
 
     DPRINT("********* USB Storage *********\n");
 
-    DriverObject->DriverUnload = DriverUnload;
-    DriverObject->DriverExtension->AddDevice = AddDevice;
+    //
+    // driver unload routine
+    //
+    DriverObject->DriverUnload = USBSTOR_Unload;
+
+    //
+    // add device function
+    //
+    DriverObject->DriverExtension->AddDevice = USBSTOR_AddDevice;
+
+    //
+    // driver start i/o routine
+    //
+    DriverObject->DriverStartIo = USBSTOR_StartIo;
+
+    //
+    // create / close
+    //
+    DriverObject->MajorFunction[IRP_MJ_CREATE] = USBSTOR_DispatchClose;
+    DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBSTOR_DispatchClose;
 
-    for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
-        DriverObject->MajorFunction[i] = IrpStub;
+    //
+    // scsi pass through requests
+    //
+    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBSTOR_DispatchDeviceControl;
 
-    DriverObject->DriverStartIo = (PVOID)StartIo;
+    //
+    // irp dispatch read / write
+    //
+    DriverObject->MajorFunction[IRP_MJ_READ] = USBSTOR_DispatchReadWrite;
+    DriverObject->MajorFunction[IRP_MJ_WRITE] = USBSTOR_DispatchReadWrite;
 
-    DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchClose;
-    DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
-    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup;
-    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
-    DriverObject->MajorFunction[IRP_MJ_READ] = DispatchReadWrite;
-    DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchReadWrite;
+    //
+    // scsi queue ioctl
+    //
+    DriverObject->MajorFunction[IRP_MJ_SCSI] = USBSTOR_DispatchScsi;
 
-    /* Scsi Miniport support */
-    DriverObject->MajorFunction[IRP_MJ_SCSI] = DispatchScsi;
-    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = DispatchSystemControl;
+    //
+    // pnp processing
+    //
+    DriverObject->MajorFunction[IRP_MJ_PNP] = USBSTOR_DispatchPnp;
 
-    DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
-    DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
+    //
+    // power processing
+    //
+    DriverObject->MajorFunction[IRP_MJ_POWER] = USBSTOR_DispatchPower;
 
     return STATUS_SUCCESS;
 }