summaryrefslogtreecommitdiff
path: root/bluetooth/bthecho/bthcli/sys/queue.c
diff options
context:
space:
mode:
authorDave Wilson <[email protected]>2015-04-29 09:48:49 -0700
committerDave Wilson <[email protected]>2015-04-29 10:47:29 -0700
commitd40232638faaab19de557e70a3ee938da7a35295 (patch)
tree14e61c973745949af186b7940e3a53d25322f5de /bluetooth/bthecho/bthcli/sys/queue.c
parent02e5b090a6131a7cc1b90f4a9373117c9e3c7088 (diff)
samples update for //build
Diffstat (limited to 'bluetooth/bthecho/bthcli/sys/queue.c')
-rw-r--r--bluetooth/bthecho/bthcli/sys/queue.c349
1 files changed, 349 insertions, 0 deletions
diff --git a/bluetooth/bthecho/bthcli/sys/queue.c b/bluetooth/bthecho/bthcli/sys/queue.c
new file mode 100644
index 00000000..6f1e244c
--- /dev/null
+++ b/bluetooth/bthecho/bthcli/sys/queue.c
@@ -0,0 +1,349 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ Queue.c
+
+Abstract:
+
+ Read/write functionality for bthecho client
+
+Environment:
+
+ Kernel mode only
+
+
+--*/
+
+#include "clisrv.h"
+#include "device.h"
+#include "queue.h"
+
+#if defined(EVENT_TRACING)
+#include "queue.tmh"
+#endif
+
+void
+BthEchoCliReadWriteCompletion(
+ _In_ WDFREQUEST Request,
+ _In_ WDFIOTARGET Target,
+ _In_ PWDF_REQUEST_COMPLETION_PARAMS Params,
+ _In_ WDFCONTEXT Context
+ )
+/*++
+Description:
+
+ Completion routine for read/write requests
+
+ We receive l2ca transfer BRB as the context. This BRB
+ is part of the request context and doesn't need to be freed
+ explicitly.
+
+Arguments:
+
+ Request - Request that got completed
+ Target - Target to which request was sent
+ Params - Completion parameters for the request
+ Context - We receive BRB as the context
+
+--*/
+{
+ struct _BRB_L2CA_ACL_TRANSFER *brb;
+ size_t information;
+
+ UNREFERENCED_PARAMETER(Target);
+
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_CONNECT,
+ "I/O completion, status: %!STATUS!", Params->IoStatus.Status);
+
+ brb = (struct _BRB_L2CA_ACL_TRANSFER *) Context;
+
+ NT_ASSERT((brb != NULL));
+
+ //
+ // Bytes read/written are contained in Brb->BufferSize
+ //
+ information = brb->BufferSize;
+
+ //
+ // Complete the request
+ //
+ WdfRequestCompleteWithInformation(
+ Request,
+ Params->IoStatus.Status,
+ information
+ );
+}
+
+VOID
+BthEchoCliEvtQueueIoWrite(
+ _In_ WDFQUEUE Queue,
+ _In_ WDFREQUEST Request,
+ _In_ size_t Length
+ )
+/*++
+Description:
+
+ This routine is invoked by the framework to deliver a
+ Write request to the driver.
+
+Arguments:
+
+ Queue - Queue delivering the request
+ Request - Write request
+ Length - Length of write
+
+--*/
+{
+ NTSTATUS status;
+ PBTHECHOSAMPLE_CLIENT_CONTEXT DevCtx;
+ WDFMEMORY memory;
+ struct _BRB_L2CA_ACL_TRANSFER * brb = NULL;
+ PBTHECHO_CONNECTION connection;
+
+ UNREFERENCED_PARAMETER(Length);
+
+ connection = GetFileContext(WdfRequestGetFileObject(Request))->Connection;
+
+ DevCtx = GetClientDeviceContext(WdfIoQueueGetDevice(Queue));
+
+ status = WdfRequestRetrieveInputMemory(
+ Request,
+ &memory
+ );
+
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
+ "WdfRequestRetrieveInputMemory failed, request 0x%p, Status code %!STATUS!\n",
+ Request,
+ status);
+
+ goto exit;
+ }
+
+ //
+ // Get the BRB from request context and initialize it as
+ // BRB_L2CA_ACL_TRANSFER BRB
+ //
+ brb = (struct _BRB_L2CA_ACL_TRANSFER *)GetRequestContext(Request);
+ DevCtx->Header.ProfileDrvInterface.BthReuseBrb(
+ (PBRB)brb,
+ BRB_L2CA_ACL_TRANSFER
+ );
+
+
+ //
+ // Format the Write request for L2Ca OUT transfer
+ //
+ // This routine allocates a BRB which is returned to us
+ // in brb parameter
+ //
+ // This BRB is freed by the completion routine is we send the
+ // request successfully, else it is freed by this routine.
+ //
+ status = BthEchoConnectionObjectFormatRequestForL2CaTransfer(
+ connection,
+ Request,
+ &brb,
+ memory,
+ ACL_TRANSFER_DIRECTION_OUT
+ );
+
+ if (!NT_SUCCESS(status))
+ {
+ goto exit;
+ }
+
+ //
+ // Set a CompletionRoutine callback function.
+ //
+
+ WdfRequestSetCompletionRoutine(
+ Request,
+ BthEchoCliReadWriteCompletion,
+ brb
+ );
+
+ //
+ // Send the request down the stack
+ //
+ if (FALSE == WdfRequestSend(
+ Request,
+ DevCtx->Header.IoTarget,
+ NULL
+ ))
+ {
+ status = WdfRequestGetStatus(Request);
+
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_UTIL,
+ "Request send failed for request 0x%p, Brb 0x%p, Status code %!STATUS!\n",
+ Request,
+ brb,
+ status
+ );
+
+ goto exit;
+ }
+
+exit:
+ if (!NT_SUCCESS(status))
+ {
+ WdfRequestComplete(Request, status);
+ }
+}
+
+VOID
+BthEchoCliEvtQueueIoRead (
+ _In_ WDFQUEUE Queue,
+ _In_ WDFREQUEST Request,
+ _In_ size_t Length
+ )
+/*++
+Description:
+
+ This routine is invoked by the framework to deliver a
+ Read request to the driver.
+
+Arguments:
+
+ Queue - Queue delivering the request
+ Request - Read request
+ Length - Length of Read
+
+--*/
+{
+ NTSTATUS status;
+ PBTHECHOSAMPLE_CLIENT_CONTEXT DevCtx;
+ WDFMEMORY memory;
+ struct _BRB_L2CA_ACL_TRANSFER * brb = NULL;
+ PBTHECHO_CONNECTION connection;
+
+ UNREFERENCED_PARAMETER(Length);
+
+ connection = GetFileContext(WdfRequestGetFileObject(Request))->Connection;
+
+ DevCtx = GetClientDeviceContext(WdfIoQueueGetDevice(Queue));
+
+ status = WdfRequestRetrieveOutputMemory(
+ Request,
+ &memory
+ );
+
+ if (!NT_SUCCESS(status))
+ {
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
+ "WdfRequestRetrieveInputMemory failed, request 0x%p, Status code %!STATUS!\n",
+ Request,
+ status);
+
+ goto exit;
+ }
+
+ //
+ // Get the BRB from request context and initialize it as
+ // BRB_L2CA_ACL_TRANSFER BRB
+ //
+ brb = (struct _BRB_L2CA_ACL_TRANSFER *)GetRequestContext(Request);
+ DevCtx->Header.ProfileDrvInterface.BthReuseBrb(
+ (PBRB)brb,
+ BRB_L2CA_ACL_TRANSFER
+ );
+
+ //
+ // Format the Read request for L2Ca IN transfer
+ //
+ // This routine allocates a BRB which is returned to us
+ // in brb parameter
+ //
+ // This BRB is freed by the completion routine is we send the
+ // request successfully, else it is freed by this routine.
+ //
+ status = BthEchoConnectionObjectFormatRequestForL2CaTransfer(
+ connection,
+ Request,
+ &brb,
+ memory,
+ ACL_TRANSFER_DIRECTION_IN | ACL_SHORT_TRANSFER_OK
+ );
+
+ if (!NT_SUCCESS(status))
+ {
+ goto exit;
+ }
+
+ //
+ // Set a CompletionRoutine callback function.
+ //
+
+ WdfRequestSetCompletionRoutine(
+ Request,
+ BthEchoCliReadWriteCompletion,
+ brb
+ );
+
+ //
+ // Send the request down the stack
+ //
+ if (FALSE == WdfRequestSend(
+ Request,
+ DevCtx->Header.IoTarget,
+ NULL
+ ))
+ {
+ status = WdfRequestGetStatus(Request);
+
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_UTIL,
+ "Request send failed for request 0x%p, Brb 0x%p, Status code %!STATUS!\n",
+ Request,
+ brb,
+ status
+ );
+
+ goto exit;
+ }
+
+exit:
+ if (!NT_SUCCESS(status))
+ {
+ WdfRequestComplete(Request, status);
+ }
+}
+
+VOID
+BthEchoCliEvtQueueIoStop(
+ _In_ WDFQUEUE Queue,
+ _In_ WDFREQUEST Request,
+ _In_ ULONG ActionFlags
+ )
+/*++
+Description:
+
+ This routine is invoked by Framework when Queue is being stopped
+
+ We implement this routine to cancel any requests owned by our driver.
+
+ Without this Queue stop would wait indefinitely for requests to complete
+ during surprise remove.
+
+Arguments:
+
+ Queue - Framework queue being stopped
+ Request - Request owned by the driver
+ ActionFlags - Action flags
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Queue);
+ UNREFERENCED_PARAMETER(ActionFlags);
+
+ WdfRequestCancelSentRequest(Request);
+}
+