34 #include "ocs_driver.h"
39 #if defined(OCS_INCLUDE_RAMD)
43 #include "ocs_params.h"
47 #if defined(OCS_INCLUDE_RAMD)
48 static int32_t
ocs_mgmt_read_block(ocs_t *ocs,
char *,
void *, uint32_t ,
void *, uint32_t);
55 void *arg_out, uint32_t arg_out_length,
void *driver);
84 ocs_log_err(NULL,
"ocs_scsi_tgt_init failed rc=%d\n", rc);
93 ocs_log_err(NULL,
"ocs_scsi_ini_init failed rc=%d\n", rc);
158 #if defined(OCS_INCLUDE_ISCSI)
159 if (initiator && (hw_cmpl_context == OCS_HW_CMPL_CONTEXT_THREAD)) {
160 ocs_log_test(NULL,
"iSCSI initiator requires tasklets, setting hw_cmpl_context to %d\n",
161 OCS_HW_CMPL_CONTEXT_TASKLET);
162 hw_cmpl_context = OCS_HW_CMPL_CONTEXT_TASKLET;
168 ocs = ocs_malloc(NULL,
sizeof(*ocs), OCS_M_NOWAIT | OCS_M_ZERO);
170 ocs = ocs_malloc_nid(nid,
sizeof(*ocs), OCS_M_NOWAIT | OCS_M_ZERO);
175 ocs->instance_index = i;
182 ocs_log_err(NULL,
"failed\n");
183 ocs_free(ocs, ocs,
sizeof(*ocs));
192 if (ocs->ramlog == NULL) {
198 if (ddump_saved_size) {
200 ocs_log_err(ocs,
"failed to allocate memory for saved ddump\n");
204 #if defined(ENABLE_LOCK_DEBUG)
206 ocs_lock_init(NULL, &ocs->ocs_os.locklist_lock,
"locklist_lock[%d]", ocs->instance_index);
211 ocs->drv_ocs.attached = FALSE;
212 ocs->ocs_os.hw_cmpl_context = hw_cmpl_context;
234 #if defined(ENABLE_LOCK_DEBUG)
236 ocs_os_t *os = &ocs->ocs_os;
240 ocs_log_test(os,
"%s not freed\n", l->name);
244 ocs_log_debug(ocs,
"all lock objects freed\n");
248 ocs_free(ocs, ocs,
sizeof(*ocs));
262 ocs->enable_ini = initiator;
263 ocs->enable_tgt = target;
281 if (ocs->drv_ocs.attached) {
282 ocs_log_test(ocs,
"Device is already attached\n");
285 ocs_snprintf(ocs->display_name,
sizeof(ocs->display_name),
"[%s%d] ",
"i", ocs->instance_index);
288 ocs->enable_ini = initiator;
289 ocs->enable_tgt = target;
290 ocs->num_scsi_ios = num_scsi_ios;
291 ocs->model = ocs_pci_model(ocs->pci_vendor, ocs->pci_device);
294 #if defined(OCS_INCLUDE_RAMD)
295 ocs->num_tgts = num_tgts;
296 ocs->global_ramdisc = global_ramdisc;
302 ocs_strcpy(ocs->local_ip, local_ip);
303 ocs_strcpy(ocs->local_subnet, local_subnet);
304 ocs_strcpy(ocs->iqn_prefix, iqn_prefix);
305 ocs_strcpy(ocs->iqn_suffix,
306 (iqn_suffix[ocs->instance_index] ?
307 iqn_suffix[ocs->instance_index] :
309 ocs_strcpy(ocs->gateway, gateway);
310 ocs->tcp_window_size = tcp_window_size;
311 ocs->tcp_window_scale = tcp_window_scale;
312 ocs->num_scsi_ios = num_scsi_ios;
313 ocs->ctrlmask = ctrlmask;
314 ocs->num_cxns = num_cxns;
315 ocs->hal_war_version = hal_war_version;
318 ocs->enable_sgl_chaining = (enable_sgl_chaining == 0 ? FALSE : TRUE);
319 ocs->enable_immediate_data = (enable_immediate_data == 0 ? FALSE : TRUE);
320 ocs->enable_hdr_digest = (enable_hdr_digest == 0 ? FALSE : TRUE);
321 ocs->enable_data_digest = (enable_data_digest == 0 ? FALSE : TRUE);
322 ocs->enable_jumbo_frame = (enable_jumbo_frame == 0 ? FALSE : TRUE);
323 ocs->require_chap = FALSE;
326 ocs->target_io_timer_sec = 0;
328 if (max_sge_size < 1024 &&
329 max_sge_size > 65536) {
330 ocs_log_test(ocs,
"Ignoring invalid max_sge_size\n");
332 ocs->max_sge_size = max_sge_size;
334 ocs->post_sgl_config = post_sgl_config;
341 ocs->desc = ocs->hal.sli.config.modeldesc;
342 ocs_log_info(ocs,
"adapter model description: %s\n", ocs->hal.sli.config.modeldesc);
344 ocs->drv_ocs.attached = TRUE;
346 ocs_teardown_msix((ocs_os_t *)ocs);
381 if (!ocs->drv_ocs.attached) {
382 ocs_log_test(ocs,
"Device is not attached\n");
389 ocs_intr_disable(ocs);
392 ocs_log_err(ocs,
"ocs_iscsi_teardown failed\n");
400 ocs->drv_ocs.attached = FALSE;
422 if (ocs_strcmp(prop_name,
"initiator") == 0) {
423 ocs_snprintf(buffer, buffer_len,
"%d", initiator);
424 }
else if (ocs_strcmp(prop_name,
"target") == 0) {
425 ocs_snprintf(buffer, buffer_len,
"%d", target);
426 #if defined(OCS_INCLUDE_RAMD)
427 }
else if (ocs_strcmp(prop_name,
"global_ramdisc") == 0) {
428 ocs_snprintf(buffer, buffer_len,
"%d", global_ramdisc);
429 }
else if (ocs_strcmp(prop_name,
"ramdisc_size") == 0) {
430 ocs_strncpy(buffer, ramdisc_size, buffer_len);
431 }
else if (ocs_strcmp(prop_name,
"ramdisc_blocksize") == 0) {
432 ocs_snprintf(buffer, buffer_len,
"%d", ramdisc_blocksize);
433 }
else if (ocs_strcmp(prop_name,
"num_luns") == 0) {
434 ocs_snprintf(buffer, buffer_len,
"%d", num_luns);
435 }
else if (ocs_strcmp(prop_name,
"p_type") == 0) {
436 ocs_snprintf(buffer, buffer_len,
"%d", p_type);
437 }
else if (ocs_strcmp(prop_name,
"stub_res6_rel6") == 0) {
438 ocs_snprintf(buffer, buffer_len,
"%d", stub_res6_rel6);
439 }
else if (strcmp(prop_name,
"ramd_threading") == 0) {
440 ocs_snprintf(buffer, buffer_len,
"%d", ramd_threading);
441 }
else if (strcmp(prop_name,
"thread_cmds") == 0) {
442 ocs_snprintf(buffer, buffer_len,
"%d",
thread_cmds);
443 }
else if (strcmp(prop_name,
"external_dif") == 0) {
444 ocs_strncpy(buffer, external_dif, buffer_len);
445 }
else if (ocs_strcmp(prop_name,
"num_tgts") == 0) {
446 ocs_snprintf(buffer, buffer_len,
"%d", num_tgts);
448 }
else if (ocs_strcmp(prop_name,
"dif_separate") == 0) {
450 ocs_snprintf(buffer, buffer_len,
"%d", 1);
452 ocs_log_test(NULL,
"Error: unknown property %s\n", prop_name);
453 ocs_snprintf(buffer, buffer_len,
"%s",
"");
473 return ocs->display_name;
526 ocs_snprintf(qualifier,
sizeof(qualifier),
"%s/driver", parent);
529 if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
530 char *unqualified_name = name + strlen(qualifier) +1;
533 if (ocs_strcmp(unqualified_name,
"ctrlmask") == 0) {
536 }
else if (ocs_strcmp(unqualified_name,
"num_cxns") == 0) {
539 }
else if (ocs_strcmp(unqualified_name,
"ddump_saved_size") == 0) {
542 }
else if (ocs_strcmp(unqualified_name,
"enable_data_digest") == 0) {
545 }
else if (ocs_strcmp(unqualified_name,
"enable_hdr_digest") == 0) {
548 }
else if (ocs_strcmp(unqualified_name,
"enable_immediate_data") == 0) {
551 }
else if (ocs_strcmp(unqualified_name,
"enable_jumbo_frame") == 0) {
554 }
else if (ocs_strcmp(unqualified_name,
"enable_sgl_chaining") == 0) {
557 }
else if (ocs_strcmp(unqualified_name,
"gateway") == 0) {
560 }
else if (ocs_strcmp(unqualified_name,
"hal_war_version") == 0) {
563 }
else if (ocs_strcmp(unqualified_name,
"hw_cmpl_context") == 0) {
566 }
else if (ocs_strcmp(unqualified_name,
"initiator") == 0) {
569 }
else if (ocs_strcmp(unqualified_name,
"local_ip") == 0) {
572 }
else if (ocs_strcmp(unqualified_name,
"local_subnet") == 0) {
575 }
else if (ocs_strcmp(unqualified_name,
"logdest") == 0) {
578 }
else if (ocs_strcmp(unqualified_name,
"max_sge_size") == 0) {
581 }
else if (ocs_strcmp(unqualified_name,
"num_scsi_ios") == 0) {
584 }
else if (ocs_strcmp(unqualified_name,
"post_sgl_config") == 0) {
587 #if defined(OCS_INCLUDE_RAMD)
588 }
else if (ocs_strcmp(unqualified_name,
"num_luns") == 0) {
591 }
else if (ocs_strcmp(unqualified_name,
"global_ramdisc") == 0) {
594 }
else if (ocs_strcmp(unqualified_name,
"ramdisc_blocksize") == 0) {
597 }
else if (ocs_strcmp(unqualified_name,
"ramdisc_size") == 0) {
600 }
else if (ocs_strcmp(unqualified_name,
"num_tgts") == 0) {
604 }
else if (ocs_strcmp(unqualified_name,
"ramlog_size") == 0) {
607 }
else if (ocs_strcmp(unqualified_name,
"target") == 0) {
610 }
else if (ocs_strcmp(unqualified_name,
"tcp_window_scale") == 0) {
613 }
else if (ocs_strcmp(unqualified_name,
"tcp_window_size") == 0) {
646 #if defined(OCS_INCLUDE_RAMD)
663 uint32_t arg_in_length,
void *arg_out, uint32_t arg_out_length,
void *
object)
667 ocs_t *ocs = (ocs_t *)
object;
669 ocs_snprintf(qualifier,
sizeof(qualifier),
"%s/driver", parent);
672 if (ocs_strncmp(action_name, qualifier, strlen(qualifier)) == 0) {
673 char *unqualified_name = action_name + strlen(qualifier) +1;
675 if (ocs_strcmp(unqualified_name,
"clear_ramlog") == 0) {
676 char local_arg_in[128];
677 int clear_start_of_day = 0;
678 int clear_recent = 0;
680 if (ocs_copy_from_user(local_arg_in, arg_in,
681 MIN(arg_in_length,
sizeof(local_arg_in)-1))) {
682 ocs_log_test(ocs,
"Error: copy arg_in from user failed\n");
686 local_arg_in[
sizeof(local_arg_in)-1] = 0;
687 if (ocs_strcmp(local_arg_in,
"recent") == 0) {
689 }
else if (ocs_strcmp(local_arg_in,
"start_of_day") == 0) {
690 clear_start_of_day = 1;
691 }
else if (ocs_strcmp(local_arg_in,
"all") == 0) {
693 clear_start_of_day = 1;
697 clear_start_of_day = 1;
700 ocs_log_debug(ocs,
"Clear ramlog:%s%s\n", clear_start_of_day ?
" start_of_day" :
"",
701 clear_recent ?
" recent" :
"");
706 #if defined(OCS_INCLUDE_RAMD)
707 if (ocs_strcmp(unqualified_name,
"read_block") == 0) {
709 arg_out, arg_out_length);
717 #if defined(OCS_INCLUDE_RAMD)
719 ocs_mgmt_read_block(ocs_t *ocs,
char *name,
void *arg_in, uint32_t arg_in_length,
void *arg_out, uint32_t arg_out_length)
724 char input_buffer[80];
729 if ((arg_in == NULL) ||
730 (arg_in_length == 0) ||
732 (arg_out_length == 0)) {
736 if (arg_in_length >
sizeof(input_buffer)) {
737 arg_in_length =
sizeof(input_buffer);
740 if (ocs_copy_from_user(input_buffer, arg_in, arg_in_length)) {
741 ocs_log_test(ocs,
"Failed to copy addr from user\n");
745 if (ocs_sscanf(input_buffer,
"%d:%d:%d", &tgt, &lun, &lba) != 3) {
750 if (ramdisc == NULL) {
756 length = arg_out_length;
758 if (ocs_copy_to_user(arg_out, block, length)) {
759 ocs_log_test(ocs,
"Failed to copy buffer to user\n");
int32_t ocs_device_detach(ocs_t *ocs)
Remove the PCI device instance.
const char * ocs_display_name(void *os)
int32_t ocs_scsi_tgt_driver_init(void)
Driver-wide initialization for the target-server.
int32_t ocs_get_property(const char *prop_name, char *buffer, uint32_t buffer_len)
void ocs_device_shutdown(void)
Perform driver-wide shut down actions.
uint8_t * ocs_ramdisc_lba_address(ocs_ramdisc_t *ramdisc, uint64_t lba)
Return the address of a ramdisc logical block.
int32_t ocs_scsi_ini_driver_init(int32_t initiator)
Initialize initiator client.
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.
#define OCS_IQN_SUFFIX_DEFAULT
static void ocs_device_lock_init(ocs_t *ocs)
ocs_t * ocs_devices[MAX_OCS_DEVICES]
void * ocs_device_alloc(uint32_t nid)
Instantiate the PCI device.
void ocs_device_free(ocs_t *ocs)
static void ocs_device_lock_free(ocs_t *ocs)
static uint32_t thread_cmds
void ocs_iscsi_cxn_req_invalidate(ocs_iscsi_t *iscsi)
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_device_interrupts_required(ocs_t *ocs)
Returns the number of interrupts required per HBA.
ramdisc instance structure
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.
int32_t ocs_device_attach(ocs_t *ocs)
void ocs_ramlog_free(ocs_t *ocs, ocs_ramlog_t *ramlog)
Free a ramlog buffer.
void ocs_device_shutdown_complete(void)
Perform driver-wide shutdown complete actions.
#define ocs_list_init(head, type, link)
int32_t ocs_start_event_processing(ocs_os_t *ocs_os)
int32_t ocs_hal_process(ocs_hal_t *hal, uint32_t vector, uint32_t max_isr_time_msec)
Process events associated with the interrupt vector.
void ocs_mgmt_end_unnumbered_section(ocs_textbuf_t *textbuf, const char *name)
Generate the end of a section in a management XML document.
ocs_ramdisc_t * ocs_ramd_lookup_by_tgt(ocs_t *ocs, uint32_t tgt, uint32_t lun)
Given an TGT number and a LUN number, return the corresponding ramdisc.
void ocs_mgmt_driver_list(ocs_textbuf_t *textbuf, void *driver)
PARAM_LIST int32_t ocs_device_init(void)
Perform driver-wide initialization.
ocs_mgmt_get_list_handler get_list_handler
int32_t ocs_iscsi_initialize(ocs_os_handle_t os, ocs_iscsi_t *iscsi, ocs_hal_t *hal, uint32_t device_instance)
Initialize the iSCSI device by setting up the chip.
int32_t ocs_iscsi_teardown(ocs_iscsi_t *iscsi)
Shut down the device.
int32_t ocs_scsi_ini_driver_exit(int32_t initiator)
initiator client exit
#define OCS_RAMLOG_DEFAULT_BUFFERS
int32_t ocs_iscsi_interrupts_required(ocs_os_handle_t os, ocs_hal_t *hal)
Returns the number of interrupts needed for this adapter.
void ocs_stop_event_processing(ocs_os_t *ocs_os)
void ocs_mgmt_driver_get_all(ocs_textbuf_t *textbuf, void *driver)
void ocs_xport_free(ocs_xport_t *xport)
free a transport object
#define ocs_assert(cond,...)
int32_t ocs_device_init_complete(void)
Perform device initialization complete.
int32_t ocs_textbuf_alloc(ocs_t *ocs, ocs_textbuf_t *textbuf, uint32_t length)
static void ocs_device_interrupt_handler(ocs_t *ocs, uint32_t vector)
interrupt handler
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.
static int32_t ocs_mgmt_read_block(ocs_t *ocs, char *, void *, uint32_t, void *, uint32_t)
static ocs_mgmt_functions_t driver_mgmt_functions
#define OCS_ISCSI_MAX_CXNS_PER_SESSION
ocs_ramlog_t * ocs_ramlog_init(ocs_t *ocs, uint32_t buffer_len, uint32_t buffer_count)
Allocate a ramlog buffer.
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.
int ocs_mgmt_driver_get(ocs_textbuf_t *textbuf, char *parent, char *name, void *driver)