\r
#define AL_RMPP_WINDOW 16 /* Max size of RMPP window */\r
#define AL_REASSEMBLY_TIMEOUT 5000 /* 5 seconds */\r
+#define AL_RMPP_RETRIES 5\r
\r
static void\r
__cleanup_mad_disp(\r
return IB_INVALID_SETTING;\r
}\r
\r
+ if( !p_mad_element->timeout_ms )\r
+ p_mad_element->timeout_ms = AL_REASSEMBLY_TIMEOUT;\r
+\r
+ if( !h_send->retry_cnt )\r
+ h_send->retry_cnt = AL_RMPP_RETRIES;\r
+\r
p_rmpp_hdr->rmpp_version = rmpp_version;\r
p_rmpp_hdr->rmpp_type = IB_RMPP_TYPE_DATA;\r
ib_rmpp_set_resp_time( p_rmpp_hdr, IB_RMPP_NO_RESP_TIME );\r
IWMProvider *prov;\r
NET64 dev_guid;\r
OVERLAPPED overlap;\r
- BOOL pending;\r
UINT8 port_num;\r
\r
} um_port_t;\r
return 0;\r
}\r
\r
+static void umad_cancel_recv(um_port_t *port)\r
+{\r
+ DWORD bytes;\r
+\r
+ port->prov->CancelOverlappedRequests();\r
+ port->prov->GetOverlappedResult(&port->overlap, &bytes, TRUE);\r
+}\r
+\r
__declspec(dllexport)\r
int umad_recv(int portid, void *umad, int *length, int timeout_ms)\r
{\r
\r
port = &ports[portid];\r
hr = port->prov->Receive(mad, sizeof(WM_MAD) + (size_t) *length, &port->overlap);\r
-\r
if (hr == WV_IO_PENDING) {\r
- if (port->pending && timeout_ms == 0) {\r
- do {\r
- hr = WaitForSingleObject(port->overlap.hEvent, 250);\r
- } while (hr == WAIT_TIMEOUT && port->pending);\r
- } else {\r
- hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms);\r
- if (hr == WAIT_TIMEOUT) {\r
- _set_errno(EWOULDBLOCK);\r
- return -EWOULDBLOCK;\r
- }\r
+ hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms);\r
+ if (hr == WAIT_TIMEOUT) {\r
+ umad_cancel_recv(port);\r
+ _set_errno(EWOULDBLOCK);\r
+ return -EWOULDBLOCK;\r
}\r
}\r
\r
}\r
\r
if (mad->Length <= (UINT32) *length) {\r
- port->pending = FALSE;\r
hr = (HRESULT) mad->Id;\r
umad_convert_av(&mad->Address, &((struct ib_user_mad *) mad)->addr);\r
} else {\r
\r
port = &ports[portid];\r
hr = port->prov->Receive(&mad, sizeof mad, &port->overlap);\r
-\r
if (hr == WV_IO_PENDING) {\r
hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms);\r
if (hr == WAIT_TIMEOUT) {\r
+ umad_cancel_recv(port);\r
+ _set_errno(ETIMEDOUT);\r
return -ETIMEDOUT;\r
}\r
}\r
\r
if (FAILED(hr) && hr != ERROR_MORE_DATA) {\r
+ _set_errno(EIO);\r
return -EIO;\r
}\r
\r
- port->pending = TRUE;\r
return 0;\r
}\r
\r
__declspec(dllexport)\r
int umad_unregister(int portid, int agentid)\r
{\r
- ports[portid].pending = FALSE;\r
return ports[portid].prov->Deregister((UINT64) agentid);\r
}\r
\r