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 * |
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); |