\r
static void WvEpDisconnectHandler(WORK_ENTRY *pWork)\r
{\r
- WORK_ENTRY *work;\r
WV_PROVIDER *prov;\r
WDFREQUEST request;\r
WV_IO_EP_DISCONNECT *pattr;\r
return STATUS_SUCCESS;\r
}\r
\r
-void WvEpConnect(WV_PROVIDER *pProvider, WDFREQUEST Request)\r
+void WvEpConnectHandler(WORK_ENTRY *pWork)\r
{\r
+ WV_PROVIDER *prov;\r
+ WDFREQUEST request;\r
WV_IO_EP_CONNECT *pattr;\r
WV_ENDPOINT *ep;\r
WV_QUEUE_PAIR *qp;\r
NTSTATUS status;\r
UINT8 data[IB_REQ_PDATA_SIZE];\r
\r
- status = WdfRequestRetrieveInputBuffer(Request, sizeof(WV_IO_EP_CONNECT),\r
+ request = (WDFREQUEST) pWork->Context;\r
+ prov = WvProviderGetContext(WdfRequestGetFileObject(request));\r
+\r
+ status = WdfRequestRetrieveInputBuffer(request, sizeof(WV_IO_EP_CONNECT),\r
&pattr, NULL);\r
if (!NT_SUCCESS(status)) {\r
goto complete;\r
goto complete;\r
}\r
\r
- ep = WvEpAcquire(pProvider, pattr->Id);\r
+ ep = WvEpAcquire(prov, pattr->Id);\r
if (ep == NULL) {\r
status = STATUS_NOT_FOUND;\r
goto complete;\r
}\r
\r
- qp = WvQpAcquire(pProvider, pattr->QpId);\r
+ qp = WvQpAcquire(prov, pattr->QpId);\r
if (qp == NULL) {\r
status = STATUS_NOT_FOUND;\r
goto release;\r
ep->State = WvEpActiveConnect;\r
status = IbCmInterface.CM.send_req(ep->pIbCmId, &req);\r
if (NT_SUCCESS(status)) {\r
- status = WdfRequestForwardToIoQueue(Request, ep->Queue);\r
+ status = WdfRequestForwardToIoQueue(request, ep->Queue);\r
}\r
\r
if (!NT_SUCCESS(status)) {\r
WvEpRelease(ep);\r
complete:\r
if (!NT_SUCCESS(status)) {\r
- WdfRequestComplete(Request, status);\r
+ WdfRequestComplete(request, status);\r
}\r
}\r
\r
+static void WvEpProcessAsync(WV_PROVIDER *pProvider, WDFREQUEST Request,\r
+ void (*AsyncHandler)(struct _WORK_ENTRY *Work))\r
+{\r
+ WORK_ENTRY *work;\r
+\r
+ work = WorkEntryFromIrp(WdfRequestWdmGetIrp(Request));\r
+ WorkEntryInit(work, AsyncHandler, Request);\r
+ WorkQueueInsert(&pProvider->WorkQueue, work);\r
+}\r
+\r
+void WvEpConnect(WV_PROVIDER *pProvider, WDFREQUEST Request)\r
+{\r
+ WvEpProcessAsync(pProvider, Request, WvEpConnectHandler);\r
+}\r
+\r
static NTSTATUS WvEpModifyQpRtr(WV_ENDPOINT *pEndpoint, WV_QUEUE_PAIR *pQp,\r
UINT64 ResponderResources, UINT32 Psn,\r
UINT8 *pVerbsData, UINT32 VerbsSize)\r
return status;\r
}\r
\r
-void WvEpAccept(WV_PROVIDER *pProvider, WDFREQUEST Request)\r
+void WvEpAcceptHandler(WORK_ENTRY *pWork)\r
{\r
+ WV_PROVIDER *prov;\r
+ WDFREQUEST request;\r
WV_IO_EP_ACCEPT *pattr;\r
WV_ENDPOINT *ep;\r
NTSTATUS status;\r
UINT8 *out;\r
size_t outlen;\r
\r
- status = WdfRequestRetrieveInputBuffer(Request, sizeof(WV_IO_EP_ACCEPT),\r
+ request = (WDFREQUEST) pWork->Context;\r
+ prov = WvProviderGetContext(WdfRequestGetFileObject(request));\r
+\r
+ status = WdfRequestRetrieveInputBuffer(request, sizeof(WV_IO_EP_ACCEPT),\r
&pattr, NULL);\r
if (!NT_SUCCESS(status)) {\r
goto complete;\r
}\r
\r
- status = WdfRequestRetrieveOutputBuffer(Request, 0, &out, &outlen);\r
+ status = WdfRequestRetrieveOutputBuffer(request, 0, &out, &outlen);\r
if (!NT_SUCCESS(status) && status != STATUS_BUFFER_TOO_SMALL) {\r
goto complete;\r
}\r
goto complete;\r
}\r
\r
- ep = WvEpAcquire(pProvider, pattr->Id);\r
+ ep = WvEpAcquire(prov, pattr->Id);\r
if (ep == NULL) {\r
status = STATUS_NOT_FOUND;\r
goto complete;\r
/* EP state is re-checked under lock in WvEpAccept* calls */\r
switch (ep->State) {\r
case WvEpActiveConnect:\r
- status = WvEpAcceptActive(Request, out, outlen, ep, pattr);\r
+ status = WvEpAcceptActive(request, out, outlen, ep, pattr);\r
break;\r
case WvEpPassiveConnect:\r
- status = WvEpAcceptPassive(Request, out, outlen, ep, pattr);\r
+ status = WvEpAcceptPassive(request, out, outlen, ep, pattr);\r
break;\r
default:\r
status = STATUS_NOT_SUPPORTED;\r
WvEpRelease(ep);\r
complete:\r
if (!NT_SUCCESS(status)) {\r
- WdfRequestComplete(Request, status);\r
+ WdfRequestComplete(request, status);\r
}\r
}\r
\r
+void WvEpAccept(WV_PROVIDER *pProvider, WDFREQUEST Request)\r
+{\r
+ WvEpProcessAsync(pProvider, Request, WvEpAcceptHandler);\r
+}\r
+\r
void WvEpReject(WV_PROVIDER *pProvider, WDFREQUEST Request)\r
{\r
WV_IO_ID *id;\r