ca_attr_p->vend_id = hca_info_p->vendor_id;\r
ca_attr_p->dev_id = (uint16_t)hca_info_p->dev_id;\r
ca_attr_p->revision = (uint16_t)hca_info_p->hw_ver;\r
+ ca_attr_p->fw_ver = hca_info_p->fw_ver;\r
\r
ca_attr_p->ca_guid = *(UNALIGNED64 u_int64_t *)vapi_hca_cap_p->node_guid;\r
ca_attr_p->num_ports = vapi_hca_cap_p->phys_port_num;\r
-; SilverStorm Technologies InfiniBand HCAs.\r
+; OpenIB InfiniBand HCAs.\r
; Copyright 2005 SilverStorm Technologies all Rights Reserved.\r
\r
[Version]\r
Signature="$Windows NT$"\r
Class=InfiniBandHca\r
ClassGUID=%HcaClassGuid%\r
-Provider=%SST%\r
-CatalogFile=infiniserv.cat\r
-DriverVer=09/01/2005,3.0.0036.0\r
+Provider=%OPENIB%\r
+DriverVer=01/12/2006,1.0.0000.213\r
\r
; ================= Destination directory section =====================\r
\r
;uvpd32d.dll=1\r
\r
[Manufacturer]\r
-%SST% = HCA.DeviceSection,ntx86,ntamd64,ntia64\r
+%OPENIB% = HCA.DeviceSection,ntx86,ntamd64,ntia64\r
\r
[HCA.DeviceSection]\r
; empty since we don't support W9x/Me\r
\r
[Strings]\r
HcaClassGuid = "{58517E00-D3CF-40c9-A679-CEE5752F4491}"\r
-SST = "SilverStorm Technologies"\r
-MT23108.DeviceDesc = "SilverStorm HCA 7000 InfiniBand HCA"\r
-MT23108.ServiceDesc = "SilverStorm HCA 7000 InfiniBand HCA Driver"\r
-MT25208.DeviceDesc = "SilverStorm HCA 9000 InfiniBand HCA"\r
-MT25208.ServiceDesc = "SilverStorm HCA 9000 InfiniBand HCA Driver"\r
-THCA.ServiceDesc = "SilverStorm HCA 7000/9000 HCA VPD for IBAL"\r
-Ibal.ServiceDesc = "SilverStorm InfiniBand Access Layer"\r
-DiskId = "SilverStorm InfiniBand HCA installation disk"\r
+OPENIB = "OpenIB Alliance"\r
+MT23108.DeviceDesc = "Mellanox MT23108 InfiniBand HCA"\r
+MT23108.ServiceDesc = "Mellanox MT23108 InfiniBand HCA Driver"\r
+MT25208.DeviceDesc = "Mellanox MT25208 InfiniBand HCA"\r
+MT25208.ServiceDesc = "Mellanox MT25208 InfiniBand HCA Driver"\r
+THCA.ServiceDesc = "Mellanox HCA VPD for IBAL"\r
+Ibal.ServiceDesc = "OpenIB InfiniBand Access Layer"\r
+DiskId = "OpenIB InfiniBand HCA installation disk"\r
SPSVCINST_NULL = 0x0\r
SPSVCINST_ASSOCSERVICE = 0x00000002\r
SERVICE_KERNEL_DRIVER = 1\r
\r
typedef struct _ib_ca\r
{\r
- HH_hca_dev_t *p_hca_ul_info;\r
+ HH_hca_dev_t * __ptr64 p_hca_ul_info;\r
void *p_hca_ul_resources;\r
ib_ca_attr_t *p_hca_attr;\r
HHUL_hca_hndl_t hhul_hca_hndl;\r
if ( ioctl_status == IB_SUCCESS && p_ca_attr &&\r
byte_count && !h_uvp_ca->p_hca_attr )\r
{\r
+ CL_ASSERT( byte_count >= p_ca_attr->size );\r
h_uvp_ca->p_hca_attr = p_umv_buf->p_inout_buf;\r
- cl_memcpy(h_uvp_ca->p_hca_attr, p_ca_attr, byte_count);\r
+ ib_copy_ca_attr( h_uvp_ca->p_hca_attr, p_ca_attr );\r
}\r
else if (p_umv_buf->p_inout_buf) \r
{\r
}\r
\r
FUNC_EXIT;\r
- return IB_SUCCESS;\r
+ return status;\r
}\r
\r
\r
("Before resize_cq_prep *p_size = %d\n", *p_size));\r
status = THHUL_cqm_resize_cq_prep ( p_hobul->hhul_hca_hndl,\r
p_cq_info->hhul_cq_hndl,\r
- *p_size, p_size,\r
+ *p_size, &p_cq_info->cq_size,\r
p_cq_ul_resources);\r
if( status != IB_SUCCESS )\r
{\r
* Device information (public object/context)\r
*\r
*/\r
-\r
+#pragma warning( disable : 4201 )\r
typedef struct HH_hca_dev_st {\r
- char *dev_desc; /* Device description (name, etc.) */\r
- char *user_lib; /* User level library (dyn-link) */\r
+ char * __ptr64 dev_desc; /* Device description (name, etc.) */\r
+ char * __ptr64 user_lib; /* User level library (dyn-link) */\r
u_int32_t vendor_id; /* IEEE's 24 bit Device Vendor ID */\r
u_int32_t dev_id; /* Device ID */\r
u_int32_t hw_ver; /* Hardware version (step/rev) */\r
- struct hh_if_ops* if_ops; /* Interface operations */\r
+ u_int64_t fw_ver;\r
+ struct hh_if_ops* __ptr64 if_ops; /* Interface operations */\r
\r
/* Size (bytes) of user-level ... */\r
+ union\r
+ {\r
MT_size_t hca_ul_resources_sz; /* .. resources context for an HCA */\r
+ void* __ptr64 resv0;\r
+ };\r
+ union\r
+ {\r
MT_size_t pd_ul_resources_sz; /* .. resources context for a PD */\r
+ void* __ptr64 resv1;\r
+ };\r
+ union\r
+ {\r
MT_size_t cq_ul_resources_sz; /* .. resources context for a CQ */\r
+ void* __ptr64 resv2;\r
+ };\r
+ union\r
+ {\r
MT_size_t srq_ul_resources_sz; /* .. resources context for a SRQ */\r
+ void* __ptr64 resv3;\r
+ };\r
+ union\r
+ {\r
MT_size_t qp_ul_resources_sz; /* .. resources context for a QP */\r
+ void* __ptr64 resv4;\r
+ };\r
\r
- void* device; /* Device private data */\r
+ void* __ptr64 device; /* Device private data */\r
HH_hca_status_t status; /* Device Status */\r
} HH_hca_dev_t;\r
-\r
+#pragma warning( default : 4201 )\r
\r
typedef enum {\r
HH_TPT_PAGE,\r
*\r
*/\r
\r
-typedef struct HH_hca_dev_st* HH_hca_hndl_t;\r
+typedef struct HH_hca_dev_st* __ptr64 HH_hca_hndl_t;\r
typedef struct HHUL_sr_wqe_st HHUL_sr_wqe_t;\r
typedef struct HHUL_rr_wqe_st HHUL_rr_wqe_t;\r
\r
typedef struct THH_uar_st *THH_uar_t;\r
\r
\r
+#pragma warning( disable : 4201 )\r
+\r
/* VERSION INFORMATION: used in order to retrieve major version numbers \r
in order to deal with differences in different versions. */\r
typedef struct THH_ver_info_st {\r
HH_hca_hndl_t hh_hca_hndl;\r
THH_ver_info_t version;\r
THH_uar_index_t uar_index;\r
+ union\r
+ {\r
MT_virt_addr_t uar_map;\r
+ void* __ptr64 resv0;\r
+ };\r
/* HCA capabilities to validate or use in THHUL */\r
MT_bool priv_ud_av; /* Privileged UD AV are enforced ? */\r
u_int32_t log2_mpt_size;\r
- char *av_ddr_base;\r
- char *av_host_base;\r
+ char * __ptr64 av_ddr_base;\r
+ char * __ptr64 av_host_base;\r
\r
u_int32_t max_qp_ous_wr; /* Maximum Number of oustanding WR on any WQ. */ \r
u_int32_t max_srq_ous_wr; /* Maximum Number of oustanding WR on any WQ. */ \r
* needed. Therefore, the udavm_buf_size value is the size of the actual udavm\r
* table, not the size of the malloc'ed buffer.\r
*/\r
+ union\r
+ {\r
MT_virt_addr_t udavm_buf; /* IN */\r
+ void* __ptr64 resv0;\r
+ };\r
+ union\r
+ {\r
MT_size_t udavm_buf_sz; /* IN */\r
+ void* __ptr64 resv1;\r
+ };\r
HH_pdm_pd_flags_t pd_flags; /* IN - if non-zero, is a PD for a special QP*/\r
VAPI_lkey_t udavm_buf_memkey; /* OUT - set by THH_uldm */\r
} THH_pd_ul_resources_t;\r
\r
typedef struct\r
{\r
+ union\r
+ {\r
MT_virt_addr_t cqe_buf; /* CQE buffer virtual addr. CQE size aligned */\r
+ void* __ptr64 resv0;\r
+ };\r
+ union\r
+ {\r
MT_size_t cqe_buf_sz; /* Buffer size in bytes (mult of CQE size) */\r
+ void* __ptr64 resv1;\r
+ };\r
THH_uar_index_t uar_index; /* Index of UAR used for this CQ. */\r
u_int32_t new_producer_index; /* New producer index after "resize_cq" (OUT)*/\r
} THH_cq_ul_resources_t;\r
\r
typedef struct \r
{\r
+ union\r
+ {\r
MT_virt_addr_t wqes_buf; /* WQEs buffer virtual address */\r
+ void* __ptr64 resv0;\r
+ };\r
+ union\r
+ {\r
MT_size_t wqes_buf_sz; /* Buffer size in bytes */\r
+ void* __ptr64 resv1;\r
+ };\r
THH_uar_index_t uar_index; /* index of UAR used for this QP */\r
/* ER: Not used anywhere: MT_virt_addr_t uar_map; */ /* Address in user space of UAR */\r
} THH_qp_ul_resources_t;\r
\r
typedef struct \r
{\r
+ union\r
+ {\r
MT_virt_addr_t wqes_buf; /* WQEs buffer virtual address */\r
+ void* __ptr64 resv0;\r
+ };\r
+ union\r
+ {\r
MT_size_t wqes_buf_sz; /* Buffer size in bytes */\r
+ void* __ptr64 resv1;\r
+ };\r
+ union\r
+ {\r
MT_size_t wqe_sz; /* WQE (descriptor) size in bytes */\r
+ void* __ptr64 resv2;\r
+ };\r
THH_uar_index_t uar_index; /* index of UAR used for this QP */\r
} THH_srq_ul_resources_t;\r
\r
+#pragma warning( default : 4201 )\r
#endif /* H_THH_COMMON_H */\r
tdev.dev_id = (u_int32_t)hw_props_p->device_id;\r
MTL_DEBUG1("hw_props_p: device_id = 0x%X, pci_vendor_id=0x%X,hw_ver=0x%X\n",\r
hw_props_p->device_id, hw_props_p->pci_vendor_id, hw_props_p->hw_ver);\r
+ tdev.fw_ver= tdev.fw_ver = hob_p->fw_props.fw_rev_major;\r
+ tdev.fw_ver = (tdev.fw_ver <<16) | hob_p->fw_props.fw_rev_minor;\r
+ tdev.fw_ver = (tdev.fw_ver <<16) | hob_p->fw_props.fw_rev_subminor;;\r
tdev.hw_ver = hob_p->hw_props.hw_ver; \r
tdev.if_ops = if_ops_p;\r
tdev.hca_ul_resources_sz = sizeof(THH_hca_ul_resources_t);\r
/******************************************************************************\r
* Function: THH_hob_alloc_rdd <==> THH_eecm_alloc_rdd\r
*****************************************************************************/\r
-HH_ret_t THH_hob_alloc_rdd(HH_hca_dev_t *hh_dev_p, \r
+HH_ret_t THH_hob_alloc_rdd(HH_hca_hndl_t hh_dev_p, \r
HH_rdd_hndl_t *rdd_p)\r
{\r
#if 0\r
/******************************************************************************\r
* Function: THH_hob_free_rdd <==> THH_eecm_free_rdd\r
*****************************************************************************/\r
-HH_ret_t THH_hob_free_rdd(HH_hca_dev_t *hh_dev_p, HH_rdd_hndl_t rdd)\r
+HH_ret_t THH_hob_free_rdd(HH_hca_hndl_t hh_dev_p, HH_rdd_hndl_t rdd)\r
{\r
#if 0\r
THH_hob_t thh_hob_p;\r
DLL_API HH_ret_t THH_hob_free_ul_res(HH_hca_hndl_t hca_hndl,void *hca_ul_resources_p);\r
DLL_API HH_ret_t THH_hob_alloc_pd(HH_hca_hndl_t hca_hndl, MOSAL_protection_ctx_t prot_ctx, void * pd_ul_resources_p,HH_pd_hndl_t *pd_num_p);\r
DLL_API HH_ret_t THH_hob_free_pd(HH_hca_hndl_t hca_hndl, HH_pd_hndl_t pd_num);\r
-DLL_API HH_ret_t THH_hob_alloc_rdd(HH_hca_dev_t *hh_dev_p, HH_rdd_hndl_t *rdd_p);\r
-DLL_API HH_ret_t THH_hob_free_rdd(HH_hca_dev_t *hh_dev_p, HH_rdd_hndl_t rdd);\r
+DLL_API HH_ret_t THH_hob_alloc_rdd(HH_hca_hndl_t hh_dev_p, HH_rdd_hndl_t *rdd_p);\r
+DLL_API HH_ret_t THH_hob_free_rdd(HH_hca_hndl_t hh_dev_p, HH_rdd_hndl_t rdd);\r
DLL_API HH_ret_t THH_hob_create_ud_av(HH_hca_hndl_t hca_hndl,HH_pd_hndl_t pd,VAPI_ud_av_t *av_p, HH_ud_av_hndl_t *ah_p);\r
DLL_API HH_ret_t THH_hob_modify_ud_av(HH_hca_hndl_t hca_hndl, HH_ud_av_hndl_t ah,VAPI_ud_av_t *av_p);\r
DLL_API HH_ret_t THH_hob_query_ud_av(HH_hca_hndl_t hca_hndl, HH_ud_av_hndl_t ah,VAPI_ud_av_t *av_p);\r
/* for TAVOR_SD */\r
{ L"5A5A", "mt%d_pci%d", "mt%d_pci%d", MD_DEV_ID_TAVOR_SD, MD_DEV_IX_TAVOR_SD, TRUE, 0x00100000, 0x01000000, 0x00000000, 167000000, 4, 0 },\r
/* for TAVOR_SD */\r
- { L"6278", "InfiniHost%d", "InfiniHosA%d", MD_DEV_ID_ARBEL_TM, MD_DEV_IX_ARBEL_TM, TRUE, 0x00100000, 0x01000000, 0x00000000, 167000000, 4, 0 },\r
+ { L"6278", "InfiniHostEx%d", "InfiniHosEx%d", MD_DEV_ID_ARBEL_TM, MD_DEV_IX_ARBEL_TM, TRUE, 0x00100000, 0x01000000, 0x00000000, 167000000, 4, 0 },\r
};\r
\r
#else\r
\r
} /* fix HCA command register from SHRIMP */\r
\r
- if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR ) \r
+ if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR \r
+ || pi_pMdDevContext->m_eDevType ==MD_DEV_IX_ARBEL_TM) \r
{ /* fix command register for TAVOR */\r
\r
l_pInterface = &pi_pMdDevContext->m_Interface;\r
return l_Status;\r
} \r
else\r
- if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR) {\r
+ if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR || \r
+ pi_pMdDevContext->m_eDevType == MD_DEV_IX_ARBEL_TM) {\r
\r
/* protect */\r
KSEM_ACQ(&pi_pMdDevContext->m_Sem);\r
\r
}\r
else\r
- if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR ) {\r
+ if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR ||\r
+ pi_pMdDevContext->m_eDevType == MD_DEV_IX_ARBEL_TM) {\r
\r
/* \r
* HCA device\r
}\r
}\r
else\r
- if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR ) {\r
+ if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR ||\r
+ pi_pMdDevContext->m_eDevType == MD_DEV_IX_ARBEL_TM) {\r
\r
/* \r
* Bridge device\r
l_Status );\r
}\r
else \r
- if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR) { /* we are Tavor device */\r
+ if (pi_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR ||\r
+ pi_pMdDevContext->m_eDevType == MD_DEV_IX_ARBEL_TM) { /* we are Tavor device */\r
l_Status = PciDevReset(pi_pMdDevContext, l_ResetOffset, l_ResetValue );\r
}\r
else\r
\r
case MD_DEV_IX_TAVOR_SD:\r
case MD_DEV_IX_TAVOR:\r
+ case MD_DEV_IX_ARBEL_TM:\r
l_Status = PciIoctl( l_pMdDevContext, l_pPcs, l_nIoControlCode, l_pInBuffer, \r
l_nInBufLength, l_pOutBuffer, l_nOutBufLength, (PULONG)&pi_pIrp->IoStatus.Information );\r
break;\r
* add device to TAVOR\r
*/ \r
\r
- if (l_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR && g_pDrvContext->m_fSupportTavor)\r
+ if ((l_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR || \r
+ l_pMdDevContext->m_eDevType == MD_DEV_IX_ARBEL_TM)\r
+ && g_pDrvContext->m_fSupportTavor)\r
{ /* add HCA to Tavor functional DLLs */\r
\r
unsigned char l_RevId = 0;\r
// stop the card by sending some commands to it or suspend all new requests and wait for the end of in-progress ones\r
//\r
\r
- if (l_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR && g_pDrvContext->m_fSupportTavor)\r
+ if ((l_pMdDevContext->m_eDevType == MD_DEV_IX_TAVOR ||\r
+ l_pMdDevContext->m_eDevType == MD_DEV_IX_ARBEL_TM)&& g_pDrvContext->m_fSupportTavor)\r
{ /* remove HCA from Tavor functional DLLs */\r
\r
HH_ret_t l_HhRet;\r
break;\r
\r
case MD_DEV_IX_TAVOR:\r
+ case MD_DEV_IX_ARBEL_TM:\r
// MDCTL\r
- PciRelease( l_pMdDevContext, l_pPcs );\r
+ PciRelease( l_pMdDevContext, l_pPcs );\r
break;\r
\r
case MD_DEV_IX_TAVOR_BD:\r
break;\r
\r
case MD_DEV_IX_TAVOR:\r
+ case MD_DEV_IX_ARBEL_TM:\r
GetRegistryDword( L"DdrMapOffset", MD_DFLT_CONF_DATA, &l_pMdDevContext->m_ulDdrMapOffset );\r
GetRegistryDword( L"DdrMapSize", MD_DFLT_CONF_DATA, &l_pMdDevContext->m_ulDdrMapSize );\r
GetRegistryDword( L"ResetCard", MD_DFLT_CONF_DATA, &l_pMdDevContext->m_PerformReset );\r
\r
/* create Control Device names */\r
/* !!! from now on work with ARBEL_TM as with TAVOR */\r
- l_pDevInfo = (pi_DevIx == (int)MD_DEV_IX_ARBEL_TM) ? &g_DevParams[MD_DEV_IX_TAVOR] : &g_DevParams[pi_DevIx];\r
- if (l_pDevInfo->m_DevId == MD_DEV_ID_TAVOR)\r
+ //l_pDevInfo = (pi_DevIx == (int)MD_DEV_IX_ARBEL_TM) ? &g_DevParams[MD_DEV_IX_TAVOR] : &g_DevParams[pi_DevIx];\r
+ l_pDevInfo = &g_DevParams[pi_DevIx];\r
+ if (l_pDevInfo->m_DevId == MD_DEV_ID_TAVOR || l_pDevInfo->m_DevId == MD_DEV_ID_ARBEL_TM)\r
sprintf( l_DevName, l_pDevInfo->m_Format, g_pDrvContext->m_uCardNo );\r
else\r
sprintf( l_DevName, l_pDevInfo->m_Format, l_pDevInfo->m_DevId, g_pDrvContext->m_uCardNo );\r
*
* SYNOPSIS
*/
-AL_INLINE uint8_t AL_API
+OSM_INLINE uint8_t AL_API
ib_port_info_get_client_rereg(
IN ib_port_info_t const* p_pi )
{
uint32_t vend_id;
uint16_t dev_id;
uint16_t revision;
+ uint64_t fw_ver;
/*
* Total size of the ca attributes in bytes
* revision
* Revision ID of this adapter
*
+* Fw_ver
+* Device Firmware version.
+*
* size
* Total size in bytes for the HCA attributes. This size includes total
* size required for all the variable members of the structure. If a
uint32_t vend_id;
uint16_t dev_id;
uint16_t revision;
+ uint64_t fw_ver;
/*
* Total size of the ca attributes in bytes
* revision
* Revision ID of this adapter
*
+* Fw_ver
+* Device Firmware version.
+*
* size
* Total size in bytes for the HCA attributes. This size includes total
* size required for all the variable members of the structure. If a
#ifndef PRIx64
#if __WORDSIZE == 64
-#define __PRI64_PREFIX "l"
-#else
-#define __PRI64_PREFIX "L"
-#endif
+#define PRId64 "I64d"
+#define PRIx64 "I64x"
+#define PRIo64 "I64o"
+#define PRIu64 "I64u"
+#else // __WORDSIZE
+#define PRId64 "I64d"
+#define PRIx64 "I64x"
+#define PRIo64 "I64o"
+#define PRIu64 "I64u"
+
+#endif //__WORDSIZE
+#endif // PRIx64
+
-#define PRId64 __PRI64_PREFIX"d"
-#define PRIo64 __PRI64_PREFIX"o"
-#define PRIu64 __PRI64_PREFIX"u"
-#define PRIx64 __PRI64_PREFIX"x"
-#endif
#define LOG_ENTRY_SIZE_MAX 4096
#define BUF_SIZE LOG_ENTRY_SIZE_MAX
IN const osm_req_t* const p_req,
IN const osm_dr_path_t* const p_path,
IN const uint8_t* const p_payload,
+ IN const size_t payload_size,
IN const uint16_t attr_id,
IN const uint32_t attr_mod,
IN const cl_disp_msgid_t err_msg,
* p_payload
* [in] Pointer to the SMP payload to send.
*
+* payload_size
+* [in] The size of the payload to be copied to the SMP data field.
+*
* attr_id
* [in] Attribute ID to request.
*
"\t\t\t\tp_key_violations........0x%X\n"
"\t\t\t\tq_key_violations........0x%X\n"
"\t\t\t\tguid_cap................0x%X\n"
+ "\t\t\t\tclient_reregister.......0x%X\n"
"\t\t\t\tsubnet_timeout..........0x%X\n"
"\t\t\t\tresp_time_value.........0x%X\n"
"\t\t\t\terror_threshold.........0x%X\n"
cl_ntoh16( p_pi->p_key_violations ),
cl_ntoh16( p_pi->q_key_violations ),
p_pi->guid_cap,
+ ib_port_info_get_client_rereg( p_pi ),
ib_port_info_get_timeout(p_pi),
p_pi->resp_time_value,
p_pi->error_threshold
if( osm_log_is_active( p_log, log_level ) )
{
sprintf(buf_service_key,
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ "0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
p_sr->service_key[0],
p_sr->service_key[1],
p_sr->service_key[2],
osm_log( p_log, log_level,
"Generic Notice dump:\n"
- "\t\t\t\ttype....................0x%02X\n"
- "\t\t\t\tprod_type...............%u\n"
- "\t\t\t\ttrap_num................%u\n%s"
+ "\t\t\t\ttype.....................0x%02X\n"
+ "\t\t\t\tprod_type................%u\n"
+ "\t\t\t\ttrap_num.................%u\n%s"
"",
ib_notice_get_type(p_ntci),
cl_ntoh32(ib_notice_get_prod_type(p_ntci)),
{
osm_log( p_log, log_level,
"Vendor Notice dump:\n"
- "\t\t\t\ttype....................0x%04x\n"
- "\t\t\t\tvendor..................%u\n"
- "\t\t\t\tdevice_id...............%u\n"
+ "\t\t\t\ttype.....................0x%04x\n"
+ "\t\t\t\tvendor...................%u\n"
+ "\t\t\t\tdevice_id................%u\n"
"",
cl_ntoh16(ib_notice_get_type(p_ntci)),
cl_ntoh32(ib_notice_get_vend_id(p_ntci)),
#define OSM_VENDOR_ID_FUJITSU 0x00E000
#define OSM_VENDOR_ID_FUJITSU2 0x000B5D
#define OSM_VENDOR_ID_VOLTAIRE 0x0008F1
+#define OSM_VENDOR_ID_YOTTAYOTTA 0x000453
+#define OSM_VENDOR_ID_PATHSCALE 0x001175
+#define OSM_VENDOR_ID_IBM 0x000255
/**********************************************************************
**********************************************************************/
IN uint64_t const guid_ho )
{
static const char* intel_str = "Intel ";
- static const char* mellanox_str = "Mellanox ";
+ static const char* mellanox_str = "Mellanox ";
static const char* redswitch_str = "Redswitch ";
- static const char* silverstorm_str = "SilverStorm ";
+ static const char* silverstorm_str = "SilverStorm ";
static const char* topspin_str = "Topspin ";
static const char* fujitsu_str = "Fujitsu ";
static const char* voltaire_str = "Voltaire ";
+ static const char* yotta_str = "YottaYotta ";
+ static const char* pathscale_str = "PathScale ";
+ static const char* ibm_str = "IBM ";
static const char* unknown_str = "Unknown ";
switch( (uint32_t)(guid_ho >> (5 * 8)) )
return( fujitsu_str );
case OSM_VENDOR_ID_VOLTAIRE:
return( voltaire_str );
+ case OSM_VENDOR_ID_YOTTAYOTTA:
+ return( yotta_str );
+ case OSM_VENDOR_ID_PATHSCALE:
+ return( pathscale_str );
+ case OSM_VENDOR_ID_IBM:
+ return( ibm_str );
default:
return( unknown_str );
}
if (strcmp (tok, longopts[i].name) == 0)
{
/* We have a match */
+ if (longindex != NULL )
*longindex = i;
if (longopts[i].flag != NULL) {
-!if $(FREEBUILD)
TARGETNAME=opensm
-!else
-TARGETNAME=opensmd
-!endif
-
!if !defined(WINIBHOME)
WINIBHOME=..\..\..\..
boolean_t cache_options = FALSE;
char *ignore_guids_file_name = NULL;
uint32_t val;
- const char * const short_option = "i:f:ed:g:l:s:t:vVhorc";
+ const char * const short_option = "i:f:ed:g:l:s:t:a:uvVhorc";
/*
In the array below, the 2nd parameter specified the number
* 1. During initialization:
* 1.1 initialize the guid2lid database domain.
* 1.2 if reassign_lid is not set:
- * 1.2.1 read the persistant data for the domain.
+ * 1.2.1 read the persistent data for the domain.
* 1.2.2 validate no duplicate use of lids and lids are 2^(lmc-1)
*
* 2. During SM port lid assignment:
/* check that if the lids define a range - that range is valid
for the current LMC mask */
osm_log( p_mgr->p_log, OSM_LOG_ERROR,
- "__osm_lid_mgr_validate_db: ERR 0313: "
+ "__osm_lid_mgr_validate_db: ERR 0313: "
"LID range [0x%x:0x%x] for guid:0x%016" PRIx64
" is not aligned acording to mask:0x%04x.\n",
min_lid, max_lid, p_item->guid, lmc_mask
( cl_ptr_vector_get( &p_mgr->used_lids, lid ) ) )
{
osm_log( p_mgr->p_log, OSM_LOG_ERROR,
- "__osm_lid_mgr_validate_db: ERR 0314: "
+ "__osm_lid_mgr_validate_db: ERR 0314: "
"0x%04x for guid:0x%016" PRIx64
" was previously used.\n",
lid, p_item->guid
{
if (osm_db_guid2lid_delete( p_mgr->p_g2l, p_item->guid ))
osm_log( p_mgr->p_log, OSM_LOG_ERROR,
- "__osm_lid_mgr_validate_db: ERR 0315: "
+ "__osm_lid_mgr_validate_db: ERR 0315: "
"failed to delete entry for guid:0x%016" PRIx64
- " .\n",
+ ".\n",
p_item->guid
);
}
if (! p_mgr->p_g2l)
{
osm_log( p_mgr->p_log, OSM_LOG_ERROR,
- "osm_lid_mgr_init: ERR 0316: "
- "Error initializing Guid-to-Lid persistant database.\n");
+ "osm_lid_mgr_init: ERR 0316: "
+ "Error initializing Guid-to-Lid persistent database.\n");
status = IB_ERROR;
goto Exit;
}
if (osm_db_restore(p_mgr->p_g2l))
{
osm_log( p_mgr->p_log, OSM_LOG_ERROR,
- "osm_lid_mgr_init: ERR 0317: "
- "Error restoring Guid-to-Lid persistant database.\n");
+ "osm_lid_mgr_init: ERR 0317: "
+ "Error restoring Guid-to-Lid persistent database.\n");
status = IB_ERROR;
goto Exit;
}
__osm_lid_mgr_validate_db(p_mgr);
}
-Exit:
+ Exit:
OSM_LOG_EXIT( p_mgr->p_log );
return( status );
}
uint16_t max_defined_lid;
uint16_t max_persistent_lid;
uint16_t max_discovered_lid;
- uint16_t lid, l;
+ uint16_t lid;
uint16_t disc_min_lid;
uint16_t disc_max_lid;
uint16_t db_min_lid;
osm_port_t *p_port;
cl_qmap_t *p_port_guid_tbl;
uint8_t lmc_num_lids = (uint8_t)(1 << p_mgr->p_subn->opt.lmc);
-
+ uint16_t lmc_mask;
+ uint16_t req_lid, num_lids;
+
OSM_LOG_ENTER( p_mgr->p_log, __osm_lid_mgr_init_sweep );
- /* if we came out of standby we need to discard any previous guid 2 lid
- info we might had */
+ if (p_mgr->p_subn->opt.lmc)
+ lmc_mask = ~((1 << p_mgr->p_subn->opt.lmc) - 1);
+ else
+ lmc_mask = 0xffff;
+
+ /* if we came out of standby we need to discard any previous guid2lid
+ info we might have */
if ( p_mgr->p_subn->coming_out_of_standby == TRUE )
{
osm_db_clear( p_mgr->p_g2l );
for (lid = 0; lid < cl_ptr_vector_get_size(&p_mgr->used_lids); lid++)
- cl_ptr_vector_set(&p_mgr->used_lids, lid, NULL);
+ cl_ptr_vector_set(p_persistent_vec, lid, NULL);
}
/* we need to cleanup the empty ranges list */
for (lid = 0; lid < cl_ptr_vector_get_size(p_discovered_vec); lid++)
cl_ptr_vector_set(p_discovered_vec, lid, NULL);
- /* we if are on the first sweep and in re-assign lids mode
- we should ignore all the available info and simply define one
- hufe empty range */
+ /* we if are in the first sweep and in re-assign lids mode
+ we should ignore all the available info and simply define one
+ huge empty range */
if ((p_mgr->p_subn->first_time_master_sweep == TRUE) &&
(p_mgr->p_subn->opt.reassign_lids == TRUE ))
{
goto AfterScanningLids;
}
- /* go over all discvered ports and mark their entries */
+ /* go over all discovered ports and mark their entries */
p_port_guid_tbl = &p_mgr->p_subn->port_guid_tbl;
for( p_port = (osm_port_t*)cl_qmap_head( p_port_guid_tbl );
osm_port_get_lid_range_ho(p_port, &disc_min_lid, &disc_max_lid);
for (lid = disc_min_lid; lid <= disc_max_lid; lid++)
cl_ptr_vector_set(p_discovered_vec, lid, p_port );
+ /* make sure the guid2lid entry is valid. If not - clean it. */
+ if (!osm_db_guid2lid_get( p_mgr->p_g2l,
+ cl_ntoh64(osm_port_get_guid(p_port)),
+ &db_min_lid, &db_max_lid))
+ {
+ if ( osm_node_get_type( osm_port_get_parent_node( p_port ) ) !=
+ IB_NODE_TYPE_SWITCH)
+ num_lids = lmc_num_lids;
+ else
+ num_lids = 1;
+
+ if ((num_lids != 1) &&
+ (((db_min_lid & lmc_mask) != db_min_lid) ||
+ (db_max_lid - db_min_lid + 1 < num_lids)) )
+ {
+ /* Not aligned, or not wide enough - remove the entry */
+ osm_log( p_mgr->p_log, OSM_LOG_DEBUG,
+ "__osm_lid_mgr_init_sweep: "
+ "Cleaning persistent entry for guid:0x%016" PRIx64
+ " illegal range:[0x%x:0x%x]\n",
+ cl_ntoh64(osm_port_get_guid(p_port)), db_min_lid,
+ db_max_lid );
+ osm_db_guid2lid_delete( p_mgr->p_g2l,
+ cl_ntoh64(osm_port_get_guid(p_port)));
+ for ( lid = db_min_lid ; lid <= db_max_lid ; lid++ )
+ cl_ptr_vector_set(p_persistent_vec, lid, NULL);
+ }
+ }
}
/*
Our task is to find free lid ranges.
A lid can be used if
1. a persistent assignment exists
- 2. the lid is used by a discovered port that does not have a persistent
+ 2. the lid is used by a discovered port that does not have a persistent
assignment.
scan through all lid values of both the persistent table and
{
is_free = TRUE;
/* first check to see if the lid is used by a persistent assignment */
- if ((lid < max_persistent_lid) && cl_ptr_vector_get(p_persistent_vec, lid))
+ if ((lid <= max_persistent_lid) && cl_ptr_vector_get(p_persistent_vec, lid))
{
osm_log( p_mgr->p_log, OSM_LOG_DEBUG,
"__osm_lid_mgr_init_sweep: "
lid);
is_free = FALSE;
}
-
- /* check the discovered port if there is one */
- if ((lid < max_discovered_lid) &&
- (p_port = (osm_port_t *)cl_ptr_vector_get(p_discovered_vec, lid)))
+ else
{
- /* get the lid range of that port - but we know how many lids we
- are about to assign to it */
- osm_port_get_lid_range_ho(p_port, &disc_min_lid, &disc_max_lid);
- if ( osm_node_get_type( osm_port_get_parent_node( p_port ) ) !=
- IB_NODE_TYPE_SWITCH)
- disc_max_lid = disc_min_lid + lmc_num_lids - 1;
-
- /* qualify the guid of the port is not persistently mapped to
- another range */
- if (!osm_db_guid2lid_get( p_mgr->p_g2l,
- cl_ntoh64(osm_port_get_guid(p_port)),
- &db_min_lid, &db_max_lid))
+ /* check this is a discovered port */
+ if (lid <= max_discovered_lid && (p_port = (osm_port_t *)cl_ptr_vector_get(p_discovered_vec, lid)))
{
- /* ok there is an asignment - is it the same ? */
- if ((disc_min_lid == db_min_lid) && (disc_max_lid == db_max_lid))
+ /* we have a port. Now lets see if we can preserve its lid range. */
+ /* For that - we need to make sure:
+ 1. The port has a (legal) persistency entry. Then the local lid
+ is free (we will use the persistency value).
+ 2. Can the port keep its local assignment?
+ a. Make sure the lid a aligned.
+ b. Make sure all needed lids (for the lmc) are free according
+ to persistency table.
+ */
+ /* qualify the guid of the port is not persistently mapped to
+ another range */
+ if (!osm_db_guid2lid_get( p_mgr->p_g2l,
+ cl_ntoh64(osm_port_get_guid(p_port)),
+ &db_min_lid, &db_max_lid))
{
osm_log( p_mgr->p_log, OSM_LOG_DEBUG,
"__osm_lid_mgr_init_sweep: "
- "[0x%04x,0x%04x] is not free as it was discovered "
- " and mapped by the persistent db.\n",
- disc_min_lid, disc_max_lid);
- is_free = FALSE;
+ "0x%04x is free as it was discovered "
+ "but mapped by the persistent db to [0x%04x:0x%04x].\n",
+ lid, db_min_lid, db_max_lid);
}
else
{
- osm_log( p_mgr->p_log, OSM_LOG_DEBUG,
- "__osm_lid_mgr_init_sweep: "
- "[0x%04x,0x%04x] is free as it was discovered"
- " but mapped to range: [0x%x:0x%x] by the persistent db.\n",
- disc_min_lid, disc_max_lid, db_min_lid, db_max_lid);
- for (l = disc_min_lid; l <= disc_max_lid; l++)
- cl_ptr_vector_set(p_discovered_vec, l, NULL);
+ /* can the port keep its assignment ? */
+ /* get the lid range of that port, and the required number
+ of lids we are about to assign to it */
+ osm_port_get_lid_range_ho(p_port, &disc_min_lid, &disc_max_lid);
+ if ( osm_node_get_type( osm_port_get_parent_node( p_port ) ) !=
+ IB_NODE_TYPE_SWITCH)
+ {
+ disc_max_lid = disc_min_lid + lmc_num_lids - 1;
+ num_lids = lmc_num_lids;
+ }
+ else
+ {
+ num_lids = 1;
+ }
+ /* Make sure the lid is aligned */
+ if ((num_lids != 1) && ((disc_min_lid & lmc_mask) != disc_min_lid))
+ {
+ /* The lid cannot be used */
+ osm_log( p_mgr->p_log, OSM_LOG_DEBUG,
+ "__osm_lid_mgr_init_sweep: "
+ "0x%04x is free as it was discovered "
+ "but not aligned. \n",
+ lid );
+ }
+ else
+ {
+ /* check that all needed lids are not persistently mapped */
+ is_free = FALSE;
+ for ( req_lid = disc_min_lid + 1 ; req_lid <= disc_max_lid ; req_lid++ )
+ {
+ if ((req_lid <= max_persistent_lid) && cl_ptr_vector_get(p_persistent_vec, req_lid))
+ {
+ osm_log( p_mgr->p_log, OSM_LOG_DEBUG,
+ "__osm_lid_mgr_init_sweep: "
+ "0x%04x is free as it was discovered "
+ "but mapped. \n",
+ lid);
+ is_free = TRUE;
+ break;
+ }
+ }
+ if (is_free == FALSE)
+ {
+ /* This port will use its local lid, and consume the entire required lid range.
+ Thus we can skip that range. */
+ /* If the disc_max_lid is greater then lid - we can skip right to it,
+ since we've done all neccessary checks on the lids in between. */
+ if (disc_max_lid > lid)
+ lid = disc_max_lid;
+ }
+ }
}
}
- else
- {
- osm_log( p_mgr->p_log, OSM_LOG_DEBUG,
- "__osm_lid_mgr_init_sweep: "
- "0x%04x is not free as it was discovered"
- " and there is no persistent db entry for it.\n",
- lid);
- is_free = FALSE;
- }
-
- /* if there is more then one lid on that port - and the discovered port
- is going to retain its lids advance to the max lid */
- if (is_free == FALSE)
- {
- lid = disc_max_lid;
- }
}
if (is_free)
{
p_range =
(osm_lid_mgr_range_t *)cl_malloc(sizeof(osm_lid_mgr_range_t));
- p_range->min_lid = 1;
+ /*
+ The p_range can be NULL in one of 2 cases:
+ 1. If max_defined_lid == 0. In this case, we want the entire range.
+ 2. If all lids discovered in the loop where mapped. In this case
+ no free range exists, and we want to define it after the last
+ mapped lid.
+ */
+ p_range->min_lid = lid;
}
p_range->max_lid = p_mgr->p_subn->max_unicast_lid_ho - 1;
cl_qlist_insert_tail( &p_mgr->free_ranges, &p_range->item );
/**********************************************************************
**********************************************************************/
void
- __osm_lid_mgr_cleanup_discovered_port_lid_range(
- IN osm_lid_mgr_t* p_mgr,
- IN osm_port_t *p_port )
+__osm_lid_mgr_cleanup_discovered_port_lid_range(
+ IN osm_lid_mgr_t* p_mgr,
+ IN osm_port_t *p_port )
{
cl_ptr_vector_t *p_discovered_vec = &p_mgr->p_subn->port_lid_tbl;
uint16_t lid, min_lid, max_lid;
(port_num != 0) )
{
/*
- Switches ports that are not 0 - should not be set with the
+ Switch ports that are not numbered 0 - should not be set with the
following attributes set later (during NO_CHANGE state in link mgr).
*/
if( osm_log_is_active( p_mgr->p_log, OSM_LOG_DEBUG ) )
if ( ( p_mgr->p_subn->first_time_master_sweep == TRUE ) &&
( (p_old_pi->capability_mask & IB_PORT_CAP_HAS_CLIENT_REREG) != 0 ) )
ib_port_info_set_client_rereg( p_pi, 1 );
+ else
+ ib_port_info_set_client_rereg( p_pi, 0 );
/* We need to send the PortInfoSet request with the new sm_lid
in the following cases:
status = osm_req_set( p_mgr->p_req,
osm_physp_get_dr_path_ptr( p_physp ),
payload,
+ sizeof(payload),
IB_MAD_ATTR_PORT_INFO,
cl_hton32(osm_physp_get_port_num( p_physp )),
CL_DISP_MSGID_NONE,
CL_PLOCK_EXCL_ACQUIRE( p_mgr->p_lock );
/* initialize the port_lid_tbl and empty ranges list following the
- persistant db */
+ persistent db */
__osm_lid_mgr_init_sweep( p_mgr );
if (p_mgr->p_subn->opt.pfn_ui_pre_lid_assign)
/* the proc returns the fact it sent a set port info */
if (__osm_lid_mgr_set_physp_pi( p_mgr, p_physp, cl_hton16( min_lid_ho )))
p_mgr->send_set_reqs = TRUE;
-
}
} /* all ports */
- /* store the guid to lid table in persistant db */
+ /* store the guid to lid table in persistent db */
osm_db_store( p_mgr->p_g2l );
if ( p_mgr->send_set_reqs == FALSE )
status = osm_req_set( p_mgr->p_req,
osm_physp_get_dr_path_ptr( p_physp ),
payload,
+ sizeof(payload),
IB_MAD_ATTR_PORT_INFO,
cl_hton32(port_num),
CL_DISP_MSGID_NONE,
status = osm_req_set( p_mgr->p_req,
p_path,
(void*)block,
+ sizeof(block),
IB_MAD_ATTR_MCAST_FWD_TBL,
cl_hton32( block_id_ho ),
CL_DISP_MSGID_NONE,
{
osm_log( p_rcv->p_log, OSM_LOG_VERBOSE,
"__osm_pi_rcv_process_endport: "
- "Setting endport minimal rate to:%u defiend by port:0x%"
+ "Setting endport minimal rate to:%u defined by port:0x%"
PRIx64 ".\n",
rate,
cl_ntoh64( port_guid ) );
/*
Check the state of the physical port.
If there appears to be something on the other end of the wire,
- then ask for NodeInfo. Ignore the switch managment port.
+ then ask for NodeInfo. Ignore the switch management port.
*/
port_num = osm_physp_get_port_num( p_physp );
/* if in_sweep_hop_0 is TRUE, then this means the SM in on the switch,
osm_dr_path_t path;
uint8_t port_num;
uint16_t block_num, max_blocks;
+ uint32_t attr_mod_ho;
osm_switch_t* p_switch;
OSM_LOG_ENTER( p_log, osm_physp_has_pkey );
else
{
/* This is a switch, and not a management port. The maximum blocks is defined
- on the switch info partition enforcement cap. */
+ in the switch info partition enforcement cap. */
p_switch = osm_get_switch_by_guid(p_subn, p_node->node_info.node_guid);
if (! p_switch)
cl_ntoh64(p_node->node_info.node_guid) );
goto Exit;
}
+
+ /* bail out if this is a switch with no partition enforcement capability */
+ if (cl_ntoh16(p_switch->switch_info.enforce_cap) == 0)
+ goto Exit;
+
max_blocks = (cl_ntoh16(p_switch->switch_info.enforce_cap)+IB_NUM_PKEY_ELEMENTS_IN_BLOCK -1)
/ IB_NUM_PKEY_ELEMENTS_IN_BLOCK ;
}
for (block_num = 0 ; block_num < max_blocks ; block_num++)
{
+ if (osm_node_get_type( p_node ) != IB_NODE_TYPE_SWITCH)
+ attr_mod_ho = block_num;
+ else
+ attr_mod_ho = block_num | (port_num << 16);
status = osm_req_get( p_req,
&path,
IB_MAD_ATTR_P_KEY_TABLE,
- cl_hton32(block_num | (port_num << 16) ),
+ cl_hton32(attr_mod_ho),
CL_DISP_MSGID_NONE,
&context );
IN const osm_req_t* const p_req,
IN const osm_dr_path_t* const p_path,
IN const uint8_t* const p_payload,
+ IN const size_t payload_size,
IN const uint16_t attr_id,
IN const uint32_t attr_mod,
IN const cl_disp_msgid_t err_msg,
p_madw->context = *p_context;
cl_memcpy( osm_madw_get_smp_ptr( p_madw )->data,
- p_payload, IB_SMP_DATA_SIZE );
+ p_payload, payload_size );
osm_vl15_post( p_req->p_vl15, p_madw );
"__osm_sm_mad_ctrl_retire_trans_mad: ERR 3120: "
"Trying to dec qp0_mads_outstanding=0. "
"Problem with transaction mgr!\n");
+ outstanding = 0;
}
else
{
- cl_atomic_dec( &p_ctrl->p_stats->qp0_mads_outstanding );
+ outstanding = cl_atomic_dec( &p_ctrl->p_stats->qp0_mads_outstanding );
}
if( osm_log_is_active( p_ctrl->p_log, OSM_LOG_DEBUG ) )
p_ctrl->p_stats->qp0_mads_outstanding );
}
- /*
- Acquire the lock non-exclusively.
- Other modules that send MADs grab this lock exclusively.
- These modules that are in the process of sending MADs
- will hold the lock until they finish posting all the MADs
- they plan to send. While the other module is sending MADs
- the outstanding count may temporarily go to zero.
- Thus, by grabbing the lock ourselves, we get an accurate
- view of whether or not the number of outstanding MADs is
- really zero.
- */
- CL_PLOCK_ACQUIRE( p_ctrl->p_lock );
- outstanding = p_ctrl->p_stats->qp0_mads_outstanding;
- CL_PLOCK_RELEASE( p_ctrl->p_lock );
-
if( outstanding == 0 )
{
/*
status = osm_req_set( p_mgr->p_req,
osm_physp_get_dr_path_ptr
( osm_port_get_default_phys_ptr( p_port ) ), payload,
+ sizeof(payload),
IB_MAD_ATTR_SM_INFO, IB_SMINFO_ATTR_MOD_HANDOVER,
CL_DISP_MSGID_NONE, &context );
status = osm_req_set( p_rcv->p_req,
osm_node_get_any_dr_path_ptr( p_node ),
payload,
+ sizeof(payload),
IB_MAD_ATTR_SWITCH_INFO,
0,
CL_DISP_MSGID_NONE,
status = osm_req_set( p_mgr->p_req,
p_path,
(uint8_t*)&si,
+ sizeof(si),
IB_MAD_ATTR_SWITCH_INFO,
0,
CL_DISP_MSGID_NONE,
status = osm_req_set( p_mgr->p_req,
p_path,
block,
+ sizeof(block),
IB_MAD_ATTR_LIN_FWD_TBL,
cl_hton32( block_id_ho ),
CL_DISP_MSGID_NONE,
the cl_disp_post with OSM_SIGNAL_NO_PENDING_TRANSACTION (in order
to wake up the state mgr).
*/
- cl_atomic_dec( &p_vl->p_stats->qp0_mads_outstanding );
+ outstanding = cl_atomic_dec( &p_vl->p_stats->qp0_mads_outstanding );
osm_log( p_vl->p_log, OSM_LOG_DEBUG,
"__osm_vl15_poller: "
"%u QP0 MADs outstanding.\n",
p_vl->p_stats->qp0_mads_outstanding );
- /*
- Acquire the lock non-exclusively.
- Other modules that send MADs grab this lock exclusively.
- These modules that are in the process of sending MADs
- will hold the lock until they finish posting all the MADs
- they plan to send. While the other module is sending MADs
- the outstanding count may temporarily go to zero.
- Thus, by grabbing the lock ourselves, we get an accurate
- view of whether or not the number of outstanding MADs is
- really zero.
- */
- CL_PLOCK_ACQUIRE( p_vl->p_lock );
- outstanding = p_vl->p_stats->qp0_mads_outstanding;
- CL_PLOCK_RELEASE( p_vl->p_lock );
-
if( outstanding == 0 )
{
/*
-; SilverStorm Technologies InfiniBand SRP Miniport.\r
+; OpenIB InfiniBand SRP Miniport.\r
; Copyright 2005 SilverStorm Technologies all Rights Reserved.\r
\r
[Version]\r
Signature="$Windows NT$"\r
Class=SCSIAdapter\r
ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}\r
-Provider=%SST%\r
-CatalogFile=ibsrp.cat\r
-DriverVer=09/01/2005,3.0.0036.0\r
+Provider=%OPENIB%\r
+DriverVer=01/12/2006,1.0.0000.213\r
\r
\r
; ================= Device Install section =====================\r
ibsrp.sys=1\r
\r
[Manufacturer]\r
-%SST% = SRP.DeviceSection,ntx86...0x1,ntx86,ntamd64,ntia64\r
+%OPENIB% = SRP.DeviceSection,ntx86...0x1,ntx86,ntamd64,ntia64\r
\r
[SRP.DeviceSection]\r
; empty since we don't support W9x/Me\r
HKR,,TypesSupported,0x00010001,7\r
\r
[Strings]\r
-SST = "SilverStorm Technologies"\r
+OPENIB = "OpenIB Alliance"\r
SRP.DeviceDesc = "InfiniBand SRP Miniport"\r
-SRP.ServiceDesc = "SilverStorm InfiniBand SRP Miniport"\r
-DiskId = "SilverStorm InfiniBand SRP installation disk"\r
+SRP.ServiceDesc = "OpenIB InfiniBand SRP Miniport"\r
+DiskId = "OpenIB InfiniBand SRP installation disk"\r
InternalBus = 0\r
PNPBus = 15\r
SPSVCINST_NULL = 0x0\r
{\r
int ret;\r
\r
- wait_cq_drain( socket_info );\r
-\r
/* Non-blocking cancel since we're in CM callback context */\r
ib_cm_cancel( socket_info->listen.handle, NULL );\r
socket_info->listen.handle = NULL;\r
+ cl_spinlock_release( &socket_info->mutex );\r
+\r
+ wait_cq_drain( socket_info );\r
\r
+ cl_spinlock_acquire( &socket_info->mutex );\r
ret = ib_accept( socket_info, p_cm_req_rec );\r
if( ret )\r
{\r
create_name(\r
OUT char *fname,\r
IN const DWORD dwProcessId,\r
- IN const DWORD identifier )\r
+ IN const GUID *p_guid )\r
{\r
- sprintf( fname, "SilverStorm-WSD-%08lx-%08lx", dwProcessId, identifier );\r
+ sprintf( fname, "Global\\OpenIB-WSD-%08lx-"\r
+ "%08lx-%04hx-%04hx-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",\r
+ dwProcessId, p_guid->Data1, p_guid->Data2, p_guid->Data3,\r
+ (int)p_guid->Data4[0], (int)p_guid->Data4[1],\r
+ (int)p_guid->Data4[2], (int)p_guid->Data4[3],\r
+ (int)p_guid->Data4[4], (int)p_guid->Data4[5],\r
+ (int)p_guid->Data4[6], (int)p_guid->Data4[7] );\r
}\r
\r
\r
int\r
setup_duplicate_socket(\r
IN struct ibsp_socket_info *socket_info,\r
- IN DWORD identifier )\r
+ IN HANDLE h_dup_info )\r
{\r
- char fname[100];\r
- HANDLE h = NULL;\r
int ret, err;\r
struct ibsp_duplicate_info *dup_info;\r
ib_net64_t dest_port_guid;\r
ib_path_rec_t path_rec;\r
\r
- CL_ASSERT( socket_info->socket_state == IBSP_CREATE );\r
-\r
- fzprint(("%s():%d:0x%x:0x%x: socket=0x%p dwProcessId=0x%x\n", __FUNCTION__,\r
- __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), socket_info));\r
-\r
+ IBSP_ENTER( IBSP_DBG_DUP );\r
\r
- /* Find the info created and shared by the previous controlling socket. */\r
- create_name( fname, GetCurrentProcessId(), identifier );\r
-\r
- h = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file\r
- NULL, // default security attributes\r
- PAGE_READWRITE, // read access\r
- 0, // size: high 32-bits\r
- sizeof(struct ibsp_duplicate_info), // size: low 32-bits\r
- fname ); // name of map object\r
- if( h == NULL )\r
- {\r
- IBSP_ERROR( ("CreateFileMapping failed with %d\n", GetLastError()) );\r
- ret = WSAENETDOWN;\r
- goto err1;\r
- }\r
-\r
- /* Make sure this file already existed. */\r
- if( GetLastError() != ERROR_ALREADY_EXISTS )\r
- {\r
- IBSP_ERROR( ("not mapping for socket duplicate info\n") );\r
- ret = WSAENETDOWN;\r
- goto err1;\r
- }\r
+ CL_ASSERT( socket_info->socket_state == IBSP_CREATE );\r
\r
/* Get a pointer to the file-mapped shared memory. */\r
- dup_info = MapViewOfFile( h, // object to map view of\r
- FILE_MAP_WRITE, // read/write access\r
- 0, // high offset: map from\r
- 0, // low offset: beginning\r
- 0 ); // default: map entire file\r
+ dup_info = MapViewOfFile( h_dup_info, FILE_MAP_READ, 0, 0, 0 );\r
if( dup_info == NULL )\r
{\r
IBSP_ERROR( ("MapViewOfFile failed with %d\n", GetLastError()) );\r
socket_info->local_addr = dup_info->local_addr;\r
socket_info->socket_options = dup_info->socket_options;\r
socket_info->duplicate.dwProcessId = dup_info->dwProcessId;\r
- socket_info->duplicate.identifier = identifier;\r
+ socket_info->duplicate.identifier = dup_info->identifier;\r
\r
- /* Get the port info */\r
- /* Find the destination IP address */\r
socket_info->port = get_port_from_ip_address( dup_info->local_addr.sin_addr );\r
if( socket_info->port == NULL )\r
{\r
}\r
else\r
{\r
+ ret = 0;\r
cl_spinlock_release( &socket_info->mutex );\r
}\r
\r
err1:\r
- if( h )\r
- CloseHandle( h );\r
-\r
if( socket_info->h_event )\r
{\r
CloseHandle( socket_info->h_event );\r
socket_info->h_event = NULL;\r
}\r
\r
- IBSP_EXIT( IBSP_DBG_CONN );\r
+ CloseHandle( h_dup_info );\r
+\r
+ IBSP_EXIT( IBSP_DBG_DUP );\r
return ret;\r
}\r
\r
\r
-/*\r
- * This function is called by the previous controlling process.\r
- * Called with the socket_info->mutex held.\r
- */\r
-int\r
-prepare_duplicate_socket(\r
- IN struct ibsp_socket_info *socket_info,\r
- IN DWORD dwProcessId )\r
+/* Function: IBSPDuplicateSocket\r
+\r
+ Description:\r
+ This function provides a WSAPROTOCOL_INFOW structure which can be passed\r
+ to another process to open a handle to the same socket. First we need\r
+ to translate the user socket into the provider socket and call the underlying\r
+ WSPDuplicateSocket. Note that the lpProtocolInfo structure passed into us\r
+ is an out parameter only!\r
+*/\r
+int WSPAPI\r
+IBSPDuplicateSocket(\r
+ SOCKET s,\r
+ DWORD dwProcessId,\r
+ LPWSAPROTOCOL_INFOW lpProtocolInfo,\r
+ LPINT lpErrno )\r
{\r
+ struct ibsp_socket_info *socket_info = (struct ibsp_socket_info *)s;\r
struct ibsp_duplicate_info *dup_info = NULL;\r
- int i;\r
- DWORD identifier = 0;\r
+ char fname[100];\r
+ GUID guid;\r
+ HANDLE h_dup_info, h_target_process, h_target_dup_info;\r
struct disconnect_reason reason;\r
\r
- fzprint(("%s():%d:0x%x:0x%x: socket=0x%p dwProcessId=0x%x \n", __FUNCTION__,\r
- __LINE__, GetCurrentProcessId(),\r
- GetCurrentThreadId(), socket_info, dwProcessId));\r
+ IBSP_ENTER( IBSP_DBG_DUP );\r
+\r
+ IBSP_TRACE4( IBSP_DBG_DUP,\r
+ ("Duplicating socket=0x%p to dwProcessId=0x%x \n",\r
+ socket_info, dwProcessId) );\r
+\r
+ cl_spinlock_acquire( &socket_info->mutex );\r
+ if( socket_info->socket_state != IBSP_CONNECTED )\r
+ {\r
+ cl_spinlock_release( &socket_info->mutex );\r
+ IBSP_TRACE_EXIT( IBSP_DBG_DUP,\r
+ ("Socket state not IBSP_CONNECTED, state=%s.\n",\r
+ IBSP_SOCKET_STATE_STR( socket_info->socket_state )) );\r
+ *lpErrno = WSAENOTCONN;\r
+ return SOCKET_ERROR;\r
+ }\r
\r
- /* First, flush all the receive buffers. There should be no send/rdma buffers left. */\r
- CL_ASSERT( socket_info->socket_state == IBSP_CONNECTED );\r
IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_DUPLICATING_OLD );\r
\r
/* We changed the state - remove from connection map. */\r
ibsp_conn_remove( socket_info );\r
\r
- /* We might have a left-over from the previous duplicate. */\r
- if( socket_info->duplicate.mmap_handle != NULL )\r
+ cl_spinlock_release( &socket_info->mutex );\r
+\r
+ /* Create a GUID to use as unique identifier for this duplication. */\r
+ UuidCreate( &guid );\r
+ create_name( fname, dwProcessId, &guid );\r
+\r
+ h_dup_info = CreateFileMapping( INVALID_HANDLE_VALUE, NULL,\r
+ PAGE_READWRITE, 0, sizeof(struct ibsp_duplicate_info), fname );\r
+ if( !h_dup_info )\r
+ {\r
+ IBSP_ERROR_EXIT(\r
+ ("CreateFileMapping for %s failed with %d\n",\r
+ fname, GetLastError()) );\r
+ *lpErrno = WSAENETDOWN;\r
+ return SOCKET_ERROR;\r
+ }\r
+\r
+ /* Get a pointer to the file-mapped shared memory. */\r
+ dup_info = MapViewOfFile( h_dup_info, FILE_MAP_WRITE, 0, 0, 0 );\r
+ if( !dup_info )\r
{\r
- CloseHandle( socket_info->duplicate.mmap_handle );\r
- socket_info->duplicate.mmap_handle = NULL;\r
+ IBSP_ERROR_EXIT(\r
+ ("MapViewOfFile failed with %d\n", GetLastError()) );\r
+ CloseHandle( h_dup_info );\r
+ *lpErrno = WSAENETDOWN;\r
+ return SOCKET_ERROR;\r
}\r
\r
/* \r
- * Share this socket_info so the next-controlling process can get the necessary\r
- * information to create the duplicated socket. Ensure a unique identifier. \r
+ * Store addressing information so that the duplicating\r
+ * process can reconnect.\r
*/\r
- for( i = 0; i < 50; i++ )\r
+ dup_info->identifier = guid;\r
+ dup_info->socket_options = socket_info->socket_options;\r
+ dup_info->peer_addr = socket_info->peer_addr;\r
+ dup_info->local_addr = socket_info->local_addr;\r
+ dup_info->dwProcessId = dwProcessId;\r
+\r
+ /* Release the reference on the underlying file */\r
+ UnmapViewOfFile( dup_info );\r
+\r
+ /* Open the target process. */\r
+ h_target_process = OpenProcess( PROCESS_DUP_HANDLE, FALSE, dwProcessId );\r
+ if( !h_target_process )\r
{\r
- char fname[100];\r
- GUID guid;\r
-\r
- /* Create a GUID and collapse it into 32 bits. */\r
- UuidCreate( &guid );\r
- identifier = guid.Data1 ^ (guid.Data2 << 16 | guid.Data3) ^\r
- (guid.Data4[7] << 24 | guid.Data4[6] << 16 | guid.Data4[5] << 8 | guid.\r
- Data4[4]) ^ (guid.Data4[3] << 24 | guid.Data4[2] << 16 | guid.\r
- Data4[1] << 8 | guid.Data4[0]);\r
-\r
- create_name( fname, dwProcessId, identifier );\r
-\r
- socket_info->duplicate.mmap_handle = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file\r
- NULL, // default security attributes\r
- PAGE_READWRITE, // read access\r
- 0, // size: high 32-bits\r
- sizeof(struct ibsp_duplicate_info), // size: low 32-bits\r
- fname ); // name of map object\r
-\r
- if( socket_info->duplicate.mmap_handle == NULL )\r
- {\r
- IBSP_ERROR_EXIT(\r
- ("CreateFileMapping failed with %d\n", GetLastError()) );\r
- return WSAENETDOWN;\r
- }\r
-\r
- /* Make sure this identifier is unique for that process. */\r
- if( GetLastError() == ERROR_ALREADY_EXISTS )\r
- {\r
- CloseHandle( socket_info->duplicate.mmap_handle );\r
- socket_info->duplicate.mmap_handle = NULL;\r
-\r
- /* Try again. */\r
- continue;\r
- }\r
-\r
- /* Get a pointer to the file-mapped shared memory. */\r
- dup_info = MapViewOfFile( socket_info->duplicate.mmap_handle, // object to map view of\r
- FILE_MAP_WRITE, // read/write access\r
- 0, // high offset: map from\r
- 0, // low offset: beginning\r
- 0 ); // default: map entire file\r
- if( dup_info == NULL )\r
- {\r
- IBSP_ERROR_EXIT(\r
- ("MapViewOfFile failed with %d\n", GetLastError()) );\r
- CloseHandle( socket_info->duplicate.mmap_handle );\r
- socket_info->duplicate.mmap_handle = NULL;\r
- return WSAENETDOWN;\r
- }\r
+ IBSP_ERROR_EXIT(\r
+ ("OpenProcess failed with %d\n", GetLastError()) );\r
+ CloseHandle( h_dup_info );\r
+ *lpErrno = WSAENETDOWN;\r
+ return SOCKET_ERROR;\r
}\r
\r
- if( dup_info == NULL )\r
+ if( !DuplicateHandle( GetCurrentProcess(), h_dup_info,\r
+ h_target_process, &h_target_dup_info, 0, TRUE,\r
+ DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS ) )\r
{\r
- IBSP_ERROR_EXIT( ("failed to get a unique identifier\n") );\r
- CloseHandle( socket_info->duplicate.mmap_handle );\r
- socket_info->duplicate.mmap_handle = NULL;\r
- return WSAENETDOWN;\r
+ IBSP_ERROR_EXIT(\r
+ ("DuplicateHandle failed with %d\n", GetLastError()) );\r
+ CloseHandle( h_target_process );\r
+ *lpErrno = WSAENETDOWN;\r
+ return SOCKET_ERROR;\r
}\r
\r
- socket_info->duplicate.identifier = identifier;\r
+ CloseHandle( h_target_process );\r
+\r
+ CL_ASSERT( !((ULONG_PTR)h_target_dup_info >> 32) );\r
+ lpProtocolInfo->dwProviderReserved = (DWORD)(ULONG_PTR)h_target_dup_info;\r
+\r
+ socket_info->duplicate.identifier = guid;\r
\r
memset( &reason, 0, sizeof(reason) );\r
reason.type = DISC_DUPLICATING;\r
- reason.duplicating.identifier = identifier;\r
+ reason.duplicating.identifier = guid;\r
reason.duplicating.dwProcessId = dwProcessId;\r
\r
- cl_spinlock_release( &socket_info->mutex );\r
+ /*\r
+ * Flush all the receive buffers. There should be no\r
+ * send/rdma buffers left.\r
+ */\r
ib_disconnect( socket_info, &reason );\r
- cl_spinlock_acquire( &socket_info->mutex );\r
\r
wait_cq_drain( socket_info );\r
\r
+ cl_spinlock_acquire( &socket_info->mutex );\r
ib_destroy_socket( socket_info );\r
-\r
- /* Put enough info in dup_info so that the remote socket can recreate the connection. */\r
- dup_info->port_guid = socket_info->port->guid;\r
- dup_info->socket_options = socket_info->socket_options;\r
- dup_info->peer_addr = socket_info->peer_addr;\r
- dup_info->local_addr = socket_info->local_addr;\r
- dup_info->dwProcessId = dwProcessId;\r
+ cl_spinlock_release( &socket_info->mutex );\r
\r
/* And that's it */\r
- IBSP_EXIT( IBSP_DBG_CONN );\r
+ IBSP_EXIT( IBSP_DBG_DUP );\r
+ *lpErrno = 0;\r
return 0;\r
}\r
* GetOverlappedResult() even if we call lpWPUCompleteOverlappedRequest()\r
*/\r
if( wc->wc_type == IB_WC_RECV )\r
+ {\r
lpOverlapped->InternalHigh = wc->length;\r
\r
+#ifdef IBSP_LOGGING\r
+ cl_spinlock_acquire( &socket_info->recv_lock );\r
+ DataLogger_WriteData(&socket_info->RecvDataLogger,\r
+ p_recv_wr->idx, (void * __ptr64)p_recv_wr->ds_array[0].vaddr,\r
+ wc->length);\r
+ cl_spinlock_release( &socket_info->recv_lock );\r
+#endif\r
+ }\r
+\r
lpOverlapped->OffsetHigh = 0;\r
break;\r
\r
cl_spinlock_release( &socket_info->recv_lock );\r
\r
cl_spinlock_release( &socket_info->mutex );\r
+ p_io_info->p_ov = NULL;\r
IBSP_EXIT( IBSP_DBG_IO );\r
return;\r
}\r
g_ibsp.overlap_h1_comp_count, g_ibsp.send_count, g_ibsp.recv_count));\r
#endif\r
\r
- IBSP_TRACE1( IBSP_DBG_IO,\r
- ("Calling lpWPUCompleteOverlappedRequest: "\r
- "socket=%p, ov=%p OffsetHigh=%d InternalHigh=%d hEvent=%p\n",\r
- socket_info, lpOverlapped, lpOverlapped->OffsetHigh,\r
- lpOverlapped->InternalHigh, lpOverlapped->hEvent) );\r
-\r
p_io_info->p_ov = lpOverlapped;\r
cl_atomic_inc( &socket_info->ref_cnt );\r
}\r
if( info[i].p_ov )\r
{\r
IBSP_TRACE1( IBSP_DBG_IO,\r
- ("Calling WPUCompleteOverlappedRequest for ov=%p\n",\r
- info[i].p_ov) );\r
+ ("Calling lpWPUCompleteOverlappedRequest: "\r
+ "socket=%p, ov=%p OffsetHigh=%d "\r
+ "InternalHigh=%d hEvent=%p\n",\r
+ info[i].p_socket, info[i].p_ov, info[i].p_ov->OffsetHigh,\r
+ info[i].p_ov->InternalHigh, info[i].p_ov->hEvent) );\r
\r
ret = g_ibsp.up_call_table.lpWPUCompleteOverlappedRequest(\r
info[i].p_socket->switch_socket, info[i].p_ov,\r
}\r
\r
/* \r
- * TODO: By rearanging thread creation and cq creation, this check\r
+ * TODO: By rearranging thread creation and cq creation, this check\r
* may be eliminated.\r
*/\r
if( cq_tinfo->cq != NULL )\r
cq_tinfo->hca = hca;\r
cq_tinfo->ib_cq_thread_exit_wanted = FALSE;\r
\r
- /* Create a cleanup thread */\r
cq_tinfo->ib_cq_thread = CreateThread( NULL, 0, ib_cq_thread, cq_tinfo, 0, (LPDWORD)&cq_tinfo->ib_cq_thread_id );\r
\r
if( cq_tinfo->ib_cq_thread == NULL )\r
cq_create.pfn_comp_cb = NULL;\r
cq_create.h_wait_obj = cq_tinfo->cq_waitobj;\r
\r
- status = ib_create_cq( hca->hca_handle, &cq_create, cq_tinfo, /* context */\r
- NULL, /* async handler */\r
- &cq_tinfo->cq );\r
+ status = ib_create_cq( hca->hca_handle, &cq_create, cq_tinfo,\r
+ NULL, &cq_tinfo->cq );\r
if( status )\r
{\r
ib_destroy_cq_tinfo( cq_tinfo );\r
goto done;\r
}\r
\r
- /* Populate IP list. */\r
- update_all_ip_addrs();\r
-\r
STAT_INC( thread_num );\r
\r
ret = 0;\r
IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_CLOSED );\r
cl_spinlock_release( &socket_info->mutex );\r
\r
- if( socket_info->duplicate.mmap_handle )\r
- {\r
- CloseHandle( socket_info->duplicate.mmap_handle );\r
- socket_info->duplicate.mmap_handle = NULL;\r
- }\r
-\r
if( socket_info->listen.handle )\r
{\r
/* Stop listening and reject queued connections. */\r
\r
ib_destroy_socket( socket_info );\r
\r
+#ifdef IBSP_LOGGING\r
+ DataLogger_Shutdown(&socket_info->SendDataLogger);\r
+ DataLogger_Shutdown(&socket_info->RecvDataLogger);\r
+#endif\r
+\r
/* Release the initial reference and clean up. */\r
deref_socket_info( socket_info );\r
\r
}\r
\r
\r
-static void AL_API\r
-query_ip_address_callback(\r
- ib_query_rec_t *p_query_rec )\r
-{\r
- struct ip_query_context *query_context =\r
- (struct ip_query_context * __ptr64)p_query_rec->query_context;\r
- cl_fmap_item_t *p_item;\r
-\r
- IBSP_ENTER( IBSP_DBG_HW );\r
- IBSP_TRACE( IBSP_DBG_HW,\r
- ("status is %s\n", ib_get_err_str( p_query_rec->status )) );\r
-\r
- if( p_query_rec->status == IB_SUCCESS )\r
- {\r
- unsigned int i;\r
-\r
- IBSP_TRACE( IBSP_DBG_HW, ("got %d records\n", p_query_rec->result_cnt) );\r
-\r
- for( i = 0; i < p_query_rec->result_cnt; i++ )\r
- {\r
- ib_service_record_t *service_record =\r
- ib_get_query_svc_rec(p_query_rec->p_result_mad, i);\r
- struct ibsp_ip_addr *ip_addr;\r
-\r
- ip_addr =\r
- HeapAlloc( g_ibsp.heap, HEAP_ZERO_MEMORY, sizeof(struct ibsp_ip_addr) );\r
- if( !ip_addr )\r
- {\r
- IBSP_ERROR_EXIT( ("no memory\n") );\r
- break;\r
- }\r
-\r
- /* Copy the IP address */\r
- ip_addr->ip_addr.S_un.S_addr =\r
- *(ib_net32_t *) & service_record->service_data8[ATS_IPV4_OFFSET];\r
- ip_addr->p_port = query_context->p_port;\r
-\r
- p_item = cl_fmap_insert(\r
- query_context->p_ip_map, ip_addr, &ip_addr->item );\r
- if( p_item != &ip_addr->item )\r
- {\r
- /* Duplicate! Should never happen. */\r
- IBSP_ERROR(\r
- ("Got duplicate addr %s\n", inet_ntoa( ip_addr->ip_addr )) );\r
- HeapFree( g_ibsp.heap, 0, ip_addr );\r
- continue;\r
- }\r
-\r
- IBSP_TRACE( IBSP_DBG_HW,\r
- (" Got addr %s\n", inet_ntoa( ip_addr->ip_addr )) );\r
- }\r
- }\r
- else if( p_query_rec->p_result_mad )\r
- {\r
- IBSP_TRACE( IBSP_DBG_HW, ("SA status is %x\n",\r
- p_query_rec->p_result_mad->p_mad_buf->status) );\r
- }\r
-\r
- if( p_query_rec->p_result_mad )\r
- ib_put_mad( p_query_rec->p_result_mad );\r
-\r
- IBSP_EXIT( IBSP_DBG_HW );\r
-}\r
-\r
-\r
/* Synchronously query the SA for an IP address. */\r
int\r
query_ip_address(\r
IN struct ibsp_port *p_port,\r
IN OUT cl_fmap_t *p_ip_map )\r
{\r
- ib_user_query_t user_query;\r
- struct ip_query_context query_context;\r
- ib_service_record_t service_record;\r
- ib_query_handle_t query_handle;\r
- ib_query_req_t query_req;\r
- ib_api_status_t status;\r
+ IOCTL_IBAT_IP_ADDRESSES_IN in;\r
+ IOCTL_IBAT_IP_ADDRESSES_OUT *p_out;\r
+ DWORD size;\r
+ LONG i;\r
+ cl_fmap_item_t *p_item;\r
\r
IBSP_ENTER( IBSP_DBG_HW );\r
\r
/* The list must be initialized and empty */\r
CL_ASSERT( !cl_fmap_count( p_ip_map ) );\r
\r
- query_context.p_ip_map = p_ip_map;\r
- query_context.p_port = p_port;\r
+ in.Version = IBAT_IOCTL_VERSION;\r
+ in.PortGuid = p_port->guid;\r
\r
- query_req.query_type = IB_QUERY_USER_DEFINED;\r
- query_req.p_query_input = &user_query;\r
- query_req.port_guid = p_port->guid;\r
- query_req.timeout_ms = 500; /* 500ms timeout */\r
- query_req.retry_cnt = 4; /* retry 4 times */\r
- query_req.flags = IB_FLAGS_SYNC;\r
- query_req.query_context = &query_context;\r
- query_req.pfn_query_cb = query_ip_address_callback;\r
+ cl_spinlock_acquire( &g_ibsp.ip_mutex );\r
+ if( g_ibsp.h_ibat_dev == INVALID_HANDLE_VALUE )\r
+ {\r
+ g_ibsp.h_ibat_dev = CreateFileW( IBAT_WIN32_NAME,\r
+ GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,\r
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );\r
+ }\r
+ cl_spinlock_release( &g_ibsp.ip_mutex );\r
\r
- user_query.method = IB_MAD_METHOD_GETTABLE;\r
- user_query.attr_id = IB_MAD_ATTR_SERVICE_RECORD;\r
- user_query.attr_size = sizeof(ib_service_record_t);\r
- user_query.comp_mask = IB_SR_COMPMASK_SGID |\r
- IB_SR_COMPMASK_SPKEY | IB_SR_COMPMASK_SLEASE | IB_SR_COMPMASK_SNAME;\r
+ size = sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT);\r
\r
- user_query.p_attr = &service_record;\r
+ do\r
+ {\r
+ p_out = HeapAlloc( g_ibsp.heap, 0, size );\r
\r
- memset( &service_record, 0, sizeof(service_record) );\r
- service_record.service_pkey = IB_DEFAULT_PKEY;\r
- ib_gid_set_default( &service_record.service_gid, p_port->guid );\r
- service_record.service_lease = 0xFFFFFFFF;\r
- strcpy( (void *)service_record.service_name, ATS_NAME );\r
+ if( !p_out )\r
+ {\r
+ IBSP_ERROR_EXIT( ("Failed to allocate output buffer.\n") );\r
+ return -1;\r
+ }\r
+\r
+ if( !DeviceIoControl( g_ibsp.h_ibat_dev, IOCTL_IBAT_IP_ADDRESSES,\r
+ &in, sizeof(in), p_out, size, &size, NULL ) )\r
+ {\r
+ HeapFree( g_ibsp.heap, 0, p_out );\r
+ IBSP_ERROR_EXIT(\r
+ ("IOCTL_IBAT_IP_ADDRESSES for port %I64x failed (%x).\n",\r
+ p_port->guid, GetLastError()) );\r
+ return -1;\r
+ }\r
\r
- fzprint(("%s():%d:0x%x:0x%x: Calling ib_query() pfn_query_cb=0x%p..\n", __FUNCTION__,\r
- __LINE__, GetCurrentProcessId(),\r
- GetCurrentThreadId(), query_req.pfn_query_cb));\r
+ if( p_out->Size > size )\r
+ {\r
+ size = p_out->Size;\r
+ HeapFree( g_ibsp.heap, 0, p_out );\r
+ p_out = NULL;\r
+ }\r
\r
- status = ib_query( g_ibsp.al_handle, &query_req, &query_handle );\r
+ } while( !p_out );\r
\r
- if( status != IB_SUCCESS && status != IB_INVALID_GUID )\r
+ IBSP_TRACE( IBSP_DBG_HW, ("Port %I64x has %d IP addresses.\n",\r
+ p_port->guid, p_out->AddressCount) );\r
+\r
+ for( i = 0; i < p_out->AddressCount; i++ )\r
{\r
- IBSP_ERROR( ("ib_query failed (%d)\n", status) );\r
- CL_ASSERT( !cl_fmap_count( p_ip_map ) );\r
+ struct ibsp_ip_addr *ip_addr;\r
\r
- IBSP_ERROR_EXIT(\r
- ("Failed to build list of IP addr for port %016I64x\n",\r
- CL_HTON64( p_port->guid )) );\r
+ ip_addr = HeapAlloc(\r
+ g_ibsp.heap, 0, sizeof(struct ibsp_ip_addr) );\r
+ if( !ip_addr )\r
+ {\r
+ IBSP_ERROR_EXIT( ("no memory\n") );\r
+ break;\r
+ }\r
\r
- IBSP_ERROR_EXIT( ("query_ip_address failed\n") );\r
- return 1;\r
- }\r
+ /* Copy the IP address */\r
+ ip_addr->ip_addr.S_un.S_addr =\r
+ *(ib_net32_t *) &p_out->Address[i].Address[ATS_IPV4_OFFSET];\r
+ ip_addr->p_port = p_port;\r
\r
- fzprint(("%s():%d:0x%x:0x%x: Done calling ib_query() status=(%d)\n", __FUNCTION__,\r
- __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), status));\r
+ p_item = cl_fmap_insert( p_ip_map, ip_addr, &ip_addr->item );\r
+ if( p_item != &ip_addr->item )\r
+ {\r
+ /* Duplicate! Should never happen. */\r
+ IBSP_ERROR(\r
+ ("Got duplicate addr %s\n", inet_ntoa( ip_addr->ip_addr )) );\r
+ HeapFree( g_ibsp.heap, 0, ip_addr );\r
+ continue;\r
+ }\r
\r
+ IBSP_TRACE( IBSP_DBG_HW,\r
+ ("Got addr %s\n", inet_ntoa( ip_addr->ip_addr )) );\r
+ }\r
+\r
+ HeapFree( g_ibsp.heap, 0, p_out );\r
\r
IBSP_EXIT( IBSP_DBG_HW );\r
return 0;\r
return 0;\r
}\r
\r
-\r
-void\r
-update_all_ip_addrs(void)\r
-{\r
- cl_list_item_t *p_hca_item, *p_port_item;\r
- struct ibsp_hca *p_hca;\r
- struct ibsp_port *p_port;\r
-\r
- IBSP_ENTER( IBSP_DBG_HW );\r
-\r
- cl_spinlock_acquire( &g_ibsp.hca_mutex );\r
- for( p_hca_item = cl_qlist_head( &g_ibsp.hca_list );\r
- p_hca_item != cl_qlist_end( &g_ibsp.hca_list );\r
- p_hca_item = cl_qlist_next( p_hca_item ) )\r
- {\r
- p_hca = PARENT_STRUCT( p_hca_item, struct ibsp_hca, item );\r
-\r
- cl_spinlock_acquire( &p_hca->port_lock );\r
- for( p_port_item = cl_qlist_head( &p_hca->port_list );\r
- p_port_item != cl_qlist_end( &p_hca->port_list );\r
- p_port_item = cl_qlist_next( p_port_item ) )\r
- {\r
- p_port = PARENT_STRUCT( p_port_item, struct ibsp_port, item );\r
- update_ip_addresses( p_port );\r
- }\r
- cl_spinlock_release( &p_hca->port_lock );\r
- }\r
- cl_spinlock_release( &g_ibsp.hca_mutex );\r
-\r
- IBSP_EXIT( IBSP_DBG_HW );\r
-}\r
-\r
/*--------------------------------------------------------------------------*/\r
\r
/* \r
switch( num_ip )\r
{\r
case 0:\r
+ cl_spinlock_acquire( &g_ibsp.ip_mutex );\r
+ if( g_ibsp.h_ibat_dev != INVALID_HANDLE_VALUE )\r
+ {\r
+ CloseHandle( g_ibsp.h_ibat_dev );\r
+ g_ibsp.h_ibat_dev = INVALID_HANDLE_VALUE;\r
+ }\r
+ cl_spinlock_release( &g_ibsp.ip_mutex );\r
break;\r
\r
default:\r
}\r
\r
#endif /* _DEBUG_ */\r
+\r
+\r
+#ifdef IBSP_LOGGING\r
+\r
+VOID DataLogger_Init(\r
+ DataLogger *pLogger,\r
+ char *prefix,\r
+ struct sockaddr_in *addr1,\r
+ struct sockaddr_in *addr2 )\r
+{\r
+ HANDLE hFile;\r
+ HANDLE hMapFile;\r
+\r
+ char Name[100];\r
+ DWORD DataSize = 20 * 1024 * 1024; \r
+\r
+ sprintf(Name,"c:\\%s_%d.%d.%d.%d_%d_%d.%d.%d.%d_%d", \r
+ prefix,\r
+ addr1->sin_addr.S_un.S_un_b.s_b1,\r
+ addr1->sin_addr.S_un.S_un_b.s_b2,\r
+ addr1->sin_addr.S_un.S_un_b.s_b3,\r
+ addr1->sin_addr.S_un.S_un_b.s_b4,\r
+ CL_NTOH16(addr1->sin_port),\r
+ addr2->sin_addr.S_un.S_un_b.s_b1,\r
+ addr2->sin_addr.S_un.S_un_b.s_b2,\r
+ addr2->sin_addr.S_un.S_un_b.s_b3,\r
+ addr2->sin_addr.S_un.S_un_b.s_b4,\r
+ CL_NTOH16(addr2->sin_port)\r
+ );\r
+\r
+ pLogger->NextPrint = NULL;\r
+ pLogger->BufferStart = NULL;\r
+ pLogger->ShutdownClosed = FALSE;\r
+ pLogger->ToatalPrinted = 0;\r
+ pLogger->TotalSize = DataSize;\r
+\r
+ hFile = CreateFile( Name, GENERIC_READ|GENERIC_WRITE,\r
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS,\r
+ FILE_ATTRIBUTE_NORMAL, NULL );\r
+\r
+ if (hFile == INVALID_HANDLE_VALUE)\r
+ {\r
+ IBSP_ERROR( ("CreateFile failed with error %d\n", GetLastError()) );\r
+ return;\r
+ }\r
+\r
+ hMapFile = CreateFileMapping(hFile, // current file handle \r
+ NULL, // default security \r
+ PAGE_READWRITE, // read/write permission \r
+ 0, // max. object size \r
+ DataSize, // size of hFile \r
+ NULL); // name of mapping object\r
+\r
+ CloseHandle( hFile );\r
+\r
+ if (hMapFile == NULL) \r
+ { \r
+ IBSP_ERROR( ("Could not create file mapping object.\n") );\r
+ return;\r
+ }\r
+\r
+ pLogger->BufferStart = MapViewOfFile(hMapFile, // handle to mapping object \r
+ FILE_MAP_ALL_ACCESS, // read/write permission \r
+ 0, // max. object size \r
+ 0, // size of hFile \r
+ 0); // map entire file \r
+\r
+ CloseHandle( hMapFile );\r
+\r
+ if( pLogger->BufferStart == NULL )\r
+ {\r
+ IBSP_ERROR( ("Could not MapViewOfFile.\n") );\r
+ return;\r
+ }\r
+\r
+ pLogger->NextPrint = pLogger->BufferStart;\r
+ cl_memclr(pLogger->NextPrint, DataSize);\r
+}\r
+\r
+\r
+VOID DataLogger_WriteData(\r
+ DataLogger *pLogger,\r
+ long Idx,\r
+ char *Data,\r
+ DWORD Len )\r
+{\r
+ char MessageHeader[16];\r
+ CL_ASSERT(Len < 64000);\r
+ CL_ASSERT(pLogger->ShutdownClosed == FALSE);\r
+ CL_ASSERT(Len < pLogger->TotalSize / 3);\r
+\r
+ if( !pLogger->BufferStart )\r
+ return;\r
+\r
+ cl_memset( MessageHeader, 0xff, sizeof(MessageHeader) );\r
+ cl_memcpy( MessageHeader+4, &Idx, sizeof(Idx) );\r
+ cl_memcpy( MessageHeader+8, &Len, sizeof(Len) );\r
+\r
+ pLogger->ToatalPrinted += Len;\r
+\r
+ if( pLogger->NextPrint + Len + (2 * sizeof (MessageHeader)) >\r
+ pLogger->BufferStart + pLogger->TotalSize )\r
+ {\r
+ /* We will now zero the remaing of the buffer, and restart */\r
+ cl_memclr( pLogger->NextPrint,\r
+ pLogger->TotalSize - (pLogger->NextPrint - pLogger->BufferStart) );\r
+ pLogger->NextPrint = pLogger->BufferStart;\r
+ }\r
+\r
+ /* Just simple copy */\r
+ cl_memcpy( pLogger->NextPrint, MessageHeader, sizeof(MessageHeader) );\r
+ pLogger->NextPrint += sizeof(MessageHeader);\r
+\r
+ cl_memcpy( pLogger->NextPrint, Data, Len );\r
+ pLogger->NextPrint += Len;\r
+\r
+ /*\r
+ * Add the end marker but don't update NextPrint so the next message\r
+ * overwrites the previous message's end marker.\r
+ */\r
+ cl_memset( pLogger->NextPrint, 0xff, sizeof(MessageHeader) );\r
+}\r
+\r
+\r
+VOID DataLogger_Shutdown(\r
+ DataLogger *pLogger )\r
+{\r
+ if( !pLogger->BufferStart )\r
+ return;\r
+\r
+ UnmapViewOfFile( pLogger->BufferStart );\r
+}\r
+\r
+#endif /* IBSP_LOGGING */\r
#define IBSP_DBG_NEV 0x00000400 /* network events */\r
#define IBSP_DBG_HW 0x00000800 /* Hardware */\r
#define IBSP_DBG_IO 0x00001000 /* Overlapped I/O request */\r
+#define IBSP_DBG_DUP 0x00002000 /* Socket Duplication */\r
\r
#define IBSP_DBG_LEVEL4 0x01000000 /* debug use */\r
#define IBSP_DBG_LEVEL3 0x02000000 /* debug use */\r
#define STATS(expr)\r
\r
#endif /* _DEBUG_ */\r
+\r
+/*\r
+ * To enable logging of all Send/Receive data for each socket\r
+ * uncomment the following line.\r
+ */\r
+//#define IBSP_LOGGING\r
+\r
+#ifdef IBSP_LOGGING\r
+\r
+typedef struct DataLogger\r
+{\r
+ char *BufferStart;\r
+ size_t TotalSize;\r
+ char *NextPrint;\r
+ size_t ToatalPrinted;\r
+ BOOL ShutdownClosed;\r
+ HANDLE hMapFile;\r
+\r
+}DataLogger;\r
+\r
+\r
+VOID DataLogger_Init(\r
+ DataLogger *pLoger,\r
+ char *prefix,\r
+ struct sockaddr_in *addr1,\r
+ struct sockaddr_in *addr2 );\r
+\r
+\r
+VOID DataLogger_WriteData(\r
+ DataLogger *pLoger,\r
+ long Idx,\r
+ char *Data,\r
+ DWORD Len );\r
+\r
+VOID DataLogger_Shutdown(\r
+ DataLogger *pLoger );\r
+\r
+#endif /* IBSP_LOGGING */\r
{\r
struct ibsp_socket_info *socket_info = NULL;\r
socket_info = PARENT_STRUCT(socket_item, struct ibsp_socket_info, item);\r
+\r
+#ifdef IBSP_LOGGING\r
+ DataLogger_Shutdown(&socket_info->SendDataLogger);\r
+ DataLogger_Shutdown(&socket_info->RecvDataLogger);\r
+#endif\r
}\r
\r
cl_spinlock_release( &g_ibsp.socket_info_mutex );\r
\r
new_socket_info->peer_addr = p_incoming->params.source;\r
\r
+#ifdef IBSP_LOGGING\r
+ DataLogger_Init( &new_socket_info->SendDataLogger, "Send",\r
+ &new_socket_info->peer_addr, &new_socket_info->local_addr );\r
+ DataLogger_Init( &new_socket_info->RecvDataLogger, "Recv",\r
+ &new_socket_info->local_addr, &new_socket_info->peer_addr );\r
+#endif\r
+\r
cl_spinlock_acquire( &new_socket_info->mutex );\r
/* Update the state of the socket context */\r
IBSP_CHANGE_SOCKET_STATE( new_socket_info, IBSP_CONNECTED );\r
/* Store the peer entity's address in socket context */\r
socket_info->peer_addr = *addr;\r
\r
+#ifdef IBSP_LOGGING\r
+ DataLogger_Init( &socket_info->SendDataLogger, "Send",\r
+ &socket_info->peer_addr, &socket_info->local_addr );\r
+ DataLogger_Init( &socket_info->RecvDataLogger, "Recv",\r
+ &socket_info->local_addr, &socket_info->peer_addr );\r
+#endif\r
+\r
/* Update the socket state */\r
IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_CONNECT );\r
\r
}\r
\r
\r
-/* Function: IBSPDuplicateSocket\r
-\r
- Description:\r
- This function provides a WSAPROTOCOL_INFOW structure which can be passed\r
- to another process to open a handle to the same socket. First we need\r
- to translate the user socket into the provider socket and call the underlying\r
- WSPDuplicateSocket. Note that the lpProtocolInfo structure passed into us\r
- is an out parameter only!\r
-*/\r
-static int WSPAPI\r
-IBSPDuplicateSocket(\r
- SOCKET s,\r
- DWORD dwProcessId,\r
- LPWSAPROTOCOL_INFOW lpProtocolInfo,\r
- LPINT lpErrno )\r
-{\r
- struct ibsp_socket_info *socket_info = (struct ibsp_socket_info *)s;\r
- int ret;\r
-\r
- IBSP_ENTER( IBSP_DBG_CONN );\r
-\r
- fzprint(("%s():%d:0x%x:0x%x: socket=0x%p state=%s\n", __FUNCTION__,\r
- __LINE__, GetCurrentProcessId(),\r
- GetCurrentThreadId(), s, IBSP_SOCKET_STATE_STR( socket_info->socket_state )));\r
-\r
- cl_spinlock_acquire( &socket_info->mutex );\r
- if( socket_info->socket_state != IBSP_CONNECTED )\r
- {\r
- cl_spinlock_release( &socket_info->mutex );\r
- IBSP_TRACE_EXIT( IBSP_DBG_CONN,\r
- ("Socket state not IBSP_CONNECTED, state=%s.\n",\r
- IBSP_SOCKET_STATE_STR( socket_info->socket_state )) );\r
- *lpErrno = WSAENOTCONN;\r
- return SOCKET_ERROR;\r
- }\r
-\r
- ret = prepare_duplicate_socket( socket_info, dwProcessId );\r
- cl_spinlock_release( &socket_info->mutex );\r
- if( ret )\r
- {\r
- IBSP_TRACE_EXIT( IBSP_DBG_CONN,\r
- ("prepare_duplicate_socket failed with %d\n", ret) );\r
- *lpErrno = ret;\r
- return SOCKET_ERROR;\r
- }\r
- else\r
- {\r
- IBSP_EXIT( IBSP_DBG_CONN );\r
- lpProtocolInfo->dwProviderReserved = socket_info->duplicate.identifier;\r
- *lpErrno = 0;\r
- return 0;\r
- }\r
-}\r
-\r
-\r
/* Function: IBSPEnumNetworkEvents\r
* \r
* Description:\r
IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_LISTEN );\r
\r
socket_info->listen.listen_req_param.dwProcessId = 0;\r
- socket_info->listen.listen_req_param.identifier = 0;\r
+ cl_memclr( &socket_info->listen.listen_req_param.identifier,\r
+ sizeof(socket_info->listen.listen_req_param.identifier) );\r
\r
ret = ib_listen( socket_info );\r
if( ret )\r
GetCurrentThreadId(), lpOverlapped,\r
g_ibsp.overlap_h0_count, g_ibsp.overlap_h1_count,\r
g_ibsp.overlap_h1_comp_count, g_ibsp.send_count, g_ibsp.recv_count));\r
-\r
-\r
#endif\r
\r
+#ifdef IBSP_LOGGING\r
+ wr->idx = socket_info->recv_log_idx++;\r
+#endif\r
\r
fzprint(("%s():%d:0x%x:0x%x: posting RECV socket=0x%p overlap=%p wr=0x%p\n",\r
__FUNCTION__, __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), s,\r
}\r
#endif\r
\r
+#ifdef IBSP_LOGGING\r
+ {\r
+ DWORD i;\r
+\r
+ for( i=0; i < dwBufferCount; i++ )\r
+ {\r
+ DataLogger_WriteData( &socket_info->SendDataLogger,\r
+ socket_info->send_log_idx++, lpBuffers[i].buf,\r
+ lpBuffers[i].len);\r
+ }\r
+ }\r
+#endif\r
+\r
status = ib_post_send( socket_info->qp, &send_wr, NULL );\r
\r
if( status == IB_SUCCESS )\r
if( lpProtocolInfo->dwProviderReserved != 0 )\r
{\r
/* This is a duplicate socket. */\r
- *lpErrno = setup_duplicate_socket(\r
- socket_info, lpProtocolInfo->dwProviderReserved );\r
+ *lpErrno = setup_duplicate_socket( socket_info,\r
+ (HANDLE)(ULONG_PTR)lpProtocolInfo->dwProviderReserved );\r
if( *lpErrno )\r
{\r
deref_socket_info( socket_info );\r
#include <stdlib.h>\r
#include <ws2spi.h>\r
#include <ws2san.h>\r
+#include <devioctl.h>\r
\r
#include <iba/ib_al.h>\r
+#include <iba/ib_at_ioctl.h>\r
#include <complib/cl_timer.h>\r
\r
#include "ibspdefines.h"\r
IN const ib_api_status_t status );\r
\r
/* Protos from ibsp_ip.c */\r
-void\r
-update_all_ip_addrs(void);\r
-\r
intn_t CL_API\r
ip_cmp(\r
IN const void* const p_key1,\r
int\r
setup_duplicate_socket(\r
IN struct ibsp_socket_info *socket_info,\r
- IN DWORD identifier );\r
+ IN HANDLE h_dup_info );\r
\r
-int\r
-prepare_duplicate_socket(\r
- IN struct ibsp_socket_info *socket_info,\r
- IN DWORD dwProcessId );\r
+int WSPAPI\r
+IBSPDuplicateSocket(\r
+ SOCKET s,\r
+ DWORD dwProcessId,\r
+ LPWSAPROTOCOL_INFOW lpProtocolInfo,\r
+ LPINT lpErrno );\r
\r
/* ibsp_mem.c */\r
\r
struct listen_req_param\r
{\r
DWORD dwProcessId;\r
- DWORD identifier;\r
+ GUID identifier;\r
};\r
\r
/* Parameters given to establish a connection */\r
struct _wr wr;\r
ib_recv_wr_t recv;\r
ib_local_ds_t ds_array[QP_ATTRIB_RQ_SGE];\r
+#ifdef IBSP_LOGGING\r
+ LONG idx;\r
+#endif\r
};\r
\r
\r
/* Information necessary to duplicate sockets */\r
struct ibsp_duplicate_info\r
{\r
- ib_net64_t port_guid;\r
+ GUID identifier;\r
struct ibsp_socket_options socket_options;\r
struct sockaddr_in local_addr;\r
struct sockaddr_in peer_addr;\r
\r
struct _disconnect_reason_dup\r
{\r
- DWORD identifier;\r
+ GUID identifier;\r
DWORD dwProcessId;\r
\r
} duplicating;\r
/* Stuff for socket duplication */\r
struct\r
{\r
- HANDLE mmap_handle;\r
- DWORD identifier; /* Unique identifier */\r
+ GUID identifier; /* Unique identifier */\r
DWORD dwProcessId;\r
} duplicate;\r
+\r
+#ifdef IBSP_LOGGING\r
+ DataLogger SendDataLogger;\r
+ DataLogger RecvDataLogger;\r
+ long recv_log_idx;\r
+ long send_log_idx;\r
+#endif\r
};\r
\r
\r
cl_qlist_t hca_list;\r
cl_spinlock_t hca_mutex;\r
\r
+ HANDLE h_ibat_dev;\r
cl_fmap_t ip_map; /* list of all IP addresses supported by all the ports. */\r
cl_spinlock_t ip_mutex;\r
\r
cl_qlist_init( &g_ibsp.hca_list );\r
cl_spinlock_init( &g_ibsp.hca_mutex );\r
\r
+ g_ibsp.h_ibat_dev = INVALID_HANDLE_VALUE;\r
cl_fmap_init( &g_ibsp.ip_map, ip_cmp );\r
cl_spinlock_init( &g_ibsp.ip_mutex );\r
\r
release_globals( void )\r
{\r
HeapDestroy( g_ibsp.heap );\r
- g_ibsp.heap = NULL;\r
+\r
+ if( g_ibsp.h_ibat_dev != INVALID_HANDLE_VALUE )\r
+ CloseHandle( g_ibsp.h_ibat_dev );\r
\r
cl_spinlock_destroy( &g_ibsp.socket_info_mutex );\r
cl_spinlock_destroy( &g_ibsp.hca_mutex );\r