NTSTATUS USBSTOR_FdoHandleStartDevice( IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension, IN OUT PIRP Irp) { PUSB_INTERFACE_DESCRIPTOR InterfaceDesc; NTSTATUS Status; UCHAR Index = 0; // // forward irp to lower device // Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp); if (!NT_SUCCESS(Status)) { // // failed to start // DPRINT1("USBSTOR_FdoHandleStartDevice Lower device failed to start %x\n", Status); return Status; } // // initialize irp queue // USBSTOR_QueueInitialize(DeviceExtension); // // first get device & configuration & string descriptor // Status = USBSTOR_GetDescriptors(DeviceObject); if (!NT_SUCCESS(Status)) { // // failed to get device descriptor // DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device descriptor with %x\n", Status); return Status; } // // dump device descriptor // USBSTOR_DumpDeviceDescriptor(DeviceExtension->DeviceDescriptor); // // Check that this device uses bulk transfers and is SCSI // InterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)DeviceExtension->ConfigurationDescriptor + sizeof(USB_CONFIGURATION_DESCRIPTOR)); // // sanity check // ASSERT(InterfaceDesc->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE); ASSERT(InterfaceDesc->bLength == sizeof(USB_INTERFACE_DESCRIPTOR)); DPRINT("bInterfaceSubClass %x\n", InterfaceDesc->bInterfaceSubClass); if (InterfaceDesc->bInterfaceProtocol != 0x50) { DPRINT1("USB Device is not a bulk only device and is not currently supported\n"); return STATUS_NOT_SUPPORTED; } if (InterfaceDesc->bInterfaceSubClass != 0x06) { // // FIXME: need to pad CDBs to 12 byte // mode select commands must be translated from 1AH / 15h to 5AH / 55h // DPRINT1("[USBSTOR] Error: need to pad CDBs\n"); return STATUS_NOT_IMPLEMENTED; } // // now select an interface // Status = USBSTOR_SelectConfigurationAndInterface(DeviceObject, DeviceExtension); if (!NT_SUCCESS(Status)) { // // failed to get device descriptor // DPRINT1("USBSTOR_FdoHandleStartDevice failed to select configuration / interface with %x\n", Status); return Status; } // // check if we got a bulk in + bulk out endpoint // Status = USBSTOR_GetPipeHandles(DeviceExtension); if (!NT_SUCCESS(Status)) { // // failed to get pipe handles descriptor // DPRINT1("USBSTOR_FdoHandleStartDevice no pipe handles %x\n", Status); return Status; } // // get num of lun which are supported // Status = USBSTOR_GetMaxLUN(DeviceExtension->LowerDeviceObject, DeviceExtension); if (!NT_SUCCESS(Status)) { // // failed to get max LUN // DPRINT1("USBSTOR_FdoHandleStartDevice failed to get max lun %x\n", Status); return Status; } // // now create for each LUN a device object, 1 minimum // do { // // create pdo // Status = USBSTOR_CreatePDO(DeviceObject, Index); // // check for failure // if (!NT_SUCCESS(Status)) { // // failed to create child pdo // DPRINT1("USBSTOR_FdoHandleStartDevice USBSTOR_CreatePDO failed for Index %lu with Status %x\n", Index, Status); return Status; } // // increment pdo index // Index++; DeviceExtension->InstanceCount++; }while(Index < DeviceExtension->MaxLUN); #if 0 // // finally get usb device interface // Status = USBSTOR_GetBusInterface(DeviceExtension->LowerDeviceObject, &DeviceExtension->BusInterface); if (!NT_SUCCESS(Status)) { // // failed to device interface // DPRINT1("USBSTOR_FdoHandleStartDevice failed to get device interface %x\n", Status); return Status; } #endif // // start the timer // //IoStartTimer(DeviceObject); // // fdo is now initialized // DPRINT("USBSTOR_FdoHandleStartDevice FDO is initialized\n"); return STATUS_SUCCESS; }
NTSTATUS USBSTOR_FdoHandleDeviceRelations( IN PFDO_DEVICE_EXTENSION DeviceExtension, IN OUT PIRP Irp) { ULONG DeviceCount = 0; LONG Index; PDEVICE_RELATIONS DeviceRelations; PIO_STACK_LOCATION IoStack; // // get current irp stack location // IoStack = IoGetCurrentIrpStackLocation(Irp); // // check if relation type is BusRelations // if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations) { // // FDO always only handles bus relations // return USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp); } // // go through array and count device objects // for (Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++) { if (DeviceExtension->ChildPDO[Index]) { // // child pdo // DeviceCount++; } } // // allocate device relations // DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS) + (DeviceCount > 1 ? (DeviceCount-1) * sizeof(PDEVICE_OBJECT) : 0)); if (!DeviceRelations) { // // no memory // return STATUS_INSUFFICIENT_RESOURCES; } // // add device objects // for(Index = 0; Index < max(DeviceExtension->MaxLUN, 1); Index++) { if (DeviceExtension->ChildPDO[Index]) { // // store child pdo // DeviceRelations->Objects[DeviceRelations->Count] = DeviceExtension->ChildPDO[Index]; // // add reference // ObReferenceObject(DeviceExtension->ChildPDO[Index]); // // increment count // DeviceRelations->Count++; } } // // store result // Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; // // request completed successfully // return STATUS_SUCCESS; }
NTSTATUS USBSTOR_PdoHandlePnp( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp) { PIO_STACK_LOCATION IoStack; PPDO_DEVICE_EXTENSION DeviceExtension; NTSTATUS Status; PDEVICE_CAPABILITIES Caps; ULONG bDelete; // // get current stack location // IoStack = IoGetCurrentIrpStackLocation(Irp); // // get device extension // DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; // // sanity check // ASSERT(DeviceExtension->Common.IsFDO == FALSE); switch(IoStack->MinorFunction) { case IRP_MN_QUERY_DEVICE_RELATIONS: { Status = USBSTOR_PdoHandleDeviceRelations(DeviceObject, Irp); break; } case IRP_MN_QUERY_DEVICE_TEXT: { Status = USBSTOR_PdoHandleQueryDeviceText(DeviceObject, Irp); break; } case IRP_MN_QUERY_ID: { if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID) { // // handle query device id // Status = USBSTOR_PdoHandleQueryDeviceId(DeviceObject, Irp); break; } else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs) { // // handle instance id // Status = USBSTOR_PdoHandleQueryHardwareId(DeviceObject, Irp); break; } else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID) { // // handle instance id // Status = USBSTOR_PdoHandleQueryInstanceId(DeviceObject, Irp); break; } else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs) { // // handle instance id // Status = USBSTOR_PdoHandleQueryCompatibleId(DeviceObject, Irp); break; } DPRINT1("USBSTOR_PdoHandlePnp: IRP_MN_QUERY_ID IdType %x unimplemented\n", IoStack->Parameters.QueryId.IdType); Status = STATUS_NOT_SUPPORTED; Irp->IoStatus.Information = 0; break; } case IRP_MN_REMOVE_DEVICE: { DPRINT("IRP_MN_REMOVE_DEVICE\n"); if(*DeviceExtension->PDODeviceObject != NULL) { // // clear entry in FDO pdo list // *DeviceExtension->PDODeviceObject = NULL; bDelete = TRUE; } else { // // device object already marked for deletion // bDelete = FALSE; } /* Complete the IRP */ Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); if (bDelete) { /* Delete the device object */ IoDeleteDevice(DeviceObject); } return STATUS_SUCCESS; } case IRP_MN_QUERY_CAPABILITIES: { // // just forward irp to lower device // Status = USBSTOR_SyncForwardIrp(DeviceExtension->LowerDeviceObject, Irp); ASSERT(Status == STATUS_SUCCESS); if (NT_SUCCESS(Status)) { // // check if no unique id // Caps = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities; Caps->UniqueID = FALSE; // no unique id is supported Caps->Removable = TRUE; //FIXME } break; } case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_QUERY_STOP_DEVICE: { #if 0 // // if we're not claimed it's ok // if (DeviceExtension->Claimed) #else if (TRUE) #endif { Status = STATUS_UNSUCCESSFUL; DPRINT1("[USBSTOR] Request %x fails because device is still claimed\n", IoStack->MinorFunction); } else Status = STATUS_SUCCESS; break; } case IRP_MN_START_DEVICE: { // // no-op for PDO // Status = STATUS_SUCCESS; break; } case IRP_MN_SURPRISE_REMOVAL: { Status = STATUS_SUCCESS; break; } default: { // // do nothing // Status = Irp->IoStatus.Status; } } // // complete request // if (Status != STATUS_PENDING) { // // store result // Irp->IoStatus.Status = Status; // // complete request // IoCompleteRequest(Irp, IO_NO_INCREMENT); } // // done processing // return Status; }