Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfbtrwr.c
Go to the documentation of this file.
00001 // Copyright (c) 2004, Antony C. Roberts 00002 00003 // Use of this file is subject to the terms 00004 // described in the LICENSE.TXT file that 00005 // accompanies this file. 00006 // 00007 // Your use of this file indicates your 00008 // acceptance of the terms described in 00009 // LICENSE.TXT. 00010 // 00011 // http://www.freebt.net 00012 00013 #include "fbtusb.h" 00014 #include "fbtpnp.h" 00015 #include "fbtpwr.h" 00016 #include "fbtdev.h" 00017 #include "fbtrwr.h" 00018 #include "fbtwmi.h" 00019 00020 #include "fbtusr.h" 00021 00022 // Read/Write handler 00023 NTSTATUS FreeBT_DispatchRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 00024 { 00025 PMDL mdl; 00026 PURB urb; 00027 ULONG totalLength; 00028 ULONG stageLength; 00029 NTSTATUS ntStatus; 00030 ULONG_PTR virtualAddress; 00031 PFILE_OBJECT fileObject; 00032 PDEVICE_EXTENSION deviceExtension; 00033 PIO_STACK_LOCATION irpStack; 00034 PIO_STACK_LOCATION nextStack; 00035 PFREEBT_RW_CONTEXT rwContext; 00036 //ULONG maxLength=0; 00037 00038 urb = NULL; 00039 mdl = NULL; 00040 rwContext = NULL; 00041 totalLength = 0; 00042 irpStack = IoGetCurrentIrpStackLocation(Irp); 00043 fileObject = irpStack->FileObject; 00044 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00045 00046 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: Entered\n")); 00047 00048 if (deviceExtension->DeviceState != Working) 00049 { 00050 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Invalid device state\n")); 00051 ntStatus = STATUS_INVALID_DEVICE_STATE; 00052 goto FreeBT_DispatchRead_Exit; 00053 00054 } 00055 00056 // Make sure that any selective suspend request has been completed. 00057 if (deviceExtension->SSEnable) 00058 { 00059 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: Waiting on the IdleReqPendEvent\n")); 00060 KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent, 00061 Executive, 00062 KernelMode, 00063 FALSE, 00064 NULL); 00065 00066 } 00067 00068 rwContext = (PFREEBT_RW_CONTEXT) ExAllocatePool(NonPagedPool, sizeof(FREEBT_RW_CONTEXT)); 00069 if (rwContext == NULL) 00070 { 00071 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Failed to alloc mem for rwContext\n")); 00072 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00073 goto FreeBT_DispatchRead_Exit; 00074 00075 } 00076 00077 if (Irp->MdlAddress) 00078 { 00079 totalLength = MmGetMdlByteCount(Irp->MdlAddress); 00080 00081 } 00082 00083 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Transfer data length = %d\n", totalLength)); 00084 if (totalLength == 0) 00085 { 00086 ntStatus = STATUS_SUCCESS; 00087 ExFreePool(rwContext); 00088 goto FreeBT_DispatchRead_Exit; 00089 00090 } 00091 00092 virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(Irp->MdlAddress); 00093 if (totalLength > deviceExtension->DataInPipe.MaximumPacketSize) 00094 { 00095 stageLength = deviceExtension->DataInPipe.MaximumPacketSize; 00096 00097 } 00098 00099 else 00100 { 00101 stageLength = totalLength; 00102 00103 } 00104 00105 mdl = IoAllocateMdl((PVOID) virtualAddress, totalLength, FALSE, FALSE, NULL); 00106 if (mdl == NULL) 00107 { 00108 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Failed to alloc mem for mdl\n")); 00109 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00110 ExFreePool(rwContext); 00111 goto FreeBT_DispatchRead_Exit; 00112 00113 } 00114 00115 // map the portion of user-buffer described by an mdl to another mdl 00116 IoBuildPartialMdl(Irp->MdlAddress, mdl, (PVOID) virtualAddress, stageLength); 00117 urb = (PURB) ExAllocatePool(NonPagedPool, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER)); 00118 if (urb == NULL) 00119 { 00120 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: Failed to alloc mem for urb\n")); 00121 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00122 ExFreePool(rwContext); 00123 IoFreeMdl(mdl); 00124 goto FreeBT_DispatchRead_Exit; 00125 00126 } 00127 00128 UsbBuildInterruptOrBulkTransferRequest( 00129 urb, 00130 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), 00131 deviceExtension->DataInPipe.PipeHandle, 00132 NULL, 00133 mdl, 00134 stageLength, 00135 USBD_SHORT_TRANSFER_OK | USBD_TRANSFER_DIRECTION_IN, 00136 NULL); 00137 00138 // set FREEBT_RW_CONTEXT parameters. 00139 rwContext->Urb = urb; 00140 rwContext->Mdl = mdl; 00141 rwContext->Length = totalLength - stageLength; 00142 rwContext->Numxfer = 0; 00143 rwContext->VirtualAddress = virtualAddress + stageLength; 00144 00145 // use the original read/write irp as an internal device control irp 00146 nextStack = IoGetNextIrpStackLocation(Irp); 00147 nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; 00148 nextStack->Parameters.Others.Argument1 = (PVOID) urb; 00149 nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; 00150 IoSetCompletionRoutine(Irp, 00151 (PIO_COMPLETION_ROUTINE)FreeBT_ReadCompletion, 00152 rwContext, 00153 TRUE, 00154 TRUE, 00155 TRUE); 00156 00157 // We return STATUS_PENDING; call IoMarkIrpPending. 00158 IoMarkIrpPending(Irp); 00159 00160 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 00161 if (!NT_SUCCESS(ntStatus)) 00162 { 00163 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: IoCallDriver fails with status %X\n", ntStatus)); 00164 00165 // if the device was yanked out, then the pipeInformation 00166 // field is invalid. 00167 // similarly if the request was cancelled, then we need not 00168 // invoked reset pipe/device. 00169 if((ntStatus != STATUS_CANCELLED) && (ntStatus != STATUS_DEVICE_NOT_CONNECTED)) 00170 { 00171 ntStatus = FreeBT_ResetPipe(DeviceObject, deviceExtension->DataInPipe.PipeHandle); 00172 if(!NT_SUCCESS(ntStatus)) 00173 { 00174 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchRead: FreeBT_ResetPipe failed\n")); 00175 ntStatus = FreeBT_ResetDevice(DeviceObject); 00176 00177 } 00178 00179 } 00180 00181 else 00182 { 00183 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: ntStatus is STATUS_CANCELLED or STATUS_DEVICE_NOT_CONNECTED\n")); 00184 00185 } 00186 00187 } 00188 00189 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead::")); 00190 FreeBT_IoIncrement(deviceExtension); 00191 00192 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: URB sent to lower driver, IRP is pending\n")); 00193 00194 // we return STATUS_PENDING and not the status returned by the lower layer. 00195 return STATUS_PENDING; 00196 00197 FreeBT_DispatchRead_Exit: 00198 Irp->IoStatus.Status = ntStatus; 00199 Irp->IoStatus.Information = 0; 00200 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00201 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchRead: Leaving\n")); 00202 00203 return ntStatus; 00204 00205 } 00206 00207 NTSTATUS FreeBT_ReadCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) 00208 { 00209 //ULONG stageLength; 00210 NTSTATUS ntStatus; 00211 //PIO_STACK_LOCATION nextStack; 00212 PFREEBT_RW_CONTEXT rwContext; 00213 PDEVICE_EXTENSION deviceExtension; 00214 00215 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00216 rwContext = (PFREEBT_RW_CONTEXT) Context; 00217 ntStatus = Irp->IoStatus.Status; 00218 00219 UNREFERENCED_PARAMETER(DeviceObject); 00220 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_ReadCompletion: Entered\n")); 00221 00222 if (NT_SUCCESS(ntStatus)) 00223 { 00224 Irp->IoStatus.Information = rwContext->Urb->UrbBulkOrInterruptTransfer.TransferBufferLength; 00225 00226 } 00227 00228 else 00229 { 00230 Irp->IoStatus.Information = 0; 00231 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_ReadCompletion: - failed with status = %X\n", ntStatus)); 00232 00233 } 00234 00235 if (rwContext) 00236 { 00237 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_ReadCompletion: ::")); 00238 FreeBT_IoDecrement(deviceExtension); 00239 00240 ExFreePool(rwContext->Urb); 00241 IoFreeMdl(rwContext->Mdl); 00242 ExFreePool(rwContext); 00243 00244 } 00245 00246 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_ReadCompletion: Leaving\n")); 00247 00248 return ntStatus; 00249 00250 } 00251 00252 // Read/Write handler 00253 NTSTATUS FreeBT_DispatchWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 00254 { 00255 PMDL mdl; 00256 PURB urb; 00257 ULONG totalLength; 00258 ULONG stageLength; 00259 NTSTATUS ntStatus; 00260 ULONG_PTR virtualAddress; 00261 PFILE_OBJECT fileObject; 00262 PDEVICE_EXTENSION deviceExtension; 00263 PIO_STACK_LOCATION irpStack; 00264 PIO_STACK_LOCATION nextStack; 00265 PFREEBT_RW_CONTEXT rwContext; 00266 //ULONG maxLength=0; 00267 00268 urb = NULL; 00269 mdl = NULL; 00270 rwContext = NULL; 00271 totalLength = 0; 00272 irpStack = IoGetCurrentIrpStackLocation(Irp); 00273 fileObject = irpStack->FileObject; 00274 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00275 00276 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchWrite: Entered\n")); 00277 00278 if (deviceExtension->DeviceState != Working) 00279 { 00280 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: Invalid device state\n")); 00281 ntStatus = STATUS_INVALID_DEVICE_STATE; 00282 goto FreeBT_DispatchWrite_Exit; 00283 00284 } 00285 00286 // Make sure that any selective suspend request has been completed. 00287 if (deviceExtension->SSEnable) 00288 { 00289 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_WriteDispatch: Waiting on the IdleReqPendEvent\n")); 00290 KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent, 00291 Executive, 00292 KernelMode, 00293 FALSE, 00294 NULL); 00295 00296 } 00297 00298 rwContext = (PFREEBT_RW_CONTEXT) ExAllocatePool(NonPagedPool, sizeof(FREEBT_RW_CONTEXT)); 00299 if (rwContext == NULL) 00300 { 00301 FreeBT_DbgPrint(1, ("FBTUSB: Failed to alloc mem for rwContext\n")); 00302 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00303 goto FreeBT_DispatchWrite_Exit; 00304 00305 } 00306 00307 if (Irp->MdlAddress) 00308 { 00309 totalLength = MmGetMdlByteCount(Irp->MdlAddress); 00310 00311 } 00312 00313 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: Transfer data length = %d\n", totalLength)); 00314 if (totalLength>FBT_HCI_DATA_MAX_SIZE) 00315 { 00316 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: Buffer exceeds maximum packet length (%d), failing IRP\n", FBT_HCI_DATA_MAX_SIZE)); 00317 ntStatus = STATUS_INVALID_BUFFER_SIZE; 00318 ExFreePool(rwContext); 00319 goto FreeBT_DispatchWrite_Exit; 00320 00321 } 00322 00323 if (totalLength<FBT_HCI_DATA_MIN_SIZE) 00324 { 00325 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: Zero length buffer, completing IRP\n")); 00326 ntStatus = STATUS_BUFFER_TOO_SMALL; 00327 ExFreePool(rwContext); 00328 goto FreeBT_DispatchWrite_Exit; 00329 00330 } 00331 00332 virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(Irp->MdlAddress); 00333 if (totalLength > deviceExtension->DataOutPipe.MaximumPacketSize) 00334 { 00335 stageLength = deviceExtension->DataOutPipe.MaximumPacketSize; 00336 00337 } 00338 00339 else 00340 { 00341 stageLength = totalLength; 00342 00343 } 00344 00345 mdl = IoAllocateMdl((PVOID) virtualAddress, totalLength, FALSE, FALSE, NULL); 00346 if (mdl == NULL) 00347 { 00348 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: Failed to alloc mem for mdl\n")); 00349 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00350 ExFreePool(rwContext); 00351 goto FreeBT_DispatchWrite_Exit; 00352 00353 } 00354 00355 // map the portion of user-buffer described by an mdl to another mdl 00356 IoBuildPartialMdl(Irp->MdlAddress, mdl, (PVOID) virtualAddress, stageLength); 00357 urb = (PURB) ExAllocatePool(NonPagedPool, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER)); 00358 if (urb == NULL) 00359 { 00360 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: Failed to alloc mem for urb\n")); 00361 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00362 ExFreePool(rwContext); 00363 IoFreeMdl(mdl); 00364 goto FreeBT_DispatchWrite_Exit; 00365 00366 } 00367 00368 UsbBuildInterruptOrBulkTransferRequest( 00369 urb, 00370 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), 00371 deviceExtension->DataOutPipe.PipeHandle, 00372 NULL, 00373 mdl, 00374 stageLength, 00375 USBD_SHORT_TRANSFER_OK | USBD_TRANSFER_DIRECTION_OUT, 00376 NULL); 00377 00378 // set FREEBT_RW_CONTEXT parameters. 00379 rwContext->Urb = urb; 00380 rwContext->Mdl = mdl; 00381 rwContext->Length = totalLength - stageLength; 00382 rwContext->Numxfer = 0; 00383 rwContext->VirtualAddress = virtualAddress + stageLength; 00384 00385 // use the original read/write irp as an internal device control irp 00386 nextStack = IoGetNextIrpStackLocation(Irp); 00387 nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; 00388 nextStack->Parameters.Others.Argument1 = (PVOID) urb; 00389 nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; 00390 IoSetCompletionRoutine(Irp, 00391 (PIO_COMPLETION_ROUTINE)FreeBT_WriteCompletion, 00392 rwContext, 00393 TRUE, 00394 TRUE, 00395 TRUE); 00396 00397 // We return STATUS_PENDING; call IoMarkIrpPending. 00398 IoMarkIrpPending(Irp); 00399 00400 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 00401 if (!NT_SUCCESS(ntStatus)) 00402 { 00403 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WriteDispatch: IoCallDriver fails with status %X\n", ntStatus)); 00404 00405 // if the device was yanked out, then the pipeInformation 00406 // field is invalid. 00407 // similarly if the request was cancelled, then we need not 00408 // invoked reset pipe/device. 00409 if((ntStatus != STATUS_CANCELLED) && (ntStatus != STATUS_DEVICE_NOT_CONNECTED)) 00410 { 00411 ntStatus = FreeBT_ResetPipe(DeviceObject, deviceExtension->DataOutPipe.PipeHandle); 00412 if(!NT_SUCCESS(ntStatus)) 00413 { 00414 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_ResetPipe failed\n")); 00415 ntStatus = FreeBT_ResetDevice(DeviceObject); 00416 00417 } 00418 00419 } 00420 00421 else 00422 { 00423 FreeBT_DbgPrint(3, ("FBTUSB: ntStatus is STATUS_CANCELLED or STATUS_DEVICE_NOT_CONNECTED\n")); 00424 00425 } 00426 00427 } 00428 00429 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchWrite::")); 00430 FreeBT_IoIncrement(deviceExtension); 00431 00432 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchWrite: URB sent to lower driver, IRP is pending\n")); 00433 00434 // we return STATUS_PENDING and not the status returned by the lower layer. 00435 return STATUS_PENDING; 00436 00437 FreeBT_DispatchWrite_Exit: 00438 Irp->IoStatus.Status = ntStatus; 00439 Irp->IoStatus.Information = 0; 00440 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00441 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchWrite: Leaving\n")); 00442 00443 return ntStatus; 00444 00445 } 00446 00447 NTSTATUS FreeBT_WriteCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) 00448 { 00449 ULONG stageLength; 00450 NTSTATUS ntStatus; 00451 PIO_STACK_LOCATION nextStack; 00452 PFREEBT_RW_CONTEXT rwContext; 00453 PDEVICE_EXTENSION deviceExtension; 00454 00455 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 00456 rwContext = (PFREEBT_RW_CONTEXT) Context; 00457 ntStatus = Irp->IoStatus.Status; 00458 00459 UNREFERENCED_PARAMETER(DeviceObject); 00460 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_WriteCompletion: Entered\n")); 00461 00462 if (NT_SUCCESS(ntStatus)) 00463 { 00464 if (rwContext) 00465 { 00466 rwContext->Numxfer += rwContext->Urb->UrbBulkOrInterruptTransfer.TransferBufferLength; 00467 if (rwContext->Length) 00468 { 00469 // More data to transfer 00470 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_WriteCompletion: Initiating next transfer\n")); 00471 if (rwContext->Length > deviceExtension->DataOutPipe.MaximumPacketSize) 00472 { 00473 stageLength = deviceExtension->DataOutPipe.MaximumPacketSize; 00474 00475 } 00476 00477 else 00478 { 00479 stageLength = rwContext->Length; 00480 00481 } 00482 00483 IoBuildPartialMdl(Irp->MdlAddress, rwContext->Mdl, (PVOID) rwContext->VirtualAddress, stageLength); 00484 00485 // reinitialize the urb 00486 rwContext->Urb->UrbBulkOrInterruptTransfer.TransferBufferLength = stageLength; 00487 rwContext->VirtualAddress += stageLength; 00488 rwContext->Length -= stageLength; 00489 00490 nextStack = IoGetNextIrpStackLocation(Irp); 00491 nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; 00492 nextStack->Parameters.Others.Argument1 = rwContext->Urb; 00493 nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; 00494 00495 IoSetCompletionRoutine(Irp, 00496 FreeBT_ReadCompletion, 00497 rwContext, 00498 TRUE, 00499 TRUE, 00500 TRUE); 00501 00502 IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); 00503 00504 return STATUS_MORE_PROCESSING_REQUIRED; 00505 00506 } 00507 00508 else 00509 { 00510 // No more data to transfer 00511 FreeBT_DbgPrint(1, ("FBTUSB: FreeNT_WriteCompletion: Write completed, %d bytes written\n", Irp->IoStatus.Information)); 00512 Irp->IoStatus.Information = rwContext->Numxfer; 00513 00514 } 00515 00516 } 00517 00518 } 00519 00520 else 00521 { 00522 FreeBT_DbgPrint(1, ("FBTUSB: FreeNT_WriteCompletion - failed with status = %X\n", ntStatus)); 00523 00524 } 00525 00526 if (rwContext) 00527 { 00528 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_WriteCompletion: ::")); 00529 FreeBT_IoDecrement(deviceExtension); 00530 00531 ExFreePool(rwContext->Urb); 00532 IoFreeMdl(rwContext->Mdl); 00533 ExFreePool(rwContext); 00534 00535 } 00536 00537 00538 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_WriteCompletion: Leaving\n")); 00539 00540 return ntStatus; 00541 00542 } 00543 Generated on Fri May 25 2012 04:25:25 for ReactOS by
1.7.6.1
|