Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ocs_driver.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 #include "ocs.h"
34 #include "ocs_elxu.h"
35 #include "ocs_driver.h"
36 #include "ocs_vpd.h"
37 #include "ocs_params.h"
38 #include "ocs_gendump.h"
39 #include "ocs_ocsu.h"
40 
41 char ocs_version[] = "version: ocs_fc_ramd: " DRV_VERSION;
42 
44 
45 void ocs_mgmt_driver_list(ocs_textbuf_t *textbuf, void *driver);
46 void ocs_mgmt_driver_get_all(ocs_textbuf_t *textbuf, void *driver);
47 int ocs_mgmt_driver_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *driver);
48 int ocs_mgmt_driver_exec(char *parent, char *action, void *arg_in, uint32_t arg_in_length,
49  void *arg_out, uint32_t arg_out_length, void *driver);
50 static void ocs_driver_print_module_params(void);
51 
54  .get_handler = ocs_mgmt_driver_get,
55  .get_all_handler = ocs_mgmt_driver_get_all,
56  .exec_handler = ocs_mgmt_driver_exec,
57 };
58 
59 /* PARAM_LIST: generate parameter declarations with initializers */
60 #define P(type, name, value, desc) type name = value;
61 PARAM_LIST
62 #undef P
63 
64 int32_t
66 {
67  hal_global.queue_topology_string = queue_topology;
68  int32_t rc;
69 
70  ocs_thread_init();
71 
72  /* Call back-end driver wide initialzation functions */
73 
74  /* driver-wide init for target-server */
75  if (target) {
77  if (rc) {
78  return rc;
79  }
80  }
81 
82  /* driver-wide init for initiator-client */
83  if (initiator) {
84  rc = ocs_scsi_ini_driver_init(initiator);
85  if (rc) {
86  return rc;
87  }
88  }
89 
90  /* Print module Parameters */
92 
93  return 0;
94 }
95 
96 /*
97  * @brief allocate ocs device
98  *
99  * @param nid Numa node ID
100  *
101  * @return returns pointer to allocated OCS structure
102  */
103 void *
104 ocs_device_alloc(uint32_t nid)
105 {
106  ocs_t *ocs = NULL;
107  uint32_t i;
108 
109  ocs = ocs_malloc(NULL, sizeof(*ocs), OCS_M_NOWAIT | OCS_M_ZERO);
110  if (ocs == NULL) {
111  ocs_log_err(ocs, "memory allocation failed for ocs_t\n");
112  return NULL;
113  }
114 
115  for (i = 0; i < ARRAY_SIZE(ocs_devices); i ++) {
116  if (ocs_devices[i] == NULL) {
117  ocs->instance_index = i;
118  ocs_devices[ocs->instance_index] = ocs;
119  break;
120  }
121  }
122 
123  if (i == ARRAY_SIZE(ocs_devices)) {
124  ocs_log_err(NULL, "failed\n");
125  ocs_free(ocs, ocs, sizeof(*ocs));
126  ocs = NULL;
127  return ocs;
128  }
129 
130  /* If enabled, initailize a RAM logging buffer */
131  if (logdest & 2) {
132  ocs->ramlog = ocs_ramlog_init(ocs, ramlog_size/OCS_RAMLOG_DEFAULT_BUFFERS,
134  /* If NULL was returned, then we'll simply skip using the ramlog but */
135  /* set logdest to 1 to ensure that we at least get default logging. */
136  if (ocs->ramlog == NULL) {
137  logdest = 1;
138  }
139  }
140 
141  /* initialize a saved ddump */
142  if (ddump_saved_size) {
143  if (ocs_textbuf_alloc(ocs, &ocs->ddump_saved, ddump_saved_size)) {
144  ocs_log_err(ocs, "failed to allocate memory for saved ddump\n");
145  }
146  }
147  ocs_list_init(&ocs->domain_list, ocs_domain_t, link);
148 //TODO: ocs->ocs_os.interrupt_cb = ocs_device_interrupt_handler;
149 
150 #if defined(ENABLE_LOCK_DEBUG)
151  ocs_lock_init(NULL, &ocs->ocs_os.locklist_lock, "locklist_lock[%d]", ocs->instance_index);
152  ocs_list_init(&ocs->ocs_os.locklist, ocs_lock_t, link);
153 #endif
154 
156  ocs->drv_ocs.attached = FALSE;
157  ocs->mgmt_functions = &driver_mgmt_functions;
158 
159  /* Save userspace mask value */
160  ocs->drv_ocs.uspace_thread_per_port = (uspacemask & (1U << 0)) == 0;
161  ocs->drv_ocs.uspace_threads_block = (uspacemask & (1U << 1)) == 0;
162  return ocs;
163 }
164 
165 /**
166  * @brief free ocs device
167  *
168  * @param ocs pointer to ocs structure
169  *
170  * @return none
171  */
172 
173 void
174 ocs_device_free(ocs_t *ocs)
175 {
176  if (ocs != NULL) {
177  ocs_textbuf_free(ocs, &ocs->ddump_saved);
178  ocs_ramlog_free(ocs, ocs->ramlog);
179  ocs_devices[ocs->instance_index] = NULL;
181 
182 #if defined(ENABLE_LOCK_DEBUG)
183  {
184  ocs_os_t *os = &ocs->ocs_os;
185  ocs_lock_t *l;
186  uint32_t count = 0;
187  ocs_list_foreach(&os->locklist, l) {
188  ocs_log_test(os, "%s not freed\n", l->name);
189  count++;
190  }
191  if (count == 0) {
192  ocs_log_debug(ocs, "all lock objects freed\n");
193  }
194  }
195 #endif
196 
197  ocs_free(ocs, ocs, sizeof(*ocs));
198  }
199 }
200 
201 /**
202  * @brief return the number of interrupts required per HBA
203  *
204  * @param ocs pointer to ocs structure
205  *
206  * @return the number of interrupts.
207  */
208 int32_t
210 {
211  int32_t rc;
212 
213  rc = ocs_hal_setup(&ocs->hal, ocs, SLI4_PORT_TYPE_FC);
214  if (rc) {
215  return -1;
216  }
217  return ocs_hal_qtop_eq_count(&ocs->hal);
218 }
219 
220 /**
221  * @brief Initialize resources when pci devices attach
222  *
223  * @param ocs pointer to ocs structure
224  *
225  * @return 0 for success, a negative error code value for failure.
226  */
227 
228 int32_t
229 ocs_device_attach(ocs_t *ocs)
230 {
231  uint32_t rc = 0;
232 
233  if (ocs->drv_ocs.attached) {
234  ocs_log_warn(ocs, "Device is already attached\n");
235  rc = -1;
236  } else {
237 
238  ocs_snprintf(ocs->display_name, sizeof(ocs->display_name), "[%s%d] ", "fc", ocs->instance_index);
239 
240  ocs->enable_ini = initiator;
241  ocs->enable_tgt = target;
242  ocs->ctrlmask = ctrlmask;
243  ocs->topology = topology;
244  ocs->speed = speed;
245  ocs->ethernet_license = ethernet_license;
246  ocs->num_scsi_ios = num_scsi_ios;
247  ocs->enable_hlm = enable_hlm;
248  ocs->enable_fw_ag_rsp = enable_fw_ag_rsp;
249  ocs->hlm_group_size = hlm_group_size;
250  ocs->hal_war_version = hal_war_version;
251  ocs->explicit_buffer_list = explicit_buffer_list;
252  ocs->esoc = esoc;
253  ocs->logmask = logmask;
254  ocs->num_vports = num_vports;
255  ocs->enable_dpp = enable_dpp;
256  ocs->external_loopback = external_loopback;
257  ocs->target_io_timer_sec = target_io_timer;
258  ocs->tgt_wqe_timer = target_wqe_timer;
259  ocs->driver_version = DRV_VERSION;
260  ocs->hal_bounce = hal_bounce;
261  ocs->rq_threads = rq_threads;
262  ocs->rq_selection_policy = rq_selection_policy;
263  ocs->rr_quanta = rr_quanta;
264  ocs->filter_def = filter_def;
265  ocs->max_isr_time_msec = OCS_OS_MAX_ISR_TIME_MSEC;
266  ocs->model = ocs_pci_model(ocs->pci_vendor, ocs->pci_device);
267  ocs->fw_version = (const char*) ocs_hal_get_ptr(&ocs->hal, OCS_HAL_FW_REV);
268  ocs->sliport_pause_errors = sliport_pause_errors;
269  ocs->enable_bbcr = enable_bbcr;
270 
271  ocs->tgt_rscn_delay_msec = 0;
272  ocs->tgt_rscn_period_msec = 0;
273 
274  /* Allocate transport object and bring online */
275  ocs->xport = ocs_xport_alloc(ocs);
276  if (ocs->xport == NULL) {
277  ocs_log_err(ocs, "failed to allocate transport object\n");
278  rc = -1;
279  } else if (ocs_xport_attach(ocs->xport) != 0) {
280  ocs_log_err(ocs, "failed to attach transport object\n");
281  rc = -1;
282  } else if (ocs_xport_initialize(ocs->xport) != 0) {
283  ocs_log_err(ocs, "failed to initialize transport object\n");
284  rc = -1;
285  } else {
286  if ((holdoff_link_online == 2) && ((!ocs->enable_tgt) && (ocs->enable_ini))) {
287  holdoff_link_online = 0;
288  }
289 
290  if (holdoff_link_online == 0) {
291  if (ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE) != 0) {
292  /*
293  * Only log a message. Don't return the error,
294  * so that the driver will still attach to this port.
295  */
296  ocs_log_err(ocs, "failed to bring port online\n");
297  }
298  }
299 
300  }
301  ocs->desc = ocs->hal.sli.config.modeldesc;
302  ocs_log_info(ocs, "adapter model description: %s\n", ocs->hal.sli.config.modeldesc);
303 
304  if (rc == 0) {
305  ocs->drv_ocs.attached = TRUE;
306  } else {
307  ocs_xport_free(ocs->xport);
308  ocs->xport = NULL;
309  }
310  }
311  return rc;
312 }
313 
314 /**
315  * @brief free resources when pci device detach
316  *
317  * @param ocs pointer to ocs structure
318  *
319  * @return 0 for success, a negative error code value for failure.
320  */
321 
322 int32_t
323 ocs_device_detach(ocs_t *ocs)
324 {
325  int32_t rc = 0;
326 
327  if (ocs != NULL) {
328 
329  if (!ocs->drv_ocs.attached) {
330  ocs_log_warn(ocs, "Device is not attached\n");
331  return -1;
332  }
333  rc = ocs_xport_control(ocs->xport, OCS_XPORT_SHUTDOWN);
334  if (rc) {
335  ocs_log_err(ocs, "Transport Shutdown timed out\n");
336  }
337  if (uspacemask & (1U << 1)) {
338  ocs_log_test(ocs, "terminating event threads for OCS device: %d\n",
339  ocs->instance_index);
340  ocsu_terminate_event_threads(ocs);
341  }
342  if (ocs_xport_detach(ocs->xport) != 0) {
343  ocs_log_err(ocs, "Transport detach failed\n");
344  }
345 
346  ocs_xport_free(ocs->xport);
347  ocs->xport = NULL;
348  ocs->drv_ocs.attached = FALSE;
349  }
350 
351  return 0;
352 }
353 
354 /**
355  * @brief get driver wide property value
356  *
357  * Return valued driver wide property. All property values using this interface
358  * are returned as null terminated text.
359  *
360  * @param prop_name property name
361  * @param buffer pointer to buffer
362  * @param buffer_len length of buffer in bytes
363  *
364  * @return returns 0 for success, a negative error code value for failure.
365  */
366 
367 int32_t
368 ocs_get_property(const char *prop_name, char *buffer, uint32_t buffer_len)
369 {
370  if (ocs_strcmp(prop_name, "ramdisc_size") == 0) {
371  strncpy(buffer, ramdisc_size, buffer_len);
372  } else if (ocs_strcmp(prop_name, "ramdisc_blocksize") == 0) {
373  snprintf(buffer, buffer_len, "%d", ramdisc_blocksize);
374  } else if (ocs_strcmp(prop_name, "num_luns") == 0) {
375  snprintf(buffer, buffer_len, "%d", num_luns);
376  } else if (ocs_strcmp(prop_name, "initiator") == 0) {
377  snprintf(buffer, buffer_len, "%d", initiator);
378  } else if (ocs_strcmp(prop_name, "target") == 0) {
379  snprintf(buffer, buffer_len, "%d", target);
380  } else if (ocs_strcmp(prop_name, "wwn_bump") == 0) {
381  snprintf(buffer, buffer_len, "%s", wwn_bump);
382  } else if (ocs_strcmp(prop_name, "p_type") == 0) {
383  snprintf(buffer, buffer_len, "%d", p_type);
384  } else if (ocs_strcmp(prop_name, "dif_separate") == 0) {
385  snprintf(buffer, buffer_len, "%d", dif_separate);
386  } else if (ocs_strcmp(prop_name, "global_ramdisc") == 0) {
387  snprintf(buffer, buffer_len, "%d", global_ramdisc);
388  } else if (ocs_strcmp(prop_name, "ncpu") == 0) {
389  ocs_snprintf(buffer, buffer_len, "%ld", sysconf(_SC_NPROCESSORS_ONLN));
390  } else if (ocs_strcmp(prop_name, "ramd_threading") == 0) {
391  ocs_snprintf(buffer, buffer_len, "%d", ramd_threading);
392  } else if (ocs_strcmp(prop_name, "thread_cmds") == 0) {
393  ocs_snprintf(buffer, buffer_len, "%d", thread_cmds);
394  } else if (ocs_strcmp(prop_name, "external_dif") == 0) {
395  ocs_strncpy(buffer, external_dif, buffer_len);
396  } else if (strcmp(prop_name, "esoc") == 0) {
397  ocs_snprintf(buffer, buffer_len, "%d", esoc);
398  } else if (strcmp(prop_name, "tow_xri_cnt") == 0) {
399  ocs_snprintf(buffer, buffer_len, "%d", tow_xri_cnt);
400  }
401  else {
402  ocs_log_test(NULL, "Error: unknown property %s\n", prop_name);
403  snprintf(buffer, buffer_len, "%s", "");
404  return -1;
405  }
406  return 0;
407 }
408 
409 /**
410  * @brief return OCS instance display name
411  *
412  * returns const char string of OCS instance display name
413  *
414  * @param os pointer to OS (ocs_t) object
415  *
416  * @return return display name
417  */
418 
419 const char *ocs_display_name(void *os)
420 {
421  ocs_t *ocs = os;
422  ocs_assert(ocs, "[?]");
423  return ocs->display_name;
424 }
425 
426 /**
427  * @brief return pointer to ocs structure given instance index
428  *
429  * A pointer to an ocs structure is returned given an instance index.
430  *
431  * @param index index to ocs_devices array
432  *
433  * @return ocs pointer
434  */
435 
436 ocs_t *ocs_get_instance(uint32_t index)
437 {
438  if (index < ARRAY_SIZE(ocs_devices)) {
439  return ocs_devices[index];
440  }
441  return NULL;
442 }
443 
444 /**
445  * @brief Return instance index of an opaque ocs structure
446  *
447  * Returns the ocs instance index
448  *
449  * @param os pointer to ocs instance
450  *
451  * @return pointer to ocs instance index
452  */
453 uint32_t
454 ocs_instance(void *os)
455 {
456  ocs_t *ocs = os;
457 
458  return ocs != NULL ? ocs->instance_index : UINT32_MAX;
459 }
460 
461 void ocs_mgmt_driver_list(ocs_textbuf_t *textbuf, void *object)
462 {
463 
464  ocs_mgmt_start_unnumbered_section(textbuf, "driver");
465 
466  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "global_ramdisc");
467  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "ramdisc_size");
468  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "ramdisc_blocksize");
469  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "num_luns");
470  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "initiator");
471  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "target");
472  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "logmask");
473  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "ctrlmask");
474  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "wwn_bump");
475  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "topology");
476  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "speed");
477  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "p_type");
478  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "holdoff_link_online");
479  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "enable_hlm");
480  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "enable_fw_ag_rsp");
481  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "hlm_group_size");
482  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "external_loopback");
483  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "target_io_timer");
484  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "auto_xfer_rdy_size");
485  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "esoc");
486  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_RD, "auto_xfer_rdy_xri_cnt");
487  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_EX, "gendump");
488  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_EX, "clear_ramlog");
489 
490  ocs_mgmt_end_unnumbered_section(textbuf, "driver");
491 }
492 
493 int ocs_mgmt_driver_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *object)
494 {
495  char qualifier[80];
496  int retval = -1;
497 
498  ocs_mgmt_start_unnumbered_section(textbuf, "driver");
499 
500  snprintf(qualifier, sizeof(qualifier), "%s/driver", parent);
501 
502  /* If it doesn't start with my qualifier I don't know what to do with it */
503  if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
504  char *unqualified_name = name + strlen(qualifier) +1;
505 
506  /* See if it's a value I can supply */
507  if (ocs_strcmp(unqualified_name, "global_ramdisc") == 0) {
508  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "global_ramdisc", "%d", global_ramdisc);
509  retval = 0;
510  } else if (ocs_strcmp(unqualified_name, "ramdisc_size") == 0) {
511  ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "ramdisc_size", ramdisc_size);
512  retval = 0;
513  } else if (ocs_strcmp(unqualified_name, "ramdisc_blocksize") == 0) {
514  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "ramdisc_blocksize", "%d", ramdisc_blocksize);
515  retval = 0;
516  } else if (ocs_strcmp(unqualified_name, "num_luns") == 0) {
517  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "num_luns", "%d", num_luns);
518  retval = 0;
519  } else if (ocs_strcmp(unqualified_name, "initiator") == 0) {
520  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "initiator", initiator);
521  retval = 0;
522  } else if (ocs_strcmp(unqualified_name, "target") == 0) {
523  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "target", target);
524  retval = 0;
525  } else if (ocs_strcmp(unqualified_name, "logmask") == 0) {
526  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "logmask", "0x%x", logmask);
527  retval = 0;
528  } else if (ocs_strcmp(unqualified_name, "ctrlmask") == 0) {
529  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "ctrlmask", "0x%x", ctrlmask);
530  retval = 0;
531  } else if (ocs_strcmp(unqualified_name, "wwn_bump") == 0) {
532  ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "wwn_bump", wwn_bump);
533  retval = 0;
534  } else if (ocs_strcmp(unqualified_name, "topology") == 0) {
535  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "topology", "%d", topology);
536  retval = 0;
537  } else if (ocs_strcmp(unqualified_name, "speed") == 0) {
538  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "speed", "%d", speed);
539  retval = 0;
540  } else if (ocs_strcmp(unqualified_name, "p_type") == 0) {
541  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "p_type", "%d", p_type);
542  retval = 0;
543  } else if (ocs_strcmp(unqualified_name, "holdoff_link_online") == 0) {
544  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "holdoff_link_online", holdoff_link_online);
545  retval = 0;
546  } else if (ocs_strcmp(unqualified_name, "enable_hlm") == 0) {
547  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "enable_hlm", enable_hlm);
548  retval = 0;
549  } else if (ocs_strcmp(unqualified_name, "enable_fw_ag_rsp") == 0) {
550  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "enable_fw_ag_rsp", enable_fw_ag_rsp);
551  retval = 0;
552  } else if (ocs_strcmp(unqualified_name, "hlm_group_size") == 0) {
553  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "hlm_group_size", "%d", hlm_group_size);
554  retval = 0;
555  } else if (ocs_strcmp(unqualified_name, "tow_feature") == 0) {
556  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "tow_feature", "%d", tow_feature);
557  retval = 0;
558  } else if (ocs_strcmp(unqualified_name, "tow_xri_cnt") == 0) {
559  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "tow_xri_cnt", "%d", tow_xri_cnt);
560  retval = 0;
561  } else if (ocs_strcmp(unqualified_name, "tow_io_size") == 0) {
562  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "tow_io_size", "%d", tow_io_size);
563  retval = 0;
564  } else if (ocs_strcmp(unqualified_name, "esoc") == 0) {
565  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "esoc", "%d", esoc);
566  retval = 0;
567  } else if (ocs_strcmp(unqualified_name, "external_loopback") == 0) {
568  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "external_loopback", external_loopback);
569  retval = 0;
570  } else if (ocs_strcmp(unqualified_name, "target_io_timer") == 0) {
571  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "target_io_timer", "%d", target_io_timer);
572  retval = 0;
573  }
574  }
575 
576  ocs_mgmt_end_unnumbered_section(textbuf, "driver");
577 
578  return retval;
579 }
580 
581 void ocs_mgmt_driver_get_all(ocs_textbuf_t *textbuf, void *object)
582 {
583  ocs_mgmt_start_unnumbered_section(textbuf, "driver");
584 
585  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "global_ramdisc", "%d", global_ramdisc);
586  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "initiator", initiator);
587  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "target", target);
588  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "logmask", "0x%x", logmask);
589  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "loglevel", "%d", loglevel);
590  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "ctrlmask", "0x%x", ctrlmask);
591  ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "wwn_bump", wwn_bump);
592  ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "hal_war_version", hal_war_version);
593  ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "filter_def", filter_def);
594  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "topology", "%d", topology);
595  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "speed", "%d", speed);
596  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "holdoff_link_online", holdoff_link_online);
597  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "enable_hlm", enable_hlm);
598  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "enable_fw_ag_rsp", enable_fw_ag_rsp);
599  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "hlm_group_size", "%d", hlm_group_size);
600  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "tow_feature", "%d", tow_feature);
601  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "tow_io_size", "%d", tow_io_size);
602  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "tow_xri_cnt", "%d", tow_xri_cnt);
603  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "esoc", "%d", esoc);
604  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "external_loopback", external_loopback);
605  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "target_io_timer", "%d", target_io_timer);
606  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "ethernet_license", "%d", ethernet_license);
607  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "num_vports", "%d", num_vports);
608  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "rq_threads", "%d", rq_threads);
609  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "rr_quanta", "%d", rr_quanta);
610  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "num_scsi_ios", "%d", num_scsi_ios);
611  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "ddump_saved_size", "%d", ddump_saved_size);
612  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "explicit_buffer_list", "%d", explicit_buffer_list);
613  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "external_loopback", "%d", external_loopback);
614  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "ddump_saved_size", "%d", ddump_saved_size);
615  ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "queue_topology", queue_topology);
616  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "dif_separate", dif_separate);
617  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "rq_selection_policy", "%d", rq_selection_policy);
618  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "cq_process_limit", "%d", cq_process_limit);
619  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "ramlog_size", "%d", ramlog_size);
620  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_EX, "gendump");
621  ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_EX, "clear_ramlog");
622 #if defined(OCS_INCLUDE_RAMD)
623  ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "ramdisc_size", ramdisc_size);
624  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "ramdisc_blocksize", "%d", ramdisc_blocksize);
625  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "num_luns", "%d", num_luns);
626  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "p_type", "%d", p_type);
627  ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RD, "stub_res6_rel6", stub_res6_rel6);
628  ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "external_dif", external_dif);
629  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "ramd_threading", "%d", ramd_threading);
630  ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "thread_cmds", "%d", thread_cmds);
631 #endif
632 
633  ocs_mgmt_end_unnumbered_section(textbuf, "driver");
634 }
635 
636 int ocs_mgmt_driver_set(char *parent, char *name, char *value)
637 {
638  return -1;
639 }
640 
641 int ocs_mgmt_driver_exec(char *parent, char *action_name, void *arg_in,
642  uint32_t arg_in_length, void *arg_out, uint32_t arg_out_length, void *object)
643 {
644  char qualifier[80];
645  int retval = -1;
646  ocs_t *ocs = (ocs_t *)object;
647 
648  ocs_snprintf(qualifier, sizeof(qualifier), "%s/driver", parent);
649 
650  /* If it doesn't start with my qualifier I don't know what to do with it */
651  if (ocs_strncmp(action_name, qualifier, strlen(qualifier)) == 0) {
652  char *unqualified_name = action_name + strlen(qualifier) +1;
653 
654  /* See if it's a value I can supply */
655  if (ocs_strcmp(unqualified_name, "gendump") == 0) {
656  retval = ocs_gen_dump(ocs);
657  }
658  if (ocs_strcmp(unqualified_name, "clear_ramlog") == 0) {
659  char local_arg_in[128];
660  int clear_start_of_day = 0;
661  int clear_recent = 0;
662  if (arg_in) {
663  if (ocs_copy_from_user(local_arg_in, arg_in,
664  MIN(arg_in_length, sizeof(local_arg_in)-1))) {
665  ocs_log_test(ocs, "Error: copy arg_in from user failed\n");
666  return -1;
667  }
668 
669  local_arg_in[sizeof(local_arg_in)-1] = 0;
670  if (ocs_strcmp(local_arg_in, "recent") == 0) {
671  clear_recent = 1;
672  } else if (ocs_strcmp(local_arg_in, "start_of_day") == 0) {
673  clear_start_of_day = 1;
674  } else if (ocs_strcmp(local_arg_in, "all") == 0) {
675  clear_recent = 1;
676  clear_start_of_day = 1;
677  }
678  } else {
679  clear_recent = 1;
680  clear_start_of_day = 1;
681  }
682 
683  ocs_log_debug(ocs, "Clear ramlog:%s%s\n", clear_start_of_day ? " start_of_day" : "",
684  clear_recent ? " recent" : "");
685 
686  ocs_ramlog_clear(ocs, ocs->ramlog, clear_start_of_day, clear_recent);
687  retval = 0;
688  }
689  }
690 
691  return retval;
692 }
693 /**
694  * @brief Perform driver wide shutdown complete actions
695  *
696  * This function is called shutdown for all devices has completed
697  *
698  * @return none
699  */
700 void
702 {
703  if (initiator) {
704  ocs_scsi_ini_driver_exit(initiator);
705  }
706  if (target) {
708  }
709 }
710 
711 /**
712  * @brief Log module parameters
713  *
714  * A list of module paramters is gerneated to the driver log
715  *
716  * @return none
717  */
718 static void
720 {
721  ocs_log_info(NULL, "%s: driver version %s\n", DRV_NAME, DRV_VERSION);
722 
723  ocs_log_info(NULL, " Module parameters:\n");
724  ocs_log_info(NULL, " Initiator = %d\n", initiator);
725  ocs_log_info(NULL, " Target = %d\n", target);
726  ocs_log_info(NULL, " ctrlmask = 0x%04x\n", ctrlmask);
727  ocs_log_info(NULL, " loglevel = %d\n", loglevel);
728  ocs_log_info(NULL, " logmask = 0x%04x\n", logmask);
729  ocs_log_info(NULL, " ramlog_size = %d\n", ramlog_size);
730  ocs_log_info(NULL, " rq_threads = %d\n", rq_threads);
731  ocs_log_info(NULL, " wwn_bump = %s\n", wwn_bump);
732  ocs_log_info(NULL, " topology = %d\n", topology);
733  ocs_log_info(NULL, " speed = %d\n", speed);
734  ocs_log_info(NULL, " holdoff_link_online = %d\n", holdoff_link_online);
735  ocs_log_info(NULL, " enable_hlm = %d\n", enable_hlm);
736  ocs_log_info(NULL, " enable_fw_ag_rsp = %d\n", enable_fw_ag_rsp);
737  ocs_log_info(NULL, " hlm_group_size = %d\n", hlm_group_size);
738  ocs_log_info(NULL, " ethernet_license = %d\n", ethernet_license);
739  ocs_log_info(NULL, " num_scsi_ios = %d\n", num_scsi_ios);
740  ocs_log_info(NULL, " dif_separate = %d\n", dif_separate);
741  ocs_log_info(NULL, " tow_feature = %d\n", tow_feature);
742  ocs_log_info(NULL, " tow_xri_cnt = %d\n", tow_xri_cnt);
743  ocs_log_info(NULL, " tow_io_size = %d\n", tow_io_size);
744  ocs_log_info(NULL, " esoc = %d\n", esoc);
745  ocs_log_info(NULL, " queue_topology = %s\n", queue_topology);
746  ocs_log_info(NULL, " rq_selection_policy = %d\n", rq_selection_policy);
747  ocs_log_info(NULL, " rr_quanta = %d\n", rr_quanta);
748  ocs_log_info(NULL, " filter_ref = %s\n", filter_def);
749  ocs_log_info(NULL, " cq_process_limit = %d\n", cq_process_limit);
750  ocs_log_info(NULL, " explicit_buffer_list = %d\n", explicit_buffer_list);
751  ocs_log_info(NULL, " num_vports = %d\n", num_vports);
752  ocs_log_info(NULL, " external_loopback = %d\n", external_loopback);
753  ocs_log_info(NULL, " target_io_timer = %d\n", target_io_timer);
754  ocs_log_info(NULL, " target_wqe_timer = %d\n", target_wqe_timer);
755  ocs_log_info(NULL, " ddump_saved_size = %d\n", ddump_saved_size);
756  ocs_log_info(NULL, " hal_war_version = %s\n", hal_war_version);
757 
758 #if defined(OCS_INCLUDE_RAMD)
759  ocs_log_info(NULL, " p_type = %d\n", p_type);
760  ocs_log_info(NULL, " ramdisc_size = %s\n", ramdisc_size);
761  ocs_log_info(NULL, " ramdisc_blocksize = %d\n", ramdisc_blocksize);
762  ocs_log_info(NULL, " num_luns = %d\n", num_luns);
763  ocs_log_info(NULL, " global_ramdisc = %d\n", global_ramdisc);
764  ocs_log_info(NULL, " stub_res6_rel6 = %d\n", stub_res6_rel6);
765  ocs_log_info(NULL, " ramd_threading = %d\n", ramd_threading);
766  ocs_log_info(NULL, " thread_cmds = %d\n", thread_cmds);
767  ocs_log_info(NULL, " external_dif = %s\n", external_dif);
768 #endif
769 }
770 
static void ocs_driver_print_module_params(void)
Log module parameters.
uint32_t ocs_instance(void *os)
Return instance index of an opaque ocs structure.
int32_t ocs_scsi_tgt_driver_init(void)
Driver-wide initialization for the target-server.
Definition: ocs_ramd.c:354
#define MAX_OCS_DEVICES
int32_t ocs_scsi_ini_driver_init(int32_t initiator)
Initialize initiator client.
Definition: ocs_ini_stub.c:51
int32_t ocs_device_interrupts_required(ocs_t *ocs)
return the number of interrupts required per HBA
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.
int32_t ocs_scsi_tgt_driver_exit(void)
Driver-wide clean-up for the target-server.
Definition: ocs_ramd.c:401
uint32_t ocs_hal_qtop_eq_count(ocs_hal_t *hal)
Return count of EQs for a queue topology object.
int ocs_mgmt_driver_set(char *parent, char *name, char *value)
ocs_hal_global_t hal_global
Definition: ocs_hal.c:78
void ocs_mgmt_driver_get_all(ocs_textbuf_t *textbuf, void *driver)
void ocs_device_free(ocs_t *ocs)
free ocs device
static void ocs_device_lock_init(ocs_t *ocs)
Definition: ocs_drv_fc.h:187
#define DRV_VERSION
Definition: ocs.h:49
#define MGMT_MODE_EX
Definition: ocs_mgmt.h:49
int32_t ocs_xport_detach(ocs_xport_t *xport)
Detaches the transport from the device.
Definition: ocs_xport.c:735
static void ocs_device_lock_free(ocs_t *ocs)
Definition: ocs_drv_fc.h:192
const char * name
Definition: ocs_ddump.h:54
static uint32_t thread_cmds
int32_t ocs_device_detach(ocs_t *ocs)
free resources when pci device detach
#define DRV_NAME
Definition: ocs.h:48
int ocs_mgmt_driver_exec(char *parent, char *action, void *arg_in, uint32_t arg_in_length, void *arg_out, uint32_t arg_out_length, void *driver)
void ocs_mgmt_start_unnumbered_section(ocs_textbuf_t *textbuf, const char *name)
Generate the beginning of an unnumbered section in a management XML document.
int32_t ocs_xport_attach(ocs_xport_t *xport)
Do as much allocation as possible, but do not initialization the device.
Definition: ocs_xport.c:193
void ocs_textbuf_free(ocs_t *ocs, ocs_textbuf_t *textbuf)
Definition: ocs_textbuf.c:213
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.
void ocs_ramlog_free(ocs_t *ocs, ocs_ramlog_t *ramlog)
Free a ramlog buffer.
Definition: ocs_ramlog.c:116
int32_t ocs_xport_control(ocs_xport_t *xport, ocs_xport_ctrl_e cmd,...)
Perform transport attach function.
Definition: ocs_xport.c:866
#define ocs_list_init(head, type, link)
Definition: ocs_list.h:113
static ocs_t * ocs_devices[MAX_OCS_DEVICES]
void ocs_mgmt_end_unnumbered_section(ocs_textbuf_t *textbuf, const char *name)
Generate the end of a section in a management XML document.
int32_t ocs_device_attach(ocs_t *ocs)
Initialize resources when pci devices attach.
const char * ocs_display_name(void *os)
return OCS instance display name
int32_t ocs_xport_initialize(ocs_xport_t *xport)
Initializes the device.
Definition: ocs_xport.c:509
ocs_t * ocs_get_instance(uint32_t index)
return pointer to ocs structure given instance index
static ocs_mgmt_functions_t driver_mgmt_functions
char ocs_version[]
ocs_mgmt_get_list_handler get_list_handler
Definition: ocs_mgmt.h:83
const char * queue_topology_string
Definition: ocs_hal.h:1267
#define MGMT_MODE_RD
Definition: ocs_mgmt.h:47
int32_t ocs_scsi_ini_driver_exit(int32_t initiator)
initiator client exit
Definition: ocs_ini_stub.c:103
int ocs_mgmt_driver_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *driver)
#define OCS_RAMLOG_DEFAULT_BUFFERS
Definition: ocs_ramlog.h:46
void ocs_mgmt_driver_list(ocs_textbuf_t *textbuf, void *driver)
ocs_xport_t * ocs_xport_alloc(ocs_t *ocs)
Allocate a transport object.
Definition: ocs_xport.c:71
PARAM_LIST int32_t ocs_device_init(void)
void ocs_xport_free(ocs_xport_t *xport)
Free a transport object.
Definition: ocs_xport.c:1394
void * ocs_device_alloc(uint32_t nid)
int32_t ocs_get_property(const char *prop_name, char *buffer, uint32_t buffer_len)
get driver wide property value
ocs_hal_rtn_e ocs_hal_setup(ocs_hal_t *hal, ocs_os_handle_t os, sli4_port_type_e port_type)
Set up the Hardware Abstraction Layer module.
Definition: ocs_hal.c:606
#define ocs_assert(cond,...)
Definition: ocs_debug.h:176
int32_t ocs_textbuf_alloc(ocs_t *ocs, ocs_textbuf_t *textbuf, uint32_t length)
Definition: ocs_textbuf.c:105
void * ocs_hal_get_ptr(ocs_hal_t *hal, ocs_hal_property_e prop)
Definition: ocs_hal.c:2175
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_ramlog_clear(ocs_t *ocs, ocs_ramlog_t *ramlog, int clear_start_of_day, int clear_recent)
Clear a ramlog buffer.
Definition: ocs_ramlog.c:148
#define ocs_list_foreach(list, item)
Iterate a linked list.
Definition: ocs_list.h:428
ocs_ramlog_t * ocs_ramlog_init(ocs_t *ocs, uint32_t buffer_len, uint32_t buffer_count)
Allocate a ramlog buffer.
Definition: ocs_ramlog.c:65
int ocs_gen_dump(ocs_t *ocs)
Definition: ocs_gendump.c:246
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_device_shutdown_complete(void)
Perform driver wide shutdown complete actions.