35 #include "ocs_driver.h"
37 #include "ocs_params.h"
49 void *arg_out, uint32_t arg_out_length,
void *driver);
60 #define P(type, name, value, desc) type name = value;
109 ocs = ocs_malloc(NULL,
sizeof(*ocs), OCS_M_NOWAIT | OCS_M_ZERO);
111 ocs_log_err(ocs,
"memory allocation failed for ocs_t\n");
117 ocs->instance_index = i;
124 ocs_log_err(NULL,
"failed\n");
125 ocs_free(ocs, ocs,
sizeof(*ocs));
136 if (ocs->ramlog == NULL) {
142 if (ddump_saved_size) {
144 ocs_log_err(ocs,
"failed to allocate memory for saved ddump\n");
150 #if defined(ENABLE_LOCK_DEBUG)
151 ocs_lock_init(NULL, &ocs->ocs_os.locklist_lock,
"locklist_lock[%d]", ocs->instance_index);
156 ocs->drv_ocs.attached = FALSE;
160 ocs->drv_ocs.uspace_thread_per_port = (uspacemask & (1U << 0)) == 0;
161 ocs->drv_ocs.uspace_threads_block = (uspacemask & (1U << 1)) == 0;
182 #if defined(ENABLE_LOCK_DEBUG)
184 ocs_os_t *os = &ocs->ocs_os;
188 ocs_log_test(os,
"%s not freed\n", l->name);
192 ocs_log_debug(ocs,
"all lock objects freed\n");
197 ocs_free(ocs, ocs,
sizeof(*ocs));
233 if (ocs->drv_ocs.attached) {
234 ocs_log_warn(ocs,
"Device is already attached\n");
238 ocs_snprintf(ocs->display_name,
sizeof(ocs->display_name),
"[%s%d] ",
"fc", ocs->instance_index);
240 ocs->enable_ini = initiator;
241 ocs->enable_tgt = target;
242 ocs->ctrlmask = ctrlmask;
243 ocs->topology = topology;
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;
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;
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);
268 ocs->sliport_pause_errors = sliport_pause_errors;
269 ocs->enable_bbcr = enable_bbcr;
271 ocs->tgt_rscn_delay_msec = 0;
272 ocs->tgt_rscn_period_msec = 0;
276 if (ocs->xport == NULL) {
277 ocs_log_err(ocs,
"failed to allocate transport object\n");
280 ocs_log_err(ocs,
"failed to attach transport object\n");
283 ocs_log_err(ocs,
"failed to initialize transport object\n");
286 if ((holdoff_link_online == 2) && ((!ocs->enable_tgt) && (ocs->enable_ini))) {
287 holdoff_link_online = 0;
290 if (holdoff_link_online == 0) {
296 ocs_log_err(ocs,
"failed to bring port online\n");
301 ocs->desc = ocs->hal.sli.config.modeldesc;
302 ocs_log_info(ocs,
"adapter model description: %s\n", ocs->hal.sli.config.modeldesc);
305 ocs->drv_ocs.attached = TRUE;
329 if (!ocs->drv_ocs.attached) {
330 ocs_log_warn(ocs,
"Device is not attached\n");
335 ocs_log_err(ocs,
"Transport Shutdown timed out\n");
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);
343 ocs_log_err(ocs,
"Transport detach failed\n");
348 ocs->drv_ocs.attached = FALSE;
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);
402 ocs_log_test(NULL,
"Error: unknown property %s\n", prop_name);
403 snprintf(buffer, buffer_len,
"%s",
"");
423 return ocs->display_name;
458 return ocs != NULL ? ocs->instance_index : UINT32_MAX;
500 snprintf(qualifier,
sizeof(qualifier),
"%s/driver", parent);
503 if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
504 char *unqualified_name = name + strlen(qualifier) +1;
507 if (ocs_strcmp(unqualified_name,
"global_ramdisc") == 0) {
510 }
else if (ocs_strcmp(unqualified_name,
"ramdisc_size") == 0) {
513 }
else if (ocs_strcmp(unqualified_name,
"ramdisc_blocksize") == 0) {
516 }
else if (ocs_strcmp(unqualified_name,
"num_luns") == 0) {
519 }
else if (ocs_strcmp(unqualified_name,
"initiator") == 0) {
522 }
else if (ocs_strcmp(unqualified_name,
"target") == 0) {
525 }
else if (ocs_strcmp(unqualified_name,
"logmask") == 0) {
528 }
else if (ocs_strcmp(unqualified_name,
"ctrlmask") == 0) {
531 }
else if (ocs_strcmp(unqualified_name,
"wwn_bump") == 0) {
534 }
else if (ocs_strcmp(unqualified_name,
"topology") == 0) {
537 }
else if (ocs_strcmp(unqualified_name,
"speed") == 0) {
540 }
else if (ocs_strcmp(unqualified_name,
"p_type") == 0) {
543 }
else if (ocs_strcmp(unqualified_name,
"holdoff_link_online") == 0) {
546 }
else if (ocs_strcmp(unqualified_name,
"enable_hlm") == 0) {
549 }
else if (ocs_strcmp(unqualified_name,
"enable_fw_ag_rsp") == 0) {
552 }
else if (ocs_strcmp(unqualified_name,
"hlm_group_size") == 0) {
555 }
else if (ocs_strcmp(unqualified_name,
"tow_feature") == 0) {
558 }
else if (ocs_strcmp(unqualified_name,
"tow_xri_cnt") == 0) {
561 }
else if (ocs_strcmp(unqualified_name,
"tow_io_size") == 0) {
564 }
else if (ocs_strcmp(unqualified_name,
"esoc") == 0) {
567 }
else if (ocs_strcmp(unqualified_name,
"external_loopback") == 0) {
570 }
else if (ocs_strcmp(unqualified_name,
"target_io_timer") == 0) {
622 #if defined(OCS_INCLUDE_RAMD)
642 uint32_t arg_in_length,
void *arg_out, uint32_t arg_out_length,
void *
object)
646 ocs_t *ocs = (ocs_t *)
object;
648 ocs_snprintf(qualifier,
sizeof(qualifier),
"%s/driver", parent);
651 if (ocs_strncmp(action_name, qualifier, strlen(qualifier)) == 0) {
652 char *unqualified_name = action_name + strlen(qualifier) +1;
655 if (ocs_strcmp(unqualified_name,
"gendump") == 0) {
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;
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");
669 local_arg_in[
sizeof(local_arg_in)-1] = 0;
670 if (ocs_strcmp(local_arg_in,
"recent") == 0) {
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) {
676 clear_start_of_day = 1;
680 clear_start_of_day = 1;
683 ocs_log_debug(ocs,
"Clear ramlog:%s%s\n", clear_start_of_day ?
" start_of_day" :
"",
684 clear_recent ?
" recent" :
"");
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);
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);
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.
int32_t ocs_scsi_ini_driver_init(int32_t initiator)
Initialize initiator client.
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.
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
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)
int32_t ocs_xport_detach(ocs_xport_t *xport)
Detaches the transport from the device.
static void ocs_device_lock_free(ocs_t *ocs)
static uint32_t thread_cmds
int32_t ocs_device_detach(ocs_t *ocs)
free resources when pci device detach
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.
void ocs_textbuf_free(ocs_t *ocs, ocs_textbuf_t *textbuf)
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.
int32_t ocs_xport_control(ocs_xport_t *xport, ocs_xport_ctrl_e cmd,...)
Perform transport attach function.
#define ocs_list_init(head, type, link)
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.
ocs_t * ocs_get_instance(uint32_t index)
return pointer to ocs structure given instance index
static ocs_mgmt_functions_t driver_mgmt_functions
ocs_mgmt_get_list_handler get_list_handler
const char * queue_topology_string
int32_t ocs_scsi_ini_driver_exit(int32_t initiator)
initiator client exit
int ocs_mgmt_driver_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *driver)
#define OCS_RAMLOG_DEFAULT_BUFFERS
void ocs_mgmt_driver_list(ocs_textbuf_t *textbuf, void *driver)
ocs_xport_t * ocs_xport_alloc(ocs_t *ocs)
Allocate a transport object.
PARAM_LIST int32_t ocs_device_init(void)
void ocs_xport_free(ocs_xport_t *xport)
Free a transport object.
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.
#define ocs_assert(cond,...)
int32_t ocs_textbuf_alloc(ocs_t *ocs, ocs_textbuf_t *textbuf, uint32_t length)
void * ocs_hal_get_ptr(ocs_hal_t *hal, ocs_hal_property_e prop)
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.
#define ocs_list_foreach(list, item)
Iterate a linked list.
ocs_ramlog_t * ocs_ramlog_init(ocs_t *ocs, uint32_t buffer_len, uint32_t buffer_count)
Allocate a ramlog buffer.
int ocs_gen_dump(ocs_t *ocs)
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.