usr/src/uts/common/io/comstar/port/srpt/srpt_ioc.c
changeset 12075 b143b9fb49fc
parent 11672 5b0f04fcde66
child 12509 69ce72133f79
equal deleted inserted replaced
12074:fb7af6adefb4 12075:b143b9fb49fc
    18  *
    18  *
    19  * CDDL HEADER END
    19  * CDDL HEADER END
    20  */
    20  */
    21 
    21 
    22 /*
    22 /*
    23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
    23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
    24  * Use is subject to license terms.
       
    25  */
    24  */
    26 
    25 
    27 /*
    26 /*
    28  * I/O Controller functions for the Solaris COMSTAR SCSI RDMA Protocol
    27  * I/O Controller functions for the Solaris COMSTAR SCSI RDMA Protocol
    29  * Target (SRPT) port provider.
    28  * Target (SRPT) port provider.
    41 #include "srp.h"
    40 #include "srp.h"
    42 #include "srpt_impl.h"
    41 #include "srpt_impl.h"
    43 #include "srpt_ioc.h"
    42 #include "srpt_ioc.h"
    44 #include "srpt_stp.h"
    43 #include "srpt_stp.h"
    45 #include "srpt_ch.h"
    44 #include "srpt_ch.h"
       
    45 #include "srpt_common.h"
    46 
    46 
    47 /*
    47 /*
    48  * srpt_ioc_srq_size - Tunable parameter that specifies the number
    48  * srpt_ioc_srq_size - Tunable parameter that specifies the number
    49  * of receive WQ entries that can be posted to the IOC shared
    49  * of receive WQ entries that can be posted to the IOC shared
    50  * receive queue.
    50  * receive queue.
    51  */
    51  */
    52 uint32_t	srpt_ioc_srq_size = SRPT_DEFAULT_IOC_SRQ_SIZE;
    52 uint32_t		srpt_ioc_srq_size = SRPT_DEFAULT_IOC_SRQ_SIZE;
    53 extern uint16_t srpt_send_msg_depth;
    53 extern uint16_t		srpt_send_msg_depth;
    54 extern uint32_t	srpt_iu_size;
    54 extern uint32_t		srpt_iu_size;
       
    55 extern boolean_t	srpt_enable_by_default;
    55 
    56 
    56 /* IOC profile capabilities mask must be big-endian */
    57 /* IOC profile capabilities mask must be big-endian */
    57 typedef struct srpt_ioc_opcap_bits_s {
    58 typedef struct srpt_ioc_opcap_bits_s {
    58 #if	defined(_BIT_FIELDS_LTOH)
    59 #if	defined(_BIT_FIELDS_LTOH)
    59 	uint8_t		af:1,
    60 	uint8_t		af:1,
   113 	"srpt"
   114 	"srpt"
   114 };
   115 };
   115 
   116 
   116 static srpt_ioc_t *srpt_ioc_init(ib_guid_t guid);
   117 static srpt_ioc_t *srpt_ioc_init(ib_guid_t guid);
   117 static void srpt_ioc_fini(srpt_ioc_t *ioc);
   118 static void srpt_ioc_fini(srpt_ioc_t *ioc);
       
   119 static boolean_t srpt_check_hca_cfg_enabled(ib_guid_t hca_guid);
   118 
   120 
   119 static srpt_vmem_pool_t *srpt_vmem_create(const char *name, srpt_ioc_t *ioc,
   121 static srpt_vmem_pool_t *srpt_vmem_create(const char *name, srpt_ioc_t *ioc,
   120     ib_memlen_t chunksize, uint64_t maxsize, ibt_mr_flags_t flags);
   122     ib_memlen_t chunksize, uint64_t maxsize, ibt_mr_flags_t flags);
   121 static void *srpt_vmem_alloc(srpt_vmem_pool_t *vm_pool, size_t size);
   123 static void *srpt_vmem_alloc(srpt_vmem_pool_t *vm_pool, size_t size);
   122 static int srpt_vmem_mr_compare(const void *a, const void *b);
   124 static int srpt_vmem_mr_compare(const void *a, const void *b);
   142 {
   144 {
   143 	int		status;
   145 	int		status;
   144 	int		hca_cnt;
   146 	int		hca_cnt;
   145 	int		hca_ndx;
   147 	int		hca_ndx;
   146 	ib_guid_t	*guid;
   148 	ib_guid_t	*guid;
   147 	srpt_ioc_t	*ioc;
       
   148 
   149 
   149 	ASSERT(srpt_ctxt != NULL);
   150 	ASSERT(srpt_ctxt != NULL);
   150 
   151 
   151 	/*
   152 	/*
   152 	 * Attach to IBTF and initialize a list of IB devices.  Each
   153 	 * Attach to IBTF and initialize a list of IB devices.  Each
   169 		SRPT_DPRINTF_L2("ioc_attach, no HCA found");
   170 		SRPT_DPRINTF_L2("ioc_attach, no HCA found");
   170 		return (DDI_SUCCESS);
   171 		return (DDI_SUCCESS);
   171 	}
   172 	}
   172 
   173 
   173 	for (hca_ndx = 0; hca_ndx < hca_cnt; hca_ndx++) {
   174 	for (hca_ndx = 0; hca_ndx < hca_cnt; hca_ndx++) {
   174 		SRPT_DPRINTF_L2("ioc_attach, adding I/O"
   175 		SRPT_DPRINTF_L2("ioc_attach, attaching HCA %016llx",
   175 		    " Controller (%016llx)", (u_longlong_t)guid[hca_ndx]);
   176 		    (u_longlong_t)guid[hca_ndx]);
   176 
   177 		srpt_ioc_attach_hca(guid[hca_ndx], B_FALSE);
   177 		ioc = srpt_ioc_init(guid[hca_ndx]);
       
   178 		if (ioc == NULL) {
       
   179 			SRPT_DPRINTF_L1("ioc_attach, ioc_init GUID(%016llx)"
       
   180 			    " failed", (u_longlong_t)guid[hca_ndx]);
       
   181 			continue;
       
   182 		}
       
   183 		list_insert_tail(&srpt_ctxt->sc_ioc_list, ioc);
       
   184 		SRPT_DPRINTF_L2("ioc_attach, I/O Controller ibt HCA hdl (%p)",
       
   185 		    (void *)ioc->ioc_ibt_hdl);
       
   186 		srpt_ctxt->sc_num_iocs++;
       
   187 	}
   178 	}
   188 
   179 
   189 	ibt_free_hca_list(guid, hca_cnt);
   180 	ibt_free_hca_list(guid, hca_cnt);
   190 	SRPT_DPRINTF_L3("ioc_attach, added %d I/O Controller(s)",
   181 	SRPT_DPRINTF_L3("ioc_attach, added %d I/O Controller(s)",
   191 	    srpt_ctxt->sc_num_iocs);
   182 	    srpt_ctxt->sc_num_iocs);
   192 	return (DDI_SUCCESS);
   183 	return (DDI_SUCCESS);
   193 }
   184 }
   194 
   185 
   195 /*
   186 /*
       
   187  * Initialize I/O Controllers.  sprt_ctxt->sc_rwlock must be locked by the
       
   188  * caller.
       
   189  *
       
   190  * 'checked' indicates no need to lookup the hca in the HCA configuration
       
   191  * list.
       
   192  */
       
   193 void
       
   194 srpt_ioc_attach_hca(ib_guid_t hca_guid, boolean_t checked)
       
   195 {
       
   196 	boolean_t	enable_hca = B_TRUE;
       
   197 	srpt_ioc_t	*ioc;
       
   198 
       
   199 	if (!checked) {
       
   200 		enable_hca = srpt_check_hca_cfg_enabled(hca_guid);
       
   201 
       
   202 		if (!enable_hca) {
       
   203 			/* nothing to do */
       
   204 			SRPT_DPRINTF_L2(
       
   205 			    "ioc_attach_hca, HCA %016llx disabled "
       
   206 			    "by srpt config",
       
   207 			    (u_longlong_t)hca_guid);
       
   208 			return;
       
   209 		}
       
   210 	}
       
   211 
       
   212 	SRPT_DPRINTF_L2("ioc_attach_hca, adding I/O"
       
   213 	    " Controller (%016llx)", (u_longlong_t)hca_guid);
       
   214 
       
   215 	ioc = srpt_ioc_init(hca_guid);
       
   216 	if (ioc == NULL) {
       
   217 		/*
       
   218 		 * IOC already exists or an error occurred.  Already
       
   219 		 * logged by srpt_ioc_init()
       
   220 		 */
       
   221 		return;
       
   222 	}
       
   223 
       
   224 	/*
       
   225 	 * Create the COMSTAR SRP Target for this IOC.  If this fails,
       
   226 	 * remove the IOC.
       
   227 	 */
       
   228 	rw_enter(&ioc->ioc_rwlock, RW_WRITER);
       
   229 	ioc->ioc_tgt_port = srpt_stp_alloc_port(ioc, ioc->ioc_guid);
       
   230 	if (ioc->ioc_tgt_port == NULL) {
       
   231 		SRPT_DPRINTF_L1("ioc_attach_hca: alloc SCSI"
       
   232 		    " Target Port error on GUID(%016llx)",
       
   233 		    (u_longlong_t)ioc->ioc_guid);
       
   234 		rw_exit(&ioc->ioc_rwlock);
       
   235 		srpt_ioc_fini(ioc);
       
   236 		return;
       
   237 	}
       
   238 	rw_exit(&ioc->ioc_rwlock);
       
   239 
       
   240 	/*
       
   241 	 * New HCA added with default SCSI Target Port, SRP service
       
   242 	 * will be started when SCSI Target Port is brought
       
   243 	 * on-line by STMF.
       
   244 	 */
       
   245 	list_insert_tail(&srpt_ctxt->sc_ioc_list, ioc);
       
   246 	SRPT_DPRINTF_L2("ioc_attach_hca, I/O Controller ibt HCA hdl (%p)",
       
   247 	    (void *)ioc->ioc_ibt_hdl);
       
   248 
       
   249 	srpt_ctxt->sc_num_iocs++;
       
   250 }
       
   251 
       
   252 /*
       
   253  * srpt_check_hca_cfg_enabled()
       
   254  *
       
   255  * Function to check the configuration for the enabled status of a given
       
   256  * HCA.  Returns B_TRUE if SRPT services should be activated for this HCA,
       
   257  * B_FALSE if it should be disabled.
       
   258  */
       
   259 static boolean_t
       
   260 srpt_check_hca_cfg_enabled(ib_guid_t hca_guid)
       
   261 {
       
   262 	int		status;
       
   263 	char		buf[32];
       
   264 	nvlist_t	*hcanv;
       
   265 	boolean_t	enable_hca;
       
   266 
       
   267 	enable_hca = srpt_enable_by_default;
       
   268 
       
   269 	SRPT_FORMAT_HCAKEY(buf, sizeof (buf), (u_longlong_t)hca_guid);
       
   270 
       
   271 	if (srpt_ctxt->sc_cfg_hca_nv != NULL) {
       
   272 		status = nvlist_lookup_nvlist(srpt_ctxt->sc_cfg_hca_nv,
       
   273 		    buf, &hcanv);
       
   274 		if (status == 0) {
       
   275 			SRPT_DPRINTF_L3("check_hca_cfg, found guid %s",  buf);
       
   276 			(void) nvlist_lookup_boolean_value(hcanv,
       
   277 			    SRPT_PROP_ENABLED, &enable_hca);
       
   278 		} else {
       
   279 			SRPT_DPRINTF_L3("check_hca_cfg, did not find guid %s",
       
   280 			    buf);
       
   281 		}
       
   282 	}
       
   283 
       
   284 	return (enable_hca);
       
   285 }
       
   286 
       
   287 /*
       
   288  * srpt_ioc_update()
       
   289  *
       
   290  * Using the configuration nvlist, enables or disables SRP services
       
   291  * the provided HCAs.  srpt_ctxt->sc_rwlock should be held outside of this call.
       
   292  */
       
   293 void
       
   294 srpt_ioc_update(void)
       
   295 {
       
   296 	boolean_t	enabled;
       
   297 	nvpair_t	*nvp = NULL;
       
   298 	uint64_t	hca_guid;
       
   299 	nvlist_t	*nvl;
       
   300 	nvlist_t	*cfg = srpt_ctxt->sc_cfg_hca_nv;
       
   301 
       
   302 	if (cfg == NULL) {
       
   303 		SRPT_DPRINTF_L2("ioc_update, no configuration data");
       
   304 		return;
       
   305 	}
       
   306 
       
   307 	while ((nvp = nvlist_next_nvpair(cfg, nvp)) != NULL) {
       
   308 		enabled = srpt_enable_by_default;
       
   309 
       
   310 		if ((nvpair_value_nvlist(nvp, &nvl)) != 0) {
       
   311 			SRPT_DPRINTF_L2("ioc_update, did not find an nvlist");
       
   312 			continue;
       
   313 		}
       
   314 
       
   315 		if ((nvlist_lookup_uint64(nvl, SRPT_PROP_GUID, &hca_guid))
       
   316 		    != 0) {
       
   317 			SRPT_DPRINTF_L2("ioc_update, did not find a guid");
       
   318 			continue;
       
   319 		}
       
   320 
       
   321 		(void) nvlist_lookup_boolean_value(nvl, SRPT_PROP_ENABLED,
       
   322 		    &enabled);
       
   323 
       
   324 		if (enabled) {
       
   325 			SRPT_DPRINTF_L2("ioc_update, enabling guid %016llx",
       
   326 			    (u_longlong_t)hca_guid);
       
   327 			srpt_ioc_attach_hca(hca_guid, B_TRUE);
       
   328 		} else {
       
   329 			SRPT_DPRINTF_L2("ioc_update, disabling guid %016llx",
       
   330 			    (u_longlong_t)hca_guid);
       
   331 			srpt_ioc_detach_hca(hca_guid);
       
   332 		}
       
   333 	}
       
   334 }
       
   335 
       
   336 /*
   196  * srpt_ioc_detach() - I/O Controller detach
   337  * srpt_ioc_detach() - I/O Controller detach
   197  *
   338  *
   198  * srpt_ctxt->sc_rwlock should be held outside of this call.
   339  * srpt_ctxt->sc_rwlock should be held outside of this call.
   199  */
   340  */
   200 void
   341 void
   201 srpt_ioc_detach()
   342 srpt_ioc_detach()
   202 {
   343 {
   203 	srpt_ioc_t	*ioc;
   344 	srpt_ioc_t	*ioc;
   204 
   345 
   205 	ASSERT(srpt_ctxt != NULL);
   346 	/*
   206 
   347 	 * All SRP targets must be destroyed before calling this
       
   348 	 * function.
       
   349 	 */
   207 	while ((ioc = list_head(&srpt_ctxt->sc_ioc_list)) != NULL) {
   350 	while ((ioc = list_head(&srpt_ctxt->sc_ioc_list)) != NULL) {
   208 		list_remove(&srpt_ctxt->sc_ioc_list, ioc);
       
   209 		SRPT_DPRINTF_L2("ioc_detach, removing I/O Controller(%p)"
   351 		SRPT_DPRINTF_L2("ioc_detach, removing I/O Controller(%p)"
   210 		    " (%016llx), ibt_hdl(%p)",
   352 		    " (%016llx), ibt_hdl(%p)",
   211 		    (void *)ioc,
   353 		    (void *)ioc,
   212 		    ioc ? (u_longlong_t)ioc->ioc_guid : 0x0ll,
   354 		    ioc ? (u_longlong_t)ioc->ioc_guid : 0x0ll,
   213 		    (void *)ioc->ioc_ibt_hdl);
   355 		    (void *)ioc->ioc_ibt_hdl);
       
   356 
       
   357 		list_remove(&srpt_ctxt->sc_ioc_list, ioc);
       
   358 		ASSERT(ioc->ioc_tgt_port != NULL);
   214 		srpt_ioc_fini(ioc);
   359 		srpt_ioc_fini(ioc);
   215 	}
   360 		srpt_ctxt->sc_num_iocs--;
   216 
   361 	}
   217 	(void) ibt_detach(srpt_ctxt->sc_ibt_hdl);
   362 
   218 	srpt_ctxt->sc_ibt_hdl = NULL;
   363 	srpt_ctxt->sc_ibt_hdl = NULL;
       
   364 }
       
   365 
       
   366 /*
       
   367  * srpt_ioc_detach_hca()
       
   368  *
       
   369  * Stop SRP Target services on this HCA
       
   370  *
       
   371  * Note that this is not entirely synchronous with srpt_ioc_attach_hca()
       
   372  * in that we don't need to check the configuration to know whether to
       
   373  * disable an HCA.  We get here either because the IB framework has told
       
   374  * us the HCA has been detached, or because the administrator has explicitly
       
   375  * disabled this HCA.
       
   376  *
       
   377  * Must be called with srpt_ctxt->sc_rwlock locked as RW_WRITER.
       
   378  */
       
   379 void
       
   380 srpt_ioc_detach_hca(ib_guid_t hca_guid)
       
   381 {
       
   382 	srpt_ioc_t		*ioc;
       
   383 	srpt_target_port_t	*tgt;
       
   384 	stmf_status_t		stmf_status = STMF_SUCCESS;
       
   385 
       
   386 	ioc = srpt_ioc_get_locked(hca_guid);
       
   387 	if (ioc == NULL) {
       
   388 		/* doesn't exist, nothing to do */
       
   389 		return;
       
   390 	}
       
   391 
       
   392 	rw_enter(&ioc->ioc_rwlock, RW_WRITER);
       
   393 	tgt = ioc->ioc_tgt_port;
       
   394 
       
   395 	if (tgt != NULL) {
       
   396 		stmf_status = srpt_stp_destroy_port(tgt);
       
   397 		if (stmf_status == STMF_SUCCESS) {
       
   398 			ioc->ioc_tgt_port = NULL;
       
   399 			(void) srpt_stp_free_port(tgt);
       
   400 		}
       
   401 	}
       
   402 
       
   403 	rw_exit(&ioc->ioc_rwlock);
       
   404 
       
   405 	if (stmf_status != STMF_SUCCESS) {
       
   406 		/* should never happen */
       
   407 		return;
       
   408 	}
       
   409 
       
   410 	list_remove(&srpt_ctxt->sc_ioc_list, ioc);
       
   411 	srpt_ctxt->sc_num_iocs--;
       
   412 
       
   413 	srpt_ioc_fini(ioc);
       
   414 	SRPT_DPRINTF_L2("ioc_detach_hca, HCA %016llx detached",
       
   415 	    (u_longlong_t)hca_guid);
   219 }
   416 }
   220 
   417 
   221 /*
   418 /*
   222  * srpt_ioc_init() - I/O Controller initialization
   419  * srpt_ioc_init() - I/O Controller initialization
   223  *
   420  *
   246 		return (NULL);
   443 		return (NULL);
   247 	}
   444 	}
   248 
   445 
   249 	ioc = srpt_ioc_get_locked(guid);
   446 	ioc = srpt_ioc_get_locked(guid);
   250 	if (ioc != NULL) {
   447 	if (ioc != NULL) {
   251 		SRPT_DPRINTF_L1("ioc_init, HCA already exists");
   448 		SRPT_DPRINTF_L2("ioc_init, HCA already exists");
   252 		return (NULL);
   449 		return (NULL);
   253 	}
   450 	}
   254 
   451 
   255 	ioc = kmem_zalloc(sizeof (srpt_ioc_t), KM_SLEEP);
   452 	ioc = kmem_zalloc(sizeof (srpt_ioc_t), KM_SLEEP);
   256 
   453 
   699 /* ARGSUSED */
   896 /* ARGSUSED */
   700 void
   897 void
   701 srpt_ioc_ib_async_hdlr(void *clnt, ibt_hca_hdl_t hdl,
   898 srpt_ioc_ib_async_hdlr(void *clnt, ibt_hca_hdl_t hdl,
   702 	ibt_async_code_t code, ibt_async_event_t *event)
   899 	ibt_async_code_t code, ibt_async_event_t *event)
   703 {
   900 {
   704 	srpt_ioc_t		*ioc;
       
   705 	srpt_channel_t		*ch;
   901 	srpt_channel_t		*ch;
   706 
   902 
   707 	switch (code) {
   903 	switch (code) {
   708 	case IBT_EVENT_PORT_UP:
   904 	case IBT_EVENT_PORT_UP:
   709 		srpt_ioc_port_active(event);
   905 		srpt_ioc_port_active(event);
   712 	case IBT_ERROR_PORT_DOWN:
   908 	case IBT_ERROR_PORT_DOWN:
   713 		srpt_ioc_port_down(event);
   909 		srpt_ioc_port_down(event);
   714 		break;
   910 		break;
   715 
   911 
   716 	case IBT_HCA_ATTACH_EVENT:
   912 	case IBT_HCA_ATTACH_EVENT:
       
   913 		SRPT_DPRINTF_L2(
       
   914 		    "ib_async_hdlr, received attach event for HCA 0x%016llx",
       
   915 		    (u_longlong_t)event->ev_hca_guid);
       
   916 
   717 		rw_enter(&srpt_ctxt->sc_rwlock, RW_WRITER);
   917 		rw_enter(&srpt_ctxt->sc_rwlock, RW_WRITER);
   718 		ioc = srpt_ioc_init(event->ev_hca_guid);
   918 		srpt_ioc_attach_hca(event->ev_hca_guid, B_FALSE);
   719 
       
   720 		if (ioc == NULL) {
       
   721 			rw_exit(&srpt_ctxt->sc_rwlock);
       
   722 			SRPT_DPRINTF_L1("ib_async_hdlr, HCA_ATTACH"
       
   723 			    " event failed to initialize HCA (0x%016llx)",
       
   724 			    (u_longlong_t)event->ev_hca_guid);
       
   725 			return;
       
   726 		}
       
   727 		SRPT_DPRINTF_L2("HCA_ATTACH_EVENT: I/O Controller"
       
   728 		    " ibt hdl (%p)",
       
   729 		    (void *)ioc->ioc_ibt_hdl);
       
   730 
       
   731 		rw_enter(&ioc->ioc_rwlock, RW_WRITER);
       
   732 		ioc->ioc_tgt_port = srpt_stp_alloc_port(ioc, ioc->ioc_guid);
       
   733 		if (ioc->ioc_tgt_port == NULL) {
       
   734 			SRPT_DPRINTF_L1("ioc_ib_async_hdlr, alloc SCSI "
       
   735 			    "target port error for HCA (0x%016llx)",
       
   736 			    (u_longlong_t)event->ev_hca_guid);
       
   737 			rw_exit(&ioc->ioc_rwlock);
       
   738 			srpt_ioc_fini(ioc);
       
   739 			rw_exit(&srpt_ctxt->sc_rwlock);
       
   740 			return;
       
   741 		}
       
   742 
       
   743 		/*
       
   744 		 * New HCA added with default SCSI Target Port, SRP service
       
   745 		 * will be started when SCSI Target Port is brought
       
   746 		 * on-line by STMF.
       
   747 		 */
       
   748 		srpt_ctxt->sc_num_iocs++;
       
   749 		list_insert_tail(&srpt_ctxt->sc_ioc_list, ioc);
       
   750 
       
   751 		rw_exit(&ioc->ioc_rwlock);
       
   752 		rw_exit(&srpt_ctxt->sc_rwlock);
   919 		rw_exit(&srpt_ctxt->sc_rwlock);
       
   920 
   753 		break;
   921 		break;
   754 
   922 
   755 	case IBT_HCA_DETACH_EVENT:
   923 	case IBT_HCA_DETACH_EVENT:
   756 		SRPT_DPRINTF_L1(
   924 		SRPT_DPRINTF_L1(
   757 		    "ioc_iob_async_hdlr, HCA_DETACH_EVENT received.");
   925 		    "ioc_iob_async_hdlr, received HCA_DETACH_EVENT for "
       
   926 		    "HCA 0x%016llx",
       
   927 		    (u_longlong_t)event->ev_hca_guid);
       
   928 
       
   929 		rw_enter(&srpt_ctxt->sc_rwlock, RW_WRITER);
       
   930 		srpt_ioc_detach_hca(event->ev_hca_guid);
       
   931 		rw_exit(&srpt_ctxt->sc_rwlock);
       
   932 
   758 		break;
   933 		break;
   759 
   934 
   760 	case IBT_EVENT_EMPTY_CHAN:
   935 	case IBT_EVENT_EMPTY_CHAN:
   761 		/* Channel in ERROR state is now empty */
   936 		/* Channel in ERROR state is now empty */
   762 		ch = (srpt_channel_t *)ibt_get_chan_private(event->ev_chan_hdl);
   937 		ch = (srpt_channel_t *)ibt_get_chan_private(event->ev_chan_hdl);
  1443 {
  1618 {
  1444 	ibt_status_t		status;
  1619 	ibt_status_t		status;
  1445 
  1620 
  1446 	status = ibt_deregister_mr(ioc->ioc_ibt_hdl, mr->mr_hdl);
  1621 	status = ibt_deregister_mr(ioc->ioc_ibt_hdl, mr->mr_hdl);
  1447 	if (status != IBT_SUCCESS) {
  1622 	if (status != IBT_SUCCESS) {
  1448 		SRPT_DPRINTF_L1("ioc_fini, error deregistering MR (%d)",
  1623 		SRPT_DPRINTF_L1("srpt_dereg_mem, error deregistering MR (%d)",
  1449 		    status);
  1624 		    status);
  1450 	}
  1625 	}
  1451 	kmem_free(mr, sizeof (srpt_mr_t));
  1626 	kmem_free(mr, sizeof (srpt_mr_t));
  1452 }
  1627 }
  1453 
  1628