Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ocs_domain.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2015, Emulex
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 /**
34  * @file
35  * Handles the domain object callback from the HAL.
36  */
37 
38 /*!
39 @defgroup domain_sm Domain State Machine: States
40 */
41 
42 #include "ocs.h"
43 
44 #include "ocs_fabric.h"
45 #include "ocs_device.h"
46 #include "spv.h"
47 
48 #define domain_sm_trace(domain) \
49  do { \
50  if (OCS_LOG_ENABLE_DOMAIN_SM_TRACE(domain->ocs)) \
51  ocs_log_info(domain->ocs, "[domain] %-20s %-20s\n", __func__, ocs_sm_event_name(evt)); \
52  } while (0)
53 
54 #define domain_trace(domain, fmt, ...) \
55  do { \
56  if (OCS_LOG_ENABLE_DOMAIN_SM_TRACE(domain ? domain->ocs : NULL)) \
57  ocs_log_info(domain ? domain->ocs : NULL, fmt, ##__VA_ARGS__); \
58  } while (0)
59 
60 #define domain_printf(domain, fmt, ...) \
61  do { \
62  ocs_log_info(domain ? domain->ocs : NULL, fmt, ##__VA_ARGS__); \
63  } while (0)
64 
65 void ocs_mgmt_domain_list(ocs_textbuf_t *textbuf, void *domain);
66 void ocs_mgmt_domain_get_all(ocs_textbuf_t *textbuf, void *domain);
67 int ocs_mgmt_domain_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *domain);
68 int ocs_mgmt_domain_set(char *parent, char *name, char *value, void *domain);
69 int ocs_mgmt_domain_exec(char *parent, char *action, void *arg_in, uint32_t arg_in_length,
70  void *arg_out, uint32_t arg_out_length, void *object);
71 
74  .get_handler = ocs_mgmt_domain_get,
75  .get_all_handler = ocs_mgmt_domain_get_all,
76  .set_handler = ocs_mgmt_domain_set,
77  .exec_handler = ocs_mgmt_domain_exec,
78 };
79 
80 /**
81  * @brief Accept domain callback events from the HAL.
82  *
83  * <h3 class="desc">Description</h3>
84  * HAL calls this function with various domain-related events.
85  *
86  * @param arg Application-specified argument.
87  * @param event Domain event.
88  * @param data Event specific data.
89  *
90  * @return Returns 0 on success; or a negative error value on failure.
91  */
92 
93 int32_t
94 ocs_domain_cb(void *arg, ocs_hal_domain_event_e event, void *data)
95 {
96  ocs_t *ocs = arg;
97  ocs_domain_t *domain = NULL;
98  int32_t rc = 0;
99 
100  ocs_assert(data, -1);
101 
102  if (event != OCS_HAL_DOMAIN_FOUND) {
103  domain = data;
104  }
105 
106  switch (event) {
107  case OCS_HAL_DOMAIN_FOUND: {
108  uint64_t fcf_wwn = 0;
109  ocs_domain_record_t *drec = data;
110  ocs_assert(drec, -1);
111 
112  /* extract the fcf_wwn */
113  fcf_wwn = ocs_be64toh(*((uint64_t*)drec->wwn));
114 
115  /* lookup domain, or allocate a new one if one doesn't exist already */
116  domain = ocs_domain_find(ocs, fcf_wwn);
117  if (domain == NULL) {
118  domain = ocs_domain_alloc(ocs, fcf_wwn);
119  if (domain == NULL) {
120  ocs_log_err(ocs, "ocs_domain_alloc() failed\n");
121  rc = -1;
122  break;
123  }
124  ocs_sm_transition(&domain->drvsm, __ocs_domain_init, NULL);
125  }
127  break;
128  }
129 
130  case OCS_HAL_DOMAIN_LOST:
131  domain_trace(domain, "OCS_HAL_DOMAIN_LOST:\n");
132  ocs_domain_hold_frames(domain);
134  break;
135 
137  domain_trace(domain, "OCS_HAL_DOMAIN_ALLOC_OK:\n");
138  domain->instance_index = 0;
140  break;
141  }
142 
144  domain_trace(domain, "OCS_HAL_DOMAIN_ALLOC_FAIL:\n");
146  break;
147 
149  domain_trace(domain, "OCS_HAL_DOMAIN_ATTACH_OK:\n");
151  break;
152 
154  domain_trace(domain, "OCS_HAL_DOMAIN_ATTACH_FAIL:\n");
156  break;
157 
159  domain_trace(domain, "OCS_HAL_DOMAIN_FREE_OK:\n");
161  break;
162 
164  domain_trace(domain, "OCS_HAL_DOMAIN_FREE_FAIL:\n");
166  break;
167 
168  default:
169  ocs_log_warn(ocs, "unsupported event %#x\n", event);
170  }
171 
172  return rc;
173 }
174 
175 
176 /**
177  * @brief Find the domain, given its FCF_WWN.
178  *
179  * <h3 class="desc">Description</h3>
180  * Search the domain_list to find a matching domain object.
181  *
182  * @param ocs Pointer to the OCS device.
183  * @param fcf_wwn FCF WWN to find.
184  *
185  * @return Returns the pointer to the domain if found; or NULL otherwise.
186  */
187 
188 ocs_domain_t *
189 ocs_domain_find(ocs_t *ocs, uint64_t fcf_wwn)
190 {
191  ocs_domain_t *domain = NULL;
192 
193  /* Check to see if this domain is already allocated */
194  ocs_device_lock(ocs);
195  ocs_list_foreach(&ocs->domain_list, domain) {
196  if (fcf_wwn == domain->fcf_wwn) {
197  break;
198  }
199  }
200  ocs_device_unlock(ocs);
201  return domain;
202 }
203 
204 /**
205  * @brief Allocate a domain object.
206  *
207  * <h3 class="desc">Description</h3>
208  * A domain object is allocated and initialized. It is associated with the
209  * \c ocs argument.
210  *
211  * @param ocs Pointer to the OCS device.
212  * @param fcf_wwn FCF WWN of the domain.
213  *
214  * @return Returns a pointer to the ocs_domain_t object; or NULL.
215  */
216 
217 ocs_domain_t *
218 ocs_domain_alloc(ocs_t *ocs, uint64_t fcf_wwn)
219 {
220  ocs_domain_t *domain;
221 
222  ocs_assert(ocs, NULL);
223 
224  domain = ocs_malloc(ocs, sizeof(*domain), OCS_M_NOWAIT | OCS_M_ZERO);
225  if (domain) {
226 
227  domain->ocs = ocs;
228  domain->instance_index = ocs->domain_instance_count++;
229  domain->drvsm.app = domain;
230  ocs_rlock_init(ocs, &domain->drvsm_lock, "Domain SM lock");
231  ocs_domain_lock_init(domain);
232  ocs_lock_init(ocs, &domain->lookup_lock, "Domain lookup[%d]", domain->instance_index);
233 
234  /* Allocate a sparse vector for sport FC_ID's */
235  domain->lookup = spv_new(ocs);
236  if (domain->lookup == NULL) {
237  ocs_log_err(ocs, "spv_new() failed\n");
238  ocs_free(ocs, domain, sizeof(*domain));
239  return NULL;
240  }
241 
242  ocs_list_init(&domain->sport_list, ocs_sport_t, link);
243  domain->fcf_wwn = fcf_wwn;
244  ocs_log_debug(ocs, "Domain allocated: wwn %016" PRIX64 "\n", domain->fcf_wwn);
245  domain->femul_enable = (ocs->ctrlmask & OCS_CTRLMASK_ENABLE_FABRIC_EMULATION) != 0;
246 #if defined(ENABLE_FABRIC_EMULATION)
247  domain->ocs_ns = ocs_ns_attach(domain, OCS_NS_MAX_RECORDS);
248 #endif
249 
250  ocs_device_lock(ocs);
251  /* if this is the first domain, then assign it as the "root" domain */
252  if (ocs_list_empty(&ocs->domain_list)) {
253  ocs->domain = domain;
254  }
255  ocs_list_add_tail(&ocs->domain_list, domain);
256  ocs_device_unlock(ocs);
257 
258  domain->mgmt_functions = &domain_mgmt_functions;
259  } else {
260  ocs_log_err(ocs, "domain allocation failed\n");
261  }
262 
263 
264  return domain;
265 }
266 
267 /**
268  * @brief Free a domain object.
269  *
270  * <h3 class="desc">Description</h3>
271  * The domain object is freed.
272  *
273  * @param domain Domain object to free.
274  *
275  * @return None.
276  */
277 
278 void
279 ocs_domain_free(ocs_domain_t *domain)
280 {
281  ocs_t *ocs;
282 
283  ocs_assert(domain);
284  ocs_assert(domain->ocs);
285 
286  /* Hold frames to clear the domain pointer from the xport lookup */
287  ocs_domain_hold_frames(domain);
288 
289  ocs = domain->ocs;
290 
291  ocs_log_debug(ocs, "Domain free: wwn %016" PRIX64 "\n", domain->fcf_wwn);
292 
293  spv_del(domain->lookup);
294  domain->lookup = NULL;
295 
296  ocs_device_lock(ocs);
297  ocs_list_remove(&ocs->domain_list, domain);
298  if (domain == ocs->domain) {
299  /* set global domain to the new head */
300  ocs->domain = ocs_list_get_head(&ocs->domain_list);
301  if (ocs->domain) {
302  ocs_log_debug(ocs, "setting new domain, old=%p new=%p\n",
303  domain, ocs->domain);
304  }
305  }
306  ocs_device_unlock(ocs);
307 
308  ocs_lock(&ocs->domain_list_empty_cb_lock);
309  if (ocs->domain_list_empty_cb && ocs_list_empty(&ocs->domain_list)) {
310  ocs_log_info(ocs, "Domain list is empty. Release domain shutdown\n");
311  (*ocs->domain_list_empty_cb)(ocs, ocs->domain_list_empty_cb_arg);
312  }
313  ocs_unlock(&ocs->domain_list_empty_cb_lock);
314 
315  ocs_rlock_free(&domain->drvsm_lock);
316  ocs_lock_free(&domain->lookup_lock);
317 
318 #if defined(ENABLE_FABRIC_EMULATION)
319  /* Free name services database */
320  ocs_ns_detach(domain->ocs_ns);
321 
322  /* Shutdown fabric emulation */
323  ocs_femul_shutdown(domain);
324 #endif
325 
326  ocs_free(ocs, domain, sizeof(*domain));
327 }
328 
329 /**
330  * @brief Free memory resources of a domain object.
331  *
332  * <h3 class="desc">Description</h3>
333  * After the domain object is freed, its child objects are also freed.
334  *
335  * @param domain Pointer to a domain object.
336  *
337  * @return None.
338  */
339 
340 void
341 ocs_domain_force_free(ocs_domain_t *domain)
342 {
343  ocs_sport_t *sport;
344  ocs_sport_t *next;
345 
346  /* Shutdown domain sm */
347  ocs_sm_disable(&domain->drvsm);
348 
350 
351  ocs_domain_lock(domain);
352  ocs_list_foreach_safe(&domain->sport_list, sport, next) {
353  ocs_sport_force_free(sport);
354  }
355  ocs_domain_unlock(domain);
356  ocs_hal_domain_force_free(&domain->ocs->hal, domain);
357  ocs_domain_free(domain);
358 }
359 
360 /**
361  * @brief Unregister a callback for the domain_list empty cb
362  *
363  * <h3 class="desc">Description</h3>
364  * A function callback may be unregistered when the domain_list goes empty.
365  *
366  * @param ocs Pointer to a device object.
367  *
368  * @return None.
369  */
371 {
372  ocs_lock(&ocs->domain_list_empty_cb_lock);
373  ocs->domain_list_empty_cb_arg = NULL;
374  ocs->domain_list_empty_cb = NULL;
375  ocs_unlock(&ocs->domain_list_empty_cb_lock);
376 }
377 
378 /**
379  * @brief Register a callback when the domain_list goes empty.
380  *
381  * <h3 class="desc">Description</h3>
382  * A function callback may be registered when the domain_list goes empty.
383  *
384  * @param ocs Pointer to a device object.
385  *
386  * @return None.
387  */
388 void
390 {
391  ocs_lock(&ocs->domain_list_empty_cb_lock);
392  if (ocs->domain_list_empty_cb == NULL) {
393  ocs_sem_init(&ocs->domain_list_empty_cb_sem, 0,
394  "domain_list_empty_cb_sem");
395  ocs->domain_list_empty_cb_arg = &ocs->domain_list_empty_cb_sem;
396  ocs->domain_list_empty_cb = ocs_xport_domain_list_empty_cb;
397  }
398  ocs_unlock(&ocs->domain_list_empty_cb_lock);
399 }
400 
401 /**
402  * @brief Return a pointer to the domain, given the instance index.
403  *
404  * <h3 class="desc">Description</h3>
405  * A pointer to the domain context, given by the index, is returned.
406  *
407  * @param ocs Pointer to the driver instance context.
408  * @param index Instance index.
409  *
410  * @return Returns a pointer to the domain; or NULL.
411  */
412 
413 ocs_domain_t *
414 ocs_domain_get_instance(ocs_t *ocs, uint32_t index)
415 {
416  ocs_domain_t *domain = NULL;
417 
418  if (index >= OCS_MAX_DOMAINS) {
419  ocs_log_err(ocs, "invalid index: %d\n", index);
420  return NULL;
421  }
422  ocs_device_lock(ocs);
423  ocs_list_foreach(&ocs->domain_list, domain) {
424  if (domain->instance_index == index) {
425  break;
426  }
427  }
428  ocs_device_unlock(ocs);
429  return domain;
430 }
431 
432 /**
433  * @ingroup domain_sm
434  * @brief Domain state machine: Common event handler.
435  *
436  * <h3 class="desc">Description</h3>
437  * Common/shared events are handled here for the domain state machine.
438  *
439  * @param funcname Function name text.
440  * @param ctx Domain state machine context.
441  * @param evt Event to process.
442  * @param arg Per event optional argument.
443  *
444  * @return Returns NULL.
445  */
446 
447 static void *
448 __ocs_domain_common(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
449 {
450  ocs_domain_t *domain = ctx->app;
451 
452  switch(evt) {
453  case OCS_EVT_ENTER:
454  case OCS_EVT_REENTER:
455  case OCS_EVT_EXIT:
457  /* this can arise if an FLOGI fails on the SPORT, and the SPORT is shutdown */
458  break;
459  default:
460  ocs_log_warn(domain->ocs, "%-20s %-20s not handled\n", funcname, ocs_sm_event_name(evt));
461  break;
462  }
463 
464  return NULL;
465 }
466 
467 /**
468  * @ingroup domain_sm
469  * @brief Domain state machine: Common shutdown.
470  *
471  * <h3 class="desc">Description</h3>
472  * Handles common shutdown events.
473  *
474  * @param funcname Function name text.
475  * @param ctx Remote node state machine context.
476  * @param evt Event to process.
477  * @param arg Per event optional argument.
478  *
479  * @return Returns NULL.
480  */
481 
482 static void *
483 __ocs_domain_common_shutdown(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
484 {
485  ocs_domain_t *domain = ctx->app;
486 
487  switch(evt) {
488  case OCS_EVT_ENTER:
489  case OCS_EVT_REENTER:
490  case OCS_EVT_EXIT:
491  break;
493  ocs_assert(arg, NULL);
494  //sm: / save drec, mark domain_found_pending
495  ocs_memcpy(&domain->pending_drec, arg, sizeof(domain->pending_drec));
496  domain->domain_found_pending = TRUE;
497  break;
498  case OCS_EVT_DOMAIN_LOST: // clear drec available
499  //sm: / unmark domain_found_pending
500  domain->domain_found_pending = FALSE;
501  break;
502 
503  default:
504  ocs_log_warn(domain->ocs, "%-20s %-20s not handled\n", funcname, ocs_sm_event_name(evt));
505  break;
506  }
507 
508  return NULL;
509 }
510 
511 #define std_domain_state_decl(...) \
512  ocs_domain_t *domain = NULL; \
513  ocs_t *ocs = NULL; \
514  \
515  ocs_assert(ctx, NULL); \
516  ocs_assert(ctx->app, NULL); \
517  domain = ctx->app; \
518  ocs_assert(domain->ocs, NULL); \
519  ocs = domain->ocs; \
520  ocs_assert(ocs->xport, NULL);
521 
522 /**
523  * @ingroup domain_sm
524  * @brief Domain state machine: Initial state.
525  *
526  * <h3 class="desc">Description</h3>
527  * The initial state for a domain. Each domain is initialized to
528  * this state at start of day (SOD).
529  *
530  * @param ctx Domain state machine context.
531  * @param evt Event to process.
532  * @param arg Per event optional argument.
533  *
534  * @return Returns NULL.
535  */
536 
537 void *
538 __ocs_domain_init(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
539 {
541 
542  domain_sm_trace(domain);
543 
544  switch(evt) {
545  case OCS_EVT_ENTER:
546  domain->attached = 0;
547  break;
548 
549  case OCS_EVT_DOMAIN_FOUND: {
550  int32_t vlan = 0;
551  uint32_t i;
552  ocs_domain_record_t *drec = arg;
553  ocs_sport_t *sport;
554 
555  uint64_t my_wwnn = ocs->xport->req_wwnn;
556  uint64_t my_wwpn = ocs->xport->req_wwpn;
557  uint64_t be_wwpn;
558 
559  /* For now, user must specify both port name and node name, or we let firmware
560  * pick both (same as for vports).
561  * TODO: do we want to allow setting only port name or only node name?
562  */
563  if ((my_wwpn == 0) || (my_wwnn == 0)) {
564  ocs_log_debug(ocs, "using default hardware WWN configuration \n");
565  my_wwpn = ocs_get_wwn(&ocs->hal, OCS_HAL_WWN_PORT);
566  my_wwnn = ocs_get_wwn(&ocs->hal, OCS_HAL_WWN_NODE);
567  }
568 
569  ocs_log_debug(ocs, "Creating base sport using WWPN %016" PRIx64 " WWNN %016" PRIx64 "\n",
570  my_wwpn, my_wwnn);
571 
572  /* Allocate a sport and transition to __ocs_sport_allocated */
573  sport = ocs_sport_alloc(domain, my_wwpn, my_wwnn, UINT32_MAX, ocs->enable_ini, ocs->enable_tgt);
574 
575  if (sport == NULL) {
576  ocs_log_err(ocs, "ocs_sport_alloc() failed\n");
577  break;
578  }
579  ocs_sm_transition(&sport->sm, __ocs_sport_allocated, NULL);
580 
581  /* If domain is ethernet, then fetch the vlan id value */
582  if (drec->is_ethernet) {
583  vlan = ocs_bitmap_search((void *)drec->map.vlan, TRUE, 512 * 8);
584  if (vlan < 0) {
585  ocs_log_err(ocs, "no VLAN id available (FCF=%d)\n",
586  drec->index);
587  break;
588  }
589  }
590 
591  be_wwpn = ocs_htobe64(sport->wwpn);
592 
593  /* allocate ocs_sli_port_t object for local port
594  * Note: drec->fc_id is ALPA from read_topology only if loop
595  */
596  if (ocs_hal_port_alloc(&ocs->hal, sport, NULL, (uint8_t *)&be_wwpn)) {
597  ocs_log_err(ocs, "Can't allocate port\n");
598  ocs_sport_free(sport);
599  break;
600  }
601 
602  /* initialize domain object */
603  domain->is_loop = drec->is_loop;
604  domain->is_fc = drec->is_fc;
605 
606  /*
607  * If the loop position map includes ALPA == 0, then we are in a public loop (NL_PORT)
608  * Note that the first element of the loopmap[] contains the count of elements, and if
609  * ALPA == 0 is present, it will occupy the first location after the count.
610  */
611  domain->is_nlport = drec->map.loop[1] == 0x00;
612 
613  if (domain->is_loop) {
614  ocs_log_debug(ocs, "%s fc_id=%#x speed=%d\n",
615  drec->is_loop ? (domain->is_nlport ? "public-loop" : "loop") : "other",
616  drec->fc_id, drec->speed);
617 
618  sport->fc_id = drec->fc_id;
619  sport->topology = OCS_SPORT_TOPOLOGY_LOOP;
620  ocs_snprintf(sport->display_name, sizeof(sport->display_name), "s%06x", drec->fc_id);
621 
622  if (ocs->enable_ini) {
623  uint32_t count = drec->map.loop[0];
624  ocs_log_debug(ocs, "%d position map entries\n", count);
625  for (i = 1; i <= count; i++) {
626  if (drec->map.loop[i] != drec->fc_id) {
627  ocs_node_t *node;
628 
629  ocs_log_debug(ocs, "%#x -> %#x\n",
630  drec->fc_id, drec->map.loop[i]);
631  node = ocs_node_alloc(sport, drec->map.loop[i], FALSE, TRUE);
632  if (node == NULL) {
633  ocs_log_err(ocs, "ocs_node_alloc() failed\n");
634  break;
635  }
637  }
638  }
639  }
640  }
641 
642  /* Initiate HAL domain alloc */
643  if (ocs_hal_domain_alloc(&ocs->hal, domain, drec->index, vlan)) {
644  ocs_log_err(ocs, "Failed to initiate HAL domain allocation\n");
645  break;
646  }
648  break;
649  }
650  default:
651  __ocs_domain_common(__func__, ctx, evt, arg);
652  return NULL;
653  }
654 
655  return NULL;
656 }
657 
658 /**
659  * @ingroup domain_sm
660  * @brief Domain state machine: Wait for the domain allocation to complete.
661  *
662  * <h3 class="desc">Description</h3>
663  * Waits for the domain state to be allocated. After the HAL domain
664  * allocation process has been initiated, this state waits for
665  * that process to complete (i.e. a domain-alloc-ok event).
666  *
667  * @param ctx Domain state machine context.
668  * @param evt Event to process.
669  * @param arg Per event optional argument.
670  *
671  * @return Returns NULL.
672  */
673 
674 void *
675 __ocs_domain_wait_alloc(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
676 {
677  ocs_sport_t *sport;
679 
680  domain_sm_trace(domain);
681 
682  switch(evt) {
684  char prop_buf[32];
685  uint64_t wwn_bump = 0;
686  fc_plogi_payload_t *sp;
687 
688  if (ocs_get_property("wwn_bump", prop_buf, sizeof(prop_buf)) == 0) {
689  wwn_bump = ocs_strtoull(prop_buf, 0, 0);
690  }
691 
692  sport = domain->sport;
693  ocs_assert(sport, NULL);
694  sp = (fc_plogi_payload_t*) sport->service_params;
695 
696  /* Save the domain service parameters */
697  ocs_memcpy(domain->service_params + 4, domain->dma.virt, sizeof(fc_plogi_payload_t) - 4);
698  ocs_memcpy(sport->service_params + 4, domain->dma.virt, sizeof(fc_plogi_payload_t) - 4);
699 
700  /* If we're in fabric emulation mode, the flogi service parameters have not been setup yet,
701  * so we need some reasonable BB credit value
702  */
703  if (domain->femul_enable) {
704  ocs_memcpy(domain->flogi_service_params + 4, domain->service_params + 4, sizeof(fc_plogi_payload_t) - 4);
705  }
706 
707  /* Update the sport's service parameters, user might have specified non-default names */
708  sp->port_name_hi = ocs_htobe32((uint32_t) (sport->wwpn >> 32ll));
709  sp->port_name_lo = ocs_htobe32((uint32_t) sport->wwpn);
710  sp->node_name_hi = ocs_htobe32((uint32_t) (sport->wwnn >> 32ll));
711  sp->node_name_lo = ocs_htobe32((uint32_t) sport->wwnn);
712 
713  if (wwn_bump) {
714  sp->port_name_lo = ocs_htobe32(ocs_be32toh(sp->port_name_lo) ^ ((uint32_t)(wwn_bump)));
715  sp->port_name_hi = ocs_htobe32(ocs_be32toh(sp->port_name_hi) ^ ((uint32_t)(wwn_bump >> 32)));
716  sp->node_name_lo = ocs_htobe32(ocs_be32toh(sp->node_name_lo) ^ ((uint32_t)(wwn_bump)));
717  sp->node_name_hi = ocs_htobe32(ocs_be32toh(sp->node_name_hi) ^ ((uint32_t)(wwn_bump >> 32)));
718  ocs_log_info(ocs, "Overriding WWN\n");
719  }
720 
721  /* Take the loop topology path, unless we are an NL_PORT (public loop) */
722  if (domain->is_loop && !domain->is_nlport) {
723  /*
724  * For loop, we already have our FC ID and don't need fabric login.
725  * Transition to the allocated state and post an event to attach to
726  * the domain. Note that this breaks the normal action/transition
727  * pattern here to avoid a race with the domain attach callback.
728  */
729  //sm: is_loop / domain_attach
731  __ocs_domain_attach_internal(domain, sport->fc_id);
732  break;
733  } else {
734  ocs_node_t *node;
735 
736 #if defined(ENABLE_FABRIC_EMULATION)
737  /* If we are running in Fabric Emulation Mode, then initialize */
738  if (domain->femul_enable) {
739  ocs_log_info(ocs, "Starting Fabric Emulation operation\n");
740 
741  ocs_femul_init(domain);
742 
744 
745  /* Accept frames */
746  domain->req_accept_frames = 1;
747  break;
748  }
749 #endif
750 
751  /* alloc fabric node, send FLOGI */
752  node = ocs_node_find(sport, FC_ADDR_FABRIC);
753  if (node) {
754  ocs_log_err(ocs, "Hmmmm ... Fabric Controller node already exists\n");
755  break;
756  }
757  node = ocs_node_alloc(sport, FC_ADDR_FABRIC, FALSE, FALSE);
758  if (!node) {
759  ocs_log_err(ocs, "Error: ocs_node_alloc() failed\n");
760  } else {
761  if (ocs->nodedb_mask & OCS_NODEDB_PAUSE_FABRIC_LOGIN) {
763  } else {
765  }
766  }
767  /* Accept frames */
768  domain->req_accept_frames = 1;
769  }
770  //sm: / start fabric logins
772  break;
773  }
774 
776  // TODO: hal/device reset
777  ocs_log_err(ocs, "%s recv'd waiting for DOMAIN_ALLOC_OK; shutting down domain\n",
778  ocs_sm_event_name(evt));
779  domain->req_domain_free = 1;
780  break;
781 
783  /* Should not happen */
784  ocs_assert(evt, NULL);
785  break;
786 
787  case OCS_EVT_DOMAIN_LOST:
788  ocs_log_debug(ocs, "%s received while waiting for ocs_hal_domain_alloc() to complete\n", ocs_sm_event_name(evt));
790  break;
791 
792  default:
793  __ocs_domain_common(__func__, ctx, evt, arg);
794  return NULL;
795  }
796 
797  return NULL;
798 }
799 
800 /**
801  * @ingroup domain_sm
802  * @brief Domain state machine: Wait for the domain attach request.
803  *
804  * <h3 class="desc">Description</h3>
805  * In this state, the domain has been allocated and is waiting for a domain attach request.
806  * The attach request comes from a node instance completing the fabric login,
807  * or from a point-to-point negotiation and login.
808  *
809  * @param ctx Remote node state machine context.
810  * @param evt Event to process.
811  * @param arg Per event optional argument.
812  *
813  * @return Returns NULL.
814  */
815 
816 void *
817 __ocs_domain_allocated(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
818 {
819  int32_t rc = 0;
821 
822  domain_sm_trace(domain);
823 
824  switch(evt) {
826  uint32_t fc_id;
827 
828  ocs_assert(arg, NULL);
829 
830  fc_id = *((uint32_t*)arg);
831  ocs_log_debug(ocs, "Requesting hal domain attach fc_id x%x\n", fc_id);
832  /* Update sport lookup */
833  ocs_lock(&domain->lookup_lock);
834  spv_set(domain->lookup, fc_id, domain->sport);
835  ocs_unlock(&domain->lookup_lock);
836 
837  /* Update display name for the sport */
838  ocs_node_fcid_display(fc_id, domain->sport->display_name, sizeof(domain->sport->display_name));
839 
840  /* Issue domain attach call */
841  rc = ocs_hal_domain_attach(&ocs->hal, domain, fc_id);
842  if (rc) {
843  ocs_log_err(ocs, "ocs_hal_domain_attach failed: %d\n", rc);
844  return NULL;
845  }
846  //sm: / domain_attach
848  break;
849  }
850 
852  /* Should not happen */
853  ocs_assert(evt, NULL);
854  break;
855 
856  case OCS_EVT_DOMAIN_LOST: {
857  int32_t rc;
858  ocs_log_debug(ocs, "%s received while waiting for OCS_EVT_DOMAIN_REQ_ATTACH\n",
859  ocs_sm_event_name(evt));
860  ocs_domain_lock(domain);
861  if (!ocs_list_empty(&domain->sport_list)) {
862  /* if there are sports, transition to wait state and send
863  * shutdown to each sport */
864  ocs_sport_t *sport = NULL;
865  ocs_sport_t *sport_next = NULL;
867  ocs_list_foreach_safe(&domain->sport_list, sport, sport_next) {
868  ocs_sm_post_event(&sport->sm, OCS_EVT_SHUTDOWN, NULL);
869  }
870  ocs_domain_unlock(domain);
871  } else {
872  ocs_domain_unlock(domain);
873  /* no sports exist, free domain */
875  rc = ocs_hal_domain_free(&ocs->hal, domain);
876  if (rc) {
877  ocs_log_err(ocs, "ocs_hal_domain_free() failed: %d\n", rc);
878  //TODO: hal/device reset needed
879  }
880  }
881 
882  break;
883  }
884 
885  default:
886  __ocs_domain_common(__func__, ctx, evt, arg);
887  return NULL;
888  }
889 
890  return NULL;
891 }
892 
893 /**
894  * @ingroup domain_sm
895  * @brief Domain state machine: Wait for the HAL domain attach to complete.
896  *
897  * <h3 class="desc">Description</h3>
898  * Waits for the HAL domain attach to complete. Forwards attach ok event to the
899  * fabric node state machine.
900  *
901  * @param ctx Remote node state machine context.
902  * @param evt Event to process.
903  * @param arg Per event optional argument.
904  *
905  * @return Returns NULL.
906  */
907 
908 void *
909 __ocs_domain_wait_attach(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
910 {
912 
913  domain_sm_trace(domain);
914 
915  switch(evt) {
917  ocs_node_t *node = NULL;
918  ocs_node_t *next_node = NULL;
919  ocs_sport_t *sport;
920  ocs_sport_t *next_sport;
921 
922  /* Set domain notify pending state to avoid duplicate domain event post */
923  domain->domain_notify_pend = 1;
924 
925  /* Mark as attached */
926  domain->attached = 1;
927 
928  /* Register with SCSI API */
929  if (ocs->enable_tgt)
930  ocs_scsi_tgt_new_domain(domain);
931  if (ocs->enable_ini)
932  ocs_scsi_ini_new_domain(domain);
933 
934  /* Transition to ready */
935  //sm: / forward event to all sports and nodes
937 
938  /* We have an FCFI, so we can accept frames */
939  domain->req_accept_frames = 1;
940 
941  /* Notify all nodes that the domain attach request has completed
942  * Note: sport will have already received notification of sport attached
943  * as a result of the HAL's port attach.
944  */
945  ocs_domain_lock(domain);
946  ocs_list_foreach_safe(&domain->sport_list, sport, next_sport) {
947  ocs_sport_lock(sport);
948  ocs_list_foreach_safe(&sport->node_list, node, next_node) {
950  }
951  ocs_sport_unlock(sport);
952  }
953  ocs_domain_unlock(domain);
954  domain->domain_notify_pend = 0;
955  break;
956  }
957 
959  ocs_log_debug(ocs, "%s received while waiting for hal attach to complete\n", ocs_sm_event_name(evt));
960  //TODO: hal/device reset
961  break;
962 
964  /* Should not happen */
965  ocs_assert(evt, NULL);
966  break;
967 
968  case OCS_EVT_DOMAIN_LOST:
969  /* Domain lost while waiting for an attach to complete, go to a state that waits for
970  * the domain attach to complete, then handle domain lost
971  */
973  break;
974 
976  /* In P2P we can get an attach request from the other FLOGI path, so drop this one */
977  break;
978 
979  default:
980  __ocs_domain_common(__func__, ctx, evt, arg);
981  return NULL;
982  }
983 
984  return NULL;
985 }
986 
987 /**
988  * @ingroup domain_sm
989  * @brief Domain state machine: Ready state.
990  *
991  * <h3 class="desc">Description</h3>
992  * This is a domain ready state. It waits for a domain-lost event, and initiates shutdown.
993  *
994  * @param ctx Remote node state machine context.
995  * @param evt Event to process.
996  * @param arg Per event optional argument.
997  *
998  * @return Returns NULL.
999  */
1000 
1001 void *
1002 __ocs_domain_ready(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
1003 {
1005 
1006  domain_sm_trace(domain);
1007 
1008  switch(evt) {
1009  case OCS_EVT_ENTER: {
1010 
1011  /* start any pending vports */
1012  if (ocs_vport_start(domain)) {
1013  ocs_log_debug(domain->ocs, "ocs_vport_start() did not start all vports\n");
1014  }
1015  break;
1016  }
1017  case OCS_EVT_DOMAIN_LOST: {
1018  int32_t rc;
1019  ocs_domain_lock(domain);
1020  if (!ocs_list_empty(&domain->sport_list)) {
1021  /* if there are sports, transition to wait state and send
1022  * shutdown to each sport */
1023  ocs_sport_t *sport = NULL;
1024  ocs_sport_t *sport_next = NULL;
1026  ocs_list_foreach_safe(&domain->sport_list, sport, sport_next) {
1027  ocs_sm_post_event(&sport->sm, OCS_EVT_SHUTDOWN, NULL);
1028  }
1029  ocs_domain_unlock(domain);
1030  } else {
1031  ocs_domain_unlock(domain);
1032  /* no sports exist, free domain */
1034  rc = ocs_hal_domain_free(&ocs->hal, domain);
1035  if (rc) {
1036  ocs_log_err(ocs, "ocs_hal_domain_free() failed: %d\n", rc);
1037  //TODO: hal/device reset needed
1038  }
1039  }
1040  break;
1041  }
1042 
1043  case OCS_EVT_DOMAIN_FOUND:
1044  /* Should not happen */
1045  ocs_assert(evt, NULL);
1046  break;
1047 
1049  /* can happen during p2p */
1050  uint32_t fc_id;
1051 
1052  ocs_assert(arg, NULL);
1053  fc_id = *((uint32_t*)arg);
1054 
1055  /* Assume that the domain is attached */
1056  ocs_assert(domain->attached, NULL);
1057 
1058  /* Verify that the requested FC_ID is the same as the one we're working with */
1059  ocs_assert(domain->sport->fc_id == fc_id, NULL);
1060  break;
1061  }
1062 
1063  default:
1064  __ocs_domain_common(__func__, ctx, evt, arg);
1065  return NULL;
1066  }
1067 
1068  return NULL;
1069 }
1070 
1071 /**
1072  * @ingroup domain_sm
1073  * @brief Domain state machine: Wait for nodes to free prior to the domain shutdown.
1074  *
1075  * <h3 class="desc">Description</h3>
1076  * All nodes are freed, and ready for a domain shutdown.
1077  *
1078  * @param ctx Remote node sm context.
1079  * @param evt Event to process.
1080  * @param arg Per event optional argument.
1081  *
1082  * @return Returns NULL.
1083  */
1084 
1085 void *
1086 __ocs_domain_wait_sports_free(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
1087 {
1089 
1090  domain_sm_trace(domain);
1091 
1092  switch(evt) {
1094  int32_t rc;
1095 
1096  //sm: / ocs_hal_domain_free
1098 
1099  /* Request ocs_hal_domain_free and wait for completion */
1100  rc = ocs_hal_domain_free(&ocs->hal, domain);
1101  if (rc) {
1102  ocs_log_err(ocs, "ocs_hal_domain_free() failed: %d\n", rc);
1103  }
1104  break;
1105  }
1106  default:
1107  __ocs_domain_common_shutdown(__func__, ctx, evt, arg);
1108  return NULL;
1109  }
1110 
1111  return NULL;
1112 }
1113 
1114 /**
1115  * @ingroup domain_sm
1116  * @brief Domain state machine: Complete the domain shutdown.
1117  *
1118  * <h3 class="desc">Description</h3>
1119  * Waits for a HAL domain free to complete.
1120  *
1121  * @param ctx Remote node state machine context.
1122  * @param evt Event to process.
1123  * @param arg Per event optional argument.
1124  *
1125  * @return Returns NULL.
1126  */
1127 
1128 void *
1129 __ocs_domain_wait_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
1130 {
1132 
1133  domain_sm_trace(domain);
1134 
1135  switch(evt) {
1136  case OCS_EVT_DOMAIN_FREE_OK: {
1137  if (ocs->enable_ini)
1138  ocs_scsi_ini_del_domain(domain);
1139  if (ocs->enable_tgt)
1140  ocs_scsi_tgt_del_domain(domain);
1141 
1142  //sm: / domain_free
1143  if (domain->domain_found_pending) {
1144  /* save fcf_wwn and drec from this domain, free current domain and allocate
1145  * a new one with the same fcf_wwn
1146  * TODO: could use a SLI-4 "re-register VPI" operation here
1147  */
1148  uint64_t fcf_wwn = domain->fcf_wwn;
1149  ocs_domain_record_t drec = domain->pending_drec;
1150 
1151  ocs_log_debug(ocs, "Reallocating domain\n");
1152  domain->req_domain_free = 1;
1153  domain = ocs_domain_alloc(ocs, fcf_wwn);
1154 
1155  if (domain == NULL) {
1156  ocs_log_err(ocs, "ocs_domain_alloc() failed\n");
1157  //TODO: hal/device reset needed
1158  return NULL;
1159  }
1160  /*
1161  * got a new domain; at this point, there are at least two domains
1162  * once the req_domain_free flag is processed, the associated domain
1163  * will be removed.
1164  */
1165  ocs_sm_transition(&domain->drvsm, __ocs_domain_init, NULL);
1166  ocs_sm_post_event(&domain->drvsm, OCS_EVT_DOMAIN_FOUND, &drec);
1167  } else {
1168  domain->req_domain_free = 1;
1169  }
1170  break;
1171  }
1172 
1173  default:
1174  __ocs_domain_common_shutdown(__func__, ctx, evt, arg);
1175  return NULL;
1176  }
1177 
1178  return NULL;
1179 }
1180 
1181 /**
1182  * @ingroup domain_sm
1183  * @brief Domain state machine: Wait for the domain alloc/attach completion
1184  * after receiving a domain lost.
1185  *
1186  * <h3 class="desc">Description</h3>
1187  * This state is entered when receiving a domain lost while waiting for a domain alloc
1188  * or a domain attach to complete.
1189  *
1190  * @param ctx Remote node state machine context.
1191  * @param evt Event to process.
1192  * @param arg Per event optional argument.
1193  *
1194  * @return Returns NULL.
1195  */
1196 
1197 void *
1198 __ocs_domain_wait_domain_lost(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
1199 {
1201 
1202  domain_sm_trace(domain);
1203 
1204  switch(evt) {
1206  case OCS_EVT_DOMAIN_ATTACH_OK: {
1207  int32_t rc;
1208  ocs_domain_lock(domain);
1209  if (!ocs_list_empty(&domain->sport_list)) {
1210  /* if there are sports, transition to wait state and send
1211  * shutdown to each sport */
1212  ocs_sport_t *sport = NULL;
1213  ocs_sport_t *sport_next = NULL;
1215  ocs_list_foreach_safe(&domain->sport_list, sport, sport_next) {
1216  ocs_sm_post_event(&sport->sm, OCS_EVT_SHUTDOWN, NULL);
1217  }
1218  ocs_domain_unlock(domain);
1219  } else {
1220  ocs_domain_unlock(domain);
1221  /* no sports exist, free domain */
1223  rc = ocs_hal_domain_free(&ocs->hal, domain);
1224  if (rc) {
1225  ocs_log_err(ocs, "ocs_hal_domain_free() failed: %d\n", rc);
1226  //TODO: hal/device reset needed
1227  }
1228  }
1229  break;
1230  }
1233  ocs_log_err(ocs, "[domain] %-20s: failed\n", ocs_sm_event_name(evt));
1234  //TODO: hal/device reset needed
1235  break;
1236 
1237  default:
1238  __ocs_domain_common_shutdown(__func__, ctx, evt, arg);
1239  return NULL;
1240  }
1241 
1242  return NULL;
1243 }
1244 
1245 
1246 
1247 /**
1248  * @brief Save the port's service parameters.
1249  *
1250  * <h3 class="desc">Description</h3>
1251  * Service parameters from the fabric FLOGI are saved in the domain's
1252  * flogi_service_params array.
1253  *
1254  * @param domain Pointer to the domain.
1255  * @param payload Service parameters to save.
1256  *
1257  * @return None.
1258  */
1259 
1260 void
1261 ocs_domain_save_sparms(ocs_domain_t *domain, void *payload)
1262 {
1263  ocs_memcpy(domain->flogi_service_params, payload, sizeof (fc_plogi_payload_t));
1264 }
1265 /**
1266  * @brief Initiator domain attach. (internal call only)
1267  *
1268  * Assumes that the domain SM lock is already locked
1269  *
1270  * <h3 class="desc">Description</h3>
1271  * The HAL domain attach function is started.
1272  *
1273  * @param domain Pointer to the domain object.
1274  * @param s_id FC_ID of which to register this domain.
1275  *
1276  * @return None.
1277  */
1278 
1279 void
1280 __ocs_domain_attach_internal(ocs_domain_t *domain, uint32_t s_id)
1281 {
1282  ocs_memcpy(domain->dma.virt, ((uint8_t*)domain->flogi_service_params)+4, sizeof (fc_plogi_payload_t) - 4);
1283  (void)ocs_sm_post_event(&domain->drvsm, OCS_EVT_DOMAIN_REQ_ATTACH, &s_id);
1284 }
1285 
1286 /**
1287  * @brief Initiator domain attach.
1288  *
1289  * <h3 class="desc">Description</h3>
1290  * The HAL domain attach function is started.
1291  *
1292  * @param domain Pointer to the domain object.
1293  * @param s_id FC_ID of which to register this domain.
1294  *
1295  * @return None.
1296  */
1297 
1298 void
1299 ocs_domain_attach(ocs_domain_t *domain, uint32_t s_id)
1300 {
1301  ocs_rlock_acquire(&domain->drvsm_lock);
1302  __ocs_domain_attach_internal(domain, s_id);
1303  ocs_rlock_release(&domain->drvsm_lock);
1304 }
1305 
1306 int
1307 ocs_domain_post_event(ocs_domain_t *domain, ocs_sm_event_t event, void *arg)
1308 {
1309  int rc;
1310  int accept_frames;
1311  int req_domain_free;
1312 
1313  ocs_rlock_acquire(&domain->drvsm_lock);
1314  rc = ocs_sm_post_event(&domain->drvsm, event, arg);
1315 
1316  req_domain_free = domain->req_domain_free;
1317  domain->req_domain_free = 0;
1318 
1319  accept_frames = domain->req_accept_frames;
1320  domain->req_accept_frames = 0;
1321  ocs_rlock_release(&domain->drvsm_lock);
1322 
1323  if (accept_frames) {
1324  ocs_domain_accept_frames(domain);
1325  }
1326 
1327  if (req_domain_free) {
1328  ocs_domain_free(domain);
1329  }
1330 
1331  return rc;
1332 }
1333 
1334 
1335 /**
1336  * @brief Return the WWN as a uint64_t.
1337  *
1338  * <h3 class="desc">Description</h3>
1339  * Calls the HAL property function for the WWNN or WWPN, and returns the value
1340  * as a uint64_t.
1341  *
1342  * @param hal Pointer to the HAL object.
1343  * @param prop HAL property.
1344  *
1345  * @return Returns uint64_t request value.
1346  */
1347 
1348 uint64_t
1349 ocs_get_wwn(ocs_hal_t *hal, ocs_hal_property_e prop)
1350 {
1351  uint8_t *p = ocs_hal_get_ptr(hal, prop);
1352  uint64_t value = 0;
1353 
1354  if (p) {
1355  uint32_t i;
1356  for (i = 0; i < sizeof(value); i++) {
1357  value = (value << 8) | p[i];
1358  }
1359  }
1360  return value;
1361 }
1362 
1363 /**
1364  * @brief Generate a domain ddump.
1365  *
1366  * <h3 class="desc">Description</h3>
1367  * Generates a domain ddump.
1368  *
1369  * @param textbuf Pointer to the text buffer.
1370  * @param domain Pointer to the domain context.
1371  *
1372  * @return Returns 0 on success, or a negative value on failure.
1373  */
1374 
1375 int
1376 ocs_ddump_domain(ocs_textbuf_t *textbuf, ocs_domain_t *domain)
1377 {
1378  ocs_sport_t *sport;
1379  int retval = 0;
1380 
1381  ocs_ddump_section(textbuf, "domain", domain->instance_index);
1382  ocs_ddump_value(textbuf, "display_name", "%s", domain->display_name);
1383 
1384  ocs_ddump_value(textbuf, "fcf", "%#x", domain->fcf);
1385  ocs_ddump_value(textbuf, "fcf_indicator", "%#x", domain->fcf_indicator);
1386  ocs_ddump_value(textbuf, "vlan_id", "%#x", domain->vlan_id);
1387  ocs_ddump_value(textbuf, "indicator", "%#x", domain->indicator);
1388  ocs_ddump_value(textbuf, "attached", "%d", domain->attached);
1389  ocs_ddump_value(textbuf, "is_loop", "%d", domain->is_loop);
1390  ocs_ddump_value(textbuf, "is_nlport", "%d", domain->is_nlport);
1391 
1392  ocs_scsi_ini_ddump(textbuf, OCS_SCSI_DDUMP_DOMAIN, domain);
1393  ocs_scsi_tgt_ddump(textbuf, OCS_SCSI_DDUMP_DOMAIN, domain);
1394 
1395  ocs_display_sparams(NULL, "domain_sparms", 1, textbuf, domain->dma.virt);
1396 
1397  if (ocs_domain_lock_try(domain) != TRUE) {
1398  /* Didn't get the lock */
1399  return -1;
1400  }
1401  ocs_list_foreach(&domain->sport_list, sport) {
1402  retval = ocs_ddump_sport(textbuf, sport);
1403  if (retval != 0) {
1404  break;
1405  }
1406  }
1407 
1408 #if defined(ENABLE_FABRIC_EMULATION)
1409  ocs_ddump_ns(textbuf, domain->ocs_ns);
1410 #endif
1411 
1412  ocs_domain_unlock(domain);
1413 
1414  ocs_ddump_endsection(textbuf, "domain", domain->instance_index);
1415 
1416  return retval;
1417 }
1418 
1419 
1420 void
1421 ocs_mgmt_domain_list(ocs_textbuf_t *textbuf, void *object)
1422 {
1423  ocs_sport_t *sport;
1424  ocs_domain_t *domain = (ocs_domain_t *)object;
1425 
1426  ocs_mgmt_start_section(textbuf, "domain", domain->instance_index);
1427 
1428  /* Add my status values to textbuf */
1429  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "fcf");
1430  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "fcf_indicator");
1431  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "vlan_id");
1432  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "indicator");
1433  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "attached");
1434  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "is_loop");
1435  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "display_name");
1436  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "num_sports");
1437 #if defined(ENABLE_FABRIC_EMULATION)
1438  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RW, "femul_enable");
1439 #endif
1440 
1441  if (ocs_domain_lock_try(domain) == TRUE) {
1442 
1443 
1444  /* If we get here, then we are holding the domain lock */
1445  ocs_list_foreach(&domain->sport_list, sport) {
1446  if ((sport->mgmt_functions) && (sport->mgmt_functions->get_list_handler)) {
1447  sport->mgmt_functions->get_list_handler(textbuf, sport);
1448  }
1449  }
1450  ocs_domain_unlock(domain);
1451  }
1452 
1453  ocs_mgmt_end_section(textbuf, "domain", domain->instance_index);
1454 }
1455 
1456 int
1457 ocs_mgmt_domain_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *object)
1458 {
1459  ocs_sport_t *sport;
1460  ocs_domain_t *domain = (ocs_domain_t *)object;
1461  char qualifier[80];
1462  int retval = -1;
1463 
1464  ocs_mgmt_start_section(textbuf, "domain", domain->instance_index);
1465 
1466  snprintf(qualifier, sizeof(qualifier), "%s/domain[%d]", parent, domain->instance_index);
1467 
1468  /* If it doesn't start with my qualifier I don't know what to do with it */
1469  if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
1470  char *unqualified_name = name + strlen(qualifier) +1;
1471 
1472  /* See if it's a value I can supply */
1473  if (ocs_strcmp(unqualified_name, "display_name") == 0) {
1474  ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "display_name", domain->display_name);
1475  retval = 0;
1476  } else if (ocs_strcmp(unqualified_name, "fcf") == 0) {
1477  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "fcf", "%#x", domain->fcf);
1478  retval = 0;
1479  } else if (ocs_strcmp(unqualified_name, "fcf_indicator") == 0) {
1480  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "fcf_indicator", "%#x", domain->fcf_indicator);
1481  retval = 0;
1482  } else if (ocs_strcmp(unqualified_name, "vlan_id") == 0) {
1483  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "vlan_id", "%#x", domain->vlan_id);
1484  retval = 0;
1485  } else if (ocs_strcmp(unqualified_name, "indicator") == 0) {
1486  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "indicator", "%#x", domain->indicator);
1487  retval = 0;
1488  } else if (ocs_strcmp(unqualified_name, "attached") == 0) {
1489  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "attached", domain->attached);
1490  retval = 0;
1491  } else if (ocs_strcmp(unqualified_name, "is_loop") == 0) {
1492  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "is_loop", domain->is_loop);
1493  retval = 0;
1494  } else if (ocs_strcmp(unqualified_name, "is_nlport") == 0) {
1495  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "is_nlport", domain->is_nlport);
1496  retval = 0;
1497  } else if (ocs_strcmp(unqualified_name, "display_name") == 0) {
1498  ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "display_name", domain->display_name);
1499  retval = 0;
1500 #if defined(ENABLE_FABRIC_EMULATION)
1501  } else if (ocs_strcmp(unqualified_name, "femul_enable") == 0) {
1502  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "femul_enable", "%d", domain->femul_enable);
1503  retval = 0;
1504 #endif
1505  } else if (ocs_strcmp(unqualified_name, "num_sports") == 0) {
1506  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "num_sports", "%d", domain->sport_instance_count);
1507  retval = 0;
1508  } else {
1509  /* If I didn't know the value of this status pass the request to each of my children */
1510 
1511  ocs_domain_lock(domain);
1512  ocs_list_foreach(&domain->sport_list, sport) {
1513  if ((sport->mgmt_functions) && (sport->mgmt_functions->get_handler)) {
1514  retval = sport->mgmt_functions->get_handler(textbuf, qualifier, name, sport);
1515  }
1516 
1517  if (retval == 0) {
1518  break;
1519  }
1520 
1521  }
1522  ocs_domain_unlock(domain);
1523  }
1524  }
1525 
1526  ocs_mgmt_end_section(textbuf, "domain", domain->instance_index);
1527  return retval;
1528 }
1529 
1530 void
1532 {
1533  ocs_sport_t *sport;
1534  ocs_domain_t *domain = (ocs_domain_t *)object;
1535 
1536  ocs_mgmt_start_section(textbuf, "domain", domain->instance_index);
1537 
1538  ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "display_name", domain->display_name);
1539  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "fcf", "%#x", domain->fcf);
1540  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "fcf_indicator", "%#x", domain->fcf_indicator);
1541  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "vlan_id", "%#x", domain->vlan_id);
1542  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "indicator", "%#x", domain->indicator);
1543  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "attached", domain->attached);
1544  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "is_loop", domain->is_loop);
1545  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "is_nlport", domain->is_nlport);
1546 #if defined(ENABLE_FABRIC_EMULATION)
1547  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "femul_enable", "%d", domain->femul_enable);
1548 #endif
1549  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "num_sports", "%d", domain->sport_instance_count);
1550 
1551  ocs_domain_lock(domain);
1552  ocs_list_foreach(&domain->sport_list, sport) {
1553  if ((sport->mgmt_functions) && (sport->mgmt_functions->get_all_handler)) {
1554  sport->mgmt_functions->get_all_handler(textbuf, sport);
1555  }
1556  }
1557  ocs_domain_unlock(domain);
1558 
1559 
1560  ocs_mgmt_end_unnumbered_section(textbuf, "domain");
1561 
1562 }
1563 
1564 int
1565 ocs_mgmt_domain_set(char *parent, char *name, char *value, void *object)
1566 {
1567  ocs_sport_t *sport;
1568  ocs_domain_t *domain = (ocs_domain_t *)object;
1569  char qualifier[80];
1570  int retval = -1;
1571 
1572  snprintf(qualifier, sizeof(qualifier), "%s/domain[%d]", parent, domain->instance_index);
1573 
1574  /* If it doesn't start with my qualifier I don't know what to do with it */
1575  if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
1576  // char *unqualified_name = name + strlen(qualifier) +1;
1577 
1578  /* See if it's a value I can supply */
1579 
1580  /* if (ocs_strcmp(unqualified_name, "display_name") == 0) {
1581 
1582  } else */
1583  {
1584  /* If I didn't know the value of this status pass the request to each of my children */
1585  ocs_domain_lock(domain);
1586  ocs_list_foreach(&domain->sport_list, sport) {
1587  if ((sport->mgmt_functions) && (sport->mgmt_functions->set_handler)) {
1588  retval = sport->mgmt_functions->set_handler(qualifier, name, value, sport);
1589  }
1590 
1591  if (retval == 0) {
1592  break;
1593  }
1594 
1595  }
1596  ocs_domain_unlock(domain);
1597  }
1598  }
1599 
1600  return retval;
1601 }
1602 
1603 void ocs_mgmt_domain_exec_cb(ocs_domain_t *domain, void *arg_in)
1604 {
1605  ocs_domain_exec_arg_t *domain_exec_args = arg_in;
1606 
1607  if (domain_exec_args) {
1608  if (ocs_atomic_sub_and_test(&domain_exec_args->ref_cnt, 1)) {
1609  ocs_free(domain->ocs, domain_exec_args, sizeof(*domain_exec_args));
1610  ocs_free(domain->ocs, domain_exec_args->arg_out,
1611  domain_exec_args->arg_out_length);
1612  }
1613  ocs_sem_v(&domain_exec_args->sem);
1614  }
1615 }
1616 
1617 int ocs_mgmt_domain_exec(char *parent, char *action, void *arg_in, uint32_t arg_in_length,
1618  void *arg_out, uint32_t arg_out_length, void *object)
1619 {
1620  ocs_domain_exec_arg_t *domain_exec_args = arg_in;
1621  ocs_sport_t *sport;
1622  ocs_domain_t *domain = (ocs_domain_t *)object;
1623  char qualifier[80];
1624  int retval = -1;
1625 
1626  snprintf(qualifier, sizeof(qualifier), "%s/domain[%d]", parent, domain->instance_index);
1627 
1628  /* If it doesn't start with my qualifier I don't know what to do with it */
1629  if (ocs_strncmp(action, qualifier, strlen(qualifier)) == 0) {
1630 
1631  {
1632  /* If I didn't know how to do this action pass the request to each of my children */
1633  ocs_domain_lock(domain);
1634  ocs_list_foreach(&domain->sport_list, sport) {
1635  if ((sport->mgmt_functions) && (sport->mgmt_functions->exec_handler)) {
1636  ocs_sport_exec_arg_t *sport_exec_args =
1637  ocs_malloc(sport->ocs, sizeof(ocs_domain_exec_arg_t),
1638  OCS_M_NOWAIT | OCS_M_ZERO);
1639  if (!sport_exec_args) {
1640  ocs_log_err(sport->ocs, "Failed to allocate memory\n");
1641  ocs_domain_unlock(domain);
1642  return -ENOMEM;
1643  }
1644  sport_exec_args->arg_in_length = domain_exec_args->arg_in_length;
1645  sport_exec_args->arg_in = domain_exec_args->arg_in;
1646  sport_exec_args->arg_out_length = domain_exec_args->arg_out_length;
1647  sport_exec_args->arg_out = domain_exec_args->arg_out;
1648  sport_exec_args->exec_cb = ocs_mgmt_sport_exec_cb;
1649  sport_exec_args->domain_exec_args = domain_exec_args;
1650 
1651  retval = sport->mgmt_functions->exec_handler(qualifier, action,
1652  sport_exec_args, sizeof(ocs_sport_exec_arg_t),
1653  NULL, 0, sport);
1654  }
1655 
1656  if (retval == 0) {
1657  break;
1658  }
1659 
1660  }
1661  ocs_domain_unlock(domain);
1662  }
1663  }
1664 
1665  return retval;
1666 }
void ocs_domain_accept_frames(ocs_domain_t *domain)
Clear hold on unsolicited frames.
Definition: ocs_unsol.c:546
ocs_hal_rtn_e ocs_hal_domain_attach(ocs_hal_t *hal, ocs_domain_t *domain, uint32_t fc_id)
Attach a SLI port to a domain.
Definition: ocs_hal.c:3280
void * __ocs_domain_allocated(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
Domain state machine: Wait for the domain attach request.
Definition: ocs_domain.c:817
void * __ocs_domain_wait_attach(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
Domain state machine: Wait for the HAL domain attach to complete.
Definition: ocs_domain.c:909
void * __ocs_domain_wait_domain_lost(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
Domain state machine: Wait for the domain alloc/attach completion after receiving a domain lost...
Definition: ocs_domain.c:1198
static void ocs_scsi_notify_domain_force_free(ocs_domain_t *domain)
Notification from base driver that domain is in force-free path.
static void ocs_domain_lock_init(ocs_domain_t *domain)
Definition: ocs_domain.h:51
void ocs_domain_force_free(ocs_domain_t *domain)
Free memory resources of a domain object.
Definition: ocs_domain.c:341
ocs_hal_property_e
Definition: ocs_hal.h:179
void ocs_mgmt_sport_exec_cb(ocs_sport_t *sport, void *)
Definition: ocs_sport.c:1608
static int32_t ocs_list_empty(ocs_list_t *list)
Test if a list is empty.
Definition: ocs_list.h:125
void ocs_sport_free(ocs_sport_t *sport)
Definition: ocs_sport.c:280
ocs_domain_t * ocs_domain_get_instance(ocs_t *ocs, uint32_t index)
Return a pointer to the domain, given the instance index.
Definition: ocs_domain.c:414
void ocs_mgmt_emit_int(ocs_textbuf_t *textbuf, int mode, const char *name, const char *fmt,...)
Generate a property with an integer value in a management XML document.
uint32_t node_name_hi
Definition: ocs_fcp.h:326
void * __ocs_domain_wait_alloc(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
Domain state machine: Wait for the domain allocation to complete.
Definition: ocs_domain.c:675
ocs_domain_t * ocs_domain_alloc(ocs_t *ocs, uint64_t fcf_wwn)
Allocate a domain object.
Definition: ocs_domain.c:218
static void * ocs_list_get_head(ocs_list_t *list)
Return the first item in the list.
Definition: ocs_list.h:292
void ocs_node_post_event(ocs_node_t *node, ocs_sm_event_t evt, void *arg)
Post event to node state machine context.
Definition: ocs_node.c:1498
static void * __ocs_domain_common(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
Domain state machine: Common event handler.
Definition: ocs_domain.c:448
void ocs_domain_free(ocs_domain_t *domain)
Free a domain object.
Definition: ocs_domain.c:279
void ocs_node_transition(ocs_node_t *node, ocs_sm_function_t state, void *data)
transition state of a node
Definition: ocs_node.c:1547
void * __ocs_domain_wait_sports_free(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
Domain state machine: Wait for nodes to free prior to the domain shutdown.
Definition: ocs_domain.c:1086
void __ocs_domain_attach_internal(ocs_domain_t *domain, uint32_t s_id)
Initiator domain attach. (internal call only)
Definition: ocs_domain.c:1280
void ocs_scsi_tgt_del_domain(ocs_domain_t *domain)
Accept a domain lost notification.
Definition: ocs_ramd.c:902
ocs_atomic_t ref_cnt
Definition: ocs_common.h:259
static void ocs_device_lock(ocs_t *ocs)
Definition: ocs_drv_fc.h:218
const char * name
Definition: ocs_ddump.h:54
void ocs_sport_force_free(ocs_sport_t *sport)
Free memory resources of a SLI port object.
Definition: ocs_sport.c:299
static ocs_mgmt_functions_t domain_mgmt_functions
Definition: ocs_domain.c:72
int ocs_ddump_sport(ocs_textbuf_t *textbuf, ocs_sli_port_t *sport)
Generate a SLI port ddump.
Definition: ocs_sport.c:1203
ocs_hal_rtn_e ocs_hal_domain_force_free(ocs_hal_t *hal, ocs_domain_t *domain)
Free a fabric domain object.
Definition: ocs_hal.c:3362
void ocs_display_sparams(const char *prelabel, const char *reqlabel, int dest, void *textbuf, void *sparams)
Display service parameters.
Definition: ocs_debug.c:495
ocs_node_t * ocs_node_find(ocs_sport_t *sport, uint32_t port_id)
Find an FC node structure given the FC port ID.
Definition: ocs_node.c:202
void ocs_node_fcid_display(uint32_t fc_id, char *buffer, uint32_t buffer_length)
Generate text for a node&#39;s fc_id.
Definition: ocs_node.c:719
void ocs_ddump_section(ocs_textbuf_t *textbuf, const char *name, uint32_t instance)
Generate driver dump section start data.
Definition: ocs_ddumplib.c:90
void ocs_mgmt_start_section(ocs_textbuf_t *textbuf, const char *name, int index)
Generate the beginning of a numbered section in a management XML document.
int const char const char void ocs_mgmt_emit_boolean(ocs_textbuf_t *textbuf, int access, const char *name, const int value)
Generate a property with a boolean value in a management XML document.
union ocs_domain_record_t::@5 map
static void ocs_domain_unlock(ocs_domain_t *domain)
Definition: ocs_domain.h:70
static void * ocs_list_remove(ocs_list_t *list, void *item)
Remove an item from the list.
Definition: ocs_list.h:385
int ocs_domain_post_event(ocs_domain_t *domain, ocs_sm_event_t event, void *arg)
Definition: ocs_domain.c:1307
const char * ocs_sm_event_name(ocs_sm_event_t evt)
Definition: ocs_sm.c:92
#define domain_trace(domain, fmt,...)
Definition: ocs_domain.c:54
ocs_hal_rtn_e ocs_hal_domain_alloc(ocs_hal_t *hal, ocs_domain_t *domain, uint32_t fcf, uint32_t vlan)
Allocate a fabric domain object.
Definition: ocs_hal.c:3217
static int32_t ocs_domain_lock_try(ocs_domain_t *domain)
Definition: ocs_domain.h:56
#define ocs_list_init(head, type, link)
Definition: ocs_list.h:113
int32_t ocs_scsi_ini_new_domain(ocs_domain_t *domain)
accept new domain notification
Definition: ocs_ini_stub.c:166
uint32_t node_name_lo
Definition: ocs_fcp.h:327
#define ocs_list_foreach_safe(list, item, nxt)
Iterate a linked list safely.
Definition: ocs_list.h:446
void ocs_mgmt_end_unnumbered_section(ocs_textbuf_t *textbuf, const char *name)
Generate the end of a section in a management XML document.
static void ocs_device_unlock(ocs_t *ocs)
Definition: ocs_drv_fc.h:223
void ocs_mgmt_domain_get_all(ocs_textbuf_t *textbuf, void *domain)
Definition: ocs_domain.c:1531
uint8_t wwn[8]
Definition: ocs_common.h:89
uint32_t port_name_lo
Definition: ocs_fcp.h:325
int32_t ocs_scsi_tgt_new_domain(ocs_domain_t *domain)
Accept a new domain notification.
Definition: ocs_ramd.c:880
void ocs_mgmt_end_section(ocs_textbuf_t *textbuf, const char *name, int index)
Generate the indexed end of a section in a management XML document.
uint32_t port_name_hi
Definition: ocs_fcp.h:324
ocs_hal_rtn_e ocs_hal_port_alloc(ocs_hal_t *hal, ocs_sli_port_t *sport, ocs_domain_t *domain, uint8_t *wwpn)
Allocate a port object.
Definition: ocs_hal.c:2882
void ocs_domain_attach(ocs_domain_t *domain, uint32_t s_id)
Initiator domain attach.
Definition: ocs_domain.c:1299
void ocs_sm_transition(ocs_sm_ctx_t *ctx, ocs_sm_function_t state, void *data)
Transition to a new state.
Definition: ocs_sm.c:72
ocs_sport_t * ocs_sport_alloc(ocs_domain_t *domain, uint64_t wwpn, uint64_t wwnn, uint32_t fc_id, uint8_t enable_ini, uint8_t enable_tgt)
Allocate a SLI port object.
Definition: ocs_sport.c:144
static void ocs_sport_lock(ocs_sport_t *sport)
Definition: ocs_sport.h:67
ocs_node_t * ocs_node_alloc(ocs_sport_t *sport, uint32_t port_id, uint8_t init, uint8_t targ)
Allocate an fc node structure and add to node list.
Definition: ocs_node.c:415
void ocs_node_pause(ocs_node_t *node, ocs_sm_function_t state)
Pause a node.
Definition: ocs_node.c:2140
void ocs_ddump_endsection(ocs_textbuf_t *textbuf, const char *name, uint32_t instance)
Generate driver dump section end data.
Definition: ocs_ddumplib.c:108
ocs_mgmt_get_list_handler get_list_handler
Definition: ocs_mgmt.h:83
#define OCS_CTRLMASK_ENABLE_FABRIC_EMULATION
#define MGMT_MODE_RD
Definition: ocs_mgmt.h:47
int ocs_sm_post_event(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *data)
Post an event to a context.
Definition: ocs_sm.c:58
uint32_t arg_out_length
Definition: ocs_common.h:267
void ocs_xport_domain_list_empty_cb(ocs_t *ocs, void *arg)
domain list empty callback
Definition: ocs_xport.c:771
static void ocs_list_add_tail(ocs_list_t *list, void *item)
Add an item to the tail of the list.
Definition: ocs_list.h:263
int32_t ocs_domain_cb(void *arg, ocs_hal_domain_event_e event, void *data)
Accept domain callback events from the HAL.
Definition: ocs_domain.c:94
Description of discovered Fabric Domain.
Definition: ocs_common.h:85
void ocs_domain_hold_frames(ocs_domain_t *domain)
Globally (at xport level) hold unsolicited frames.
Definition: ocs_unsol.c:518
void * __ocs_d_wait_loop(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
Device node state machine: Wait for a domain-attach completion in loop topology.
Definition: ocs_device.c:289
void * __ocs_fabric_init(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
Fabric node state machine: Initial state.
Definition: ocs_fabric.c:103
void ocs_scsi_tgt_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj)
Definition: ocs_ramd.c:6580
ocs_hal_rtn_e ocs_hal_domain_free(ocs_hal_t *hal, ocs_domain_t *domain)
Free a fabric domain object.
Definition: ocs_hal.c:3324
int32_t ocs_vport_start(ocs_domain_t *domain)
Start the vports on a domain.
Definition: ocs_sport.c:969
void ocs_unregister_domain_list_empty_cb(ocs_t *ocs)
Unregister a callback for the domain_list empty cb.
Definition: ocs_domain.c:370
#define std_domain_state_decl(...)
Definition: ocs_domain.c:511
static void ocs_domain_lock(ocs_domain_t *domain)
Definition: ocs_domain.h:63
sparse_vector_t spv_new(ocs_os_handle_t os)
Instantiate a new sparse vector object.
Definition: spv.c:173
ocs_hal_domain_event_e
Fabric/Domain events.
Definition: ocs_hal.h:664
static void * __ocs_domain_common_shutdown(const char *funcname, ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
Domain state machine: Common shutdown.
Definition: ocs_domain.c:483
uint64_t ocs_get_wwn(ocs_hal_t *hal, ocs_hal_property_e prop)
Return the WWN as a uint64_t.
Definition: ocs_domain.c:1349
void ocs_scsi_ini_del_domain(ocs_domain_t *domain)
accept domain lost notification
Definition: ocs_ini_stub.c:197
void * __ocs_sport_allocated(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
SLI port state machine: Physical sport allocated.
Definition: ocs_sport.c:607
int ocs_mgmt_domain_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *domain)
Definition: ocs_domain.c:1457
uint32_t is_ethernet
Definition: ocs_common.h:96
void ocs_domain_save_sparms(ocs_domain_t *domain, void *payload)
Save the port&#39;s service parameters.
Definition: ocs_domain.c:1261
void(* exec_cb)(ocs_sport_t *sport, void *arg)
Definition: ocs_common.h:270
#define MGMT_MODE_RW
Definition: ocs_mgmt.h:50
int32_t ocs_get_property(const char *prop_name, char *buffer, uint32_t buffer_len)
get driver wide property value
void * __ocs_domain_init(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
Domain state machine: Initial state.
Definition: ocs_domain.c:538
void spv_del(sparse_vector_t spv)
Delete a sparse vector.
Definition: spv.c:153
#define ocs_assert(cond,...)
Definition: ocs_debug.h:176
void ocs_mgmt_domain_list(ocs_textbuf_t *textbuf, void *domain)
Definition: ocs_domain.c:1421
int ocs_mgmt_domain_exec(char *parent, char *action, void *arg_in, uint32_t arg_in_length, void *arg_out, uint32_t arg_out_length, void *object)
Definition: ocs_domain.c:1617
void ocs_register_domain_list_empty_cb(ocs_t *ocs)
Register a callback when the domain_list goes empty.
Definition: ocs_domain.c:389
void * ocs_hal_get_ptr(ocs_hal_t *hal, ocs_hal_property_e prop)
Definition: ocs_hal.c:2175
ocs_sm_event_t
Definition: ocs_sm.h:60
ocs_domain_exec_arg_t * domain_exec_args
Definition: ocs_common.h:269
int ocs_mgmt_domain_set(char *parent, char *name, char *value, void *domain)
Definition: ocs_domain.c:1565
uint8_t loop[128]
Definition: ocs_common.h:92
void ocs_mgmt_emit_string(ocs_textbuf_t *textbuf, int access, const char *name, const char *value)
Generate a property with a string value in a management XML document.
void ocs_mgmt_domain_exec_cb(ocs_domain_t *domain, void *)
Definition: ocs_domain.c:1603
#define domain_sm_trace(domain)
Definition: ocs_domain.c:48
#define ocs_list_foreach(list, item)
Iterate a linked list.
Definition: ocs_list.h:428
#define OCS_NODEDB_PAUSE_FABRIC_LOGIN
Definition: ocs_node.h:71
uint8_t vlan[512]
Definition: ocs_common.h:91
int ocs_ddump_domain(ocs_textbuf_t *textbuf, ocs_domain_t *domain)
Generate a domain ddump.
Definition: ocs_domain.c:1376
void ocs_sm_disable(ocs_sm_ctx_t *ctx)
Disable further state machine processing.
Definition: ocs_sm.c:87
uint32_t arg_in_length
Definition: ocs_common.h:265
static void ocs_sport_unlock(ocs_sport_t *sport)
Definition: ocs_sport.h:74
void ocs_mgmt_emit_property_name(ocs_textbuf_t *textbuf, int access, const char *name)
Generate a property, with no value, in a management XML document.
void ocs_ddump_value(ocs_textbuf_t *textbuf, const char *name, const char *fmt,...)
Generate driver dump data for a given value.
Definition: ocs_ddumplib.c:126
void spv_set(sparse_vector_t sv, uint32_t idx, void *value)
Set the sparse vector cell value.
Definition: spv.c:258
void * __ocs_domain_ready(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
Domain state machine: Ready state.
Definition: ocs_domain.c:1002
ocs_domain_t * ocs_domain_find(ocs_t *ocs, uint64_t fcf_wwn)
Find the domain, given its FCF_WWN.
Definition: ocs_domain.c:189
Sparse Vector API.
void ocs_scsi_ini_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj)
Definition: ocs_ini_stub.c:266
#define FC_ADDR_FABRIC
Definition: ocs_fcp.h:61
void * __ocs_domain_wait_shutdown(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *arg)
Domain state machine: Complete the domain shutdown.
Definition: ocs_domain.c:1129