2 * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbstor/misc.c
5 * PURPOSE: USB block storage device driver.
8 * Michael Martin (michael.martin@reactos.org)
9 * Johannes Anderwald (johannes.anderwald@reactos.org)
17 IO_COMPLETION_ROUTINE SyncForwardIrpCompletionRoutine
;
21 USBSTOR_SyncForwardIrpCompletionRoutine(
22 PDEVICE_OBJECT DeviceObject
,
26 if (Irp
->PendingReturned
)
28 KeSetEvent((PKEVENT
)Context
, IO_NO_INCREMENT
, FALSE
);
30 return STATUS_MORE_PROCESSING_REQUIRED
;
35 USBSTOR_SyncForwardIrp(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
43 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
46 // copy irp stack location
48 IoCopyCurrentIrpStackLocationToNext(Irp
);
51 // set completion routine
53 IoSetCompletionRoutine(Irp
, USBSTOR_SyncForwardIrpCompletionRoutine
, &Event
, TRUE
, TRUE
, TRUE
);
59 Status
= IoCallDriver(DeviceObject
, Irp
);
64 if (Status
== STATUS_PENDING
)
67 // wait for the request to finish
69 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
74 Status
= Irp
->IoStatus
.Status
;
85 USBSTOR_GetBusInterface(
86 IN PDEVICE_OBJECT DeviceObject
,
87 OUT PUSB_BUS_INTERFACE_USBDI_V2 BusInterface
)
92 IO_STATUS_BLOCK IoStatus
;
93 PIO_STACK_LOCATION Stack
;
105 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
111 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_PNP
,
127 return STATUS_INSUFFICIENT_RESOURCES
;
131 // initialize request
133 Stack
=IoGetNextIrpStackLocation(Irp
);
134 Stack
->MajorFunction
= IRP_MJ_PNP
;
135 Stack
->MinorFunction
= IRP_MN_QUERY_INTERFACE
;
136 Stack
->Parameters
.QueryInterface
.Size
= sizeof(BUS_INTERFACE_STANDARD
);
137 Stack
->Parameters
.QueryInterface
.InterfaceType
= (LPGUID
)&USB_BUS_INTERFACE_USBDI_GUID
;
138 Stack
->Parameters
.QueryInterface
.Version
= 2;
139 Stack
->Parameters
.QueryInterface
.Interface
= (PINTERFACE
)BusInterface
;
140 Stack
->Parameters
.QueryInterface
.InterfaceSpecificData
= NULL
;
141 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
146 Status
= IoCallDriver(DeviceObject
, Irp
);
149 // did operation complete
151 if (Status
== STATUS_PENDING
)
154 // wait for completion
156 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
161 Status
=IoStatus
.Status
;
168 USBSTOR_SyncUrbRequest(
169 IN PDEVICE_OBJECT DeviceObject
,
173 PIO_STACK_LOCATION IoStack
;
180 Irp
= IoAllocateIrp(DeviceObject
->StackSize
, FALSE
);
186 return STATUS_INSUFFICIENT_RESOURCES
;
192 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
196 // get next stack location
198 IoStack
= IoGetNextIrpStackLocation(Irp
);
201 // initialize stack location
203 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
204 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
205 IoStack
->Parameters
.Others
.Argument1
= (PVOID
)UrbRequest
;
206 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
= UrbRequest
->UrbHeader
.Length
;
207 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
210 // setup completion routine
212 IoSetCompletionRoutine(Irp
, USBSTOR_SyncForwardIrpCompletionRoutine
, &Event
, TRUE
, TRUE
, TRUE
);
217 Status
= IoCallDriver(DeviceObject
, Irp
);
220 // check if request is pending
222 if (Status
== STATUS_PENDING
)
225 // wait for completion
227 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
232 Status
= Irp
->IoStatus
.Status
;
248 IN POOL_TYPE PoolType
,
254 PVOID Item
= ExAllocatePoolWithTag(PoolType
, ItemSize
, USB_STOR_TAG
);
261 RtlZeroMemory(Item
, ItemSize
);
277 ExFreePoolWithTag(Item
, USB_STOR_TAG
);
281 USBSTOR_ClassRequest(
282 IN PDEVICE_OBJECT DeviceObject
,
283 IN PFDO_DEVICE_EXTENSION DeviceExtension
,
284 IN UCHAR RequestType
,
286 IN ULONG TransferFlags
,
287 IN ULONG TransferBufferLength
,
288 IN PVOID TransferBuffer
)
296 // first allocate urb
298 Urb
= (PURB
)AllocateItem(NonPagedPool
, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
));
304 return STATUS_INSUFFICIENT_RESOURCES
;
308 // allocate 1-byte buffer
310 Buffer
= (PUCHAR
)AllocateItem(NonPagedPool
, sizeof(UCHAR
));
317 return STATUS_INSUFFICIENT_RESOURCES
;
321 // initialize vendor request
323 Urb
->UrbControlVendorClassRequest
.Hdr
.Length
= sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
);
324 Urb
->UrbControlVendorClassRequest
.Hdr
.Function
= URB_FUNCTION_CLASS_INTERFACE
;
325 Urb
->UrbControlVendorClassRequest
.TransferFlags
= TransferFlags
;
326 Urb
->UrbControlVendorClassRequest
.TransferBufferLength
= TransferBufferLength
;
327 Urb
->UrbControlVendorClassRequest
.TransferBuffer
= TransferBuffer
;
328 Urb
->UrbControlVendorClassRequest
.Request
= RequestType
;
329 Urb
->UrbControlVendorClassRequest
.Index
= Index
;
334 Status
= USBSTOR_SyncUrbRequest(DeviceObject
, Urb
);
350 IN PDEVICE_OBJECT DeviceObject
,
351 IN PFDO_DEVICE_EXTENSION DeviceExtension
)
357 // allocate 1-byte buffer
359 Buffer
= (PUCHAR
)AllocateItem(NonPagedPool
, sizeof(UCHAR
));
366 return STATUS_INSUFFICIENT_RESOURCES
;
372 Status
= USBSTOR_ClassRequest(DeviceObject
, DeviceExtension
, USB_BULK_GET_MAX_LUN
, DeviceExtension
->InterfaceInformation
->InterfaceNumber
, USBD_TRANSFER_DIRECTION_IN
, sizeof(UCHAR
), Buffer
);
374 DPRINT("MaxLUN: %x\n", *Buffer
);
379 // invalid response documented in usb mass storage specification
381 Status
= STATUS_DEVICE_DATA_ERROR
;
388 DeviceExtension
->MaxLUN
= *Buffer
;
405 IN PDEVICE_OBJECT DeviceObject
,
406 IN PFDO_DEVICE_EXTENSION DeviceExtension
)
413 Status
= USBSTOR_ClassRequest(DeviceObject
, DeviceExtension
, USB_BULK_RESET_DEVICE
, DeviceExtension
->InterfaceInformation
->InterfaceNumber
, USBD_TRANSFER_DIRECTION_OUT
, 0, NULL
);
414 DPRINT1("Status %x\n", Status
);