/* * Function name: tw_cl_shutdown_ctlr * Description: Closes logical connection with the controller. * * Input: ctlr -- ptr to per ctlr structure * flags -- more info passed by the OS Layer * Output: None * Return value: 0 -- success * non-zero-- failure */ TW_INT32 tw_cl_shutdown_ctlr(struct tw_cl_ctlr_handle *ctlr_handle, TW_UINT32 flags) { struct tw_cli_ctlr_context *ctlr = (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt); TW_INT32 error; tw_cli_dbg_printf(3, ctlr_handle, tw_osl_cur_func(), "entered"); /* * Mark the controller as inactive, disable any further interrupts, * and notify the controller that we are going down. */ ctlr->state &= ~TW_CLI_CTLR_STATE_ACTIVE; tw_cli_disable_interrupts(ctlr); /* Let the controller know that we are going down. */ if ((error = tw_cli_init_connection(ctlr, TWA_SHUTDOWN_MESSAGE_CREDITS, 0, 0, 0, 0, 0, TW_CL_NULL, TW_CL_NULL, TW_CL_NULL, TW_CL_NULL, TW_CL_NULL))) tw_cl_create_event(ctlr_handle, TW_CL_FALSE, TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 0x1015, 0x1, TW_CL_SEVERITY_ERROR_STRING, "Can't close connection with controller", "error = %d", error); if (flags & TW_CL_STOP_CTLR_ONLY) goto ret; /* Destroy all locks used by CL. */ tw_osl_destroy_lock(ctlr_handle, ctlr->gen_lock); tw_osl_destroy_lock(ctlr_handle, ctlr->io_lock); if (!(ctlr->flags & TW_CL_64BIT_ADDRESSES)) tw_osl_destroy_lock(ctlr_handle, ctlr->intr_lock); ret: return(error); }
/* * Function name: tw_cli_start_ctlr * Description: Establishes a logical connection with the controller. * Determines whether or not the driver is compatible * with the firmware on the controller, before proceeding * to work with it. * * Input: ctlr -- ptr to per ctlr structure * Output: None * Return value: 0 -- success * non-zero-- failure */ TW_INT32 tw_cli_start_ctlr(struct tw_cli_ctlr_context *ctlr) { TW_UINT16 fw_on_ctlr_srl = 0; TW_UINT16 fw_on_ctlr_arch_id = 0; TW_UINT16 fw_on_ctlr_branch = 0; TW_UINT16 fw_on_ctlr_build = 0; TW_UINT32 init_connect_result = 0; TW_INT32 error = TW_OSL_ESUCCESS; tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); /* Wait for the controller to become ready. */ if ((error = tw_cli_poll_status(ctlr, TWA_STATUS_MICROCONTROLLER_READY, TW_CLI_REQUEST_TIMEOUT_PERIOD))) { tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 0x1009, 0x1, TW_CL_SEVERITY_ERROR_STRING, "Microcontroller not ready", "error = %d", error); return(error); } /* Drain the response queue. */ if ((error = tw_cli_drain_response_queue(ctlr))) { tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 0x100A, 0x1, TW_CL_SEVERITY_ERROR_STRING, "Can't drain response queue", "error = %d", error); return(error); } /* Establish a logical connection with the controller. */ if ((error = tw_cli_init_connection(ctlr, (TW_UINT16)(ctlr->max_simult_reqs), TWA_EXTENDED_INIT_CONNECT, TWA_CURRENT_FW_SRL, (TW_UINT16)(ctlr->arch_id), TWA_CURRENT_FW_BRANCH(ctlr->arch_id), TWA_CURRENT_FW_BUILD(ctlr->arch_id), &fw_on_ctlr_srl, &fw_on_ctlr_arch_id, &fw_on_ctlr_branch, &fw_on_ctlr_build, &init_connect_result))) { tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 0x100B, 0x2, TW_CL_SEVERITY_WARNING_STRING, "Can't initialize connection in current mode", "error = %d", error); return(error); } { /* See if we can at least work with the firmware on the * controller in the current mode. */ if (init_connect_result & TWA_CTLR_FW_COMPATIBLE) { /* Yes, we can. Make note of the operating mode. */ if (init_connect_result & TWA_CTLR_FW_SAME_OR_NEWER) { ctlr->working_srl = TWA_CURRENT_FW_SRL; ctlr->working_branch = TWA_CURRENT_FW_BRANCH(ctlr->arch_id); ctlr->working_build = TWA_CURRENT_FW_BUILD(ctlr->arch_id); } else { ctlr->working_srl = fw_on_ctlr_srl; ctlr->working_branch = fw_on_ctlr_branch; ctlr->working_build = fw_on_ctlr_build; } } else { /* * No, we can't. See if we can at least work with * it in the base mode. */ tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 0x1010, 0x2, TW_CL_SEVERITY_WARNING_STRING, "Driver/Firmware mismatch. " "Negotiating for base level...", " "); if ((error = tw_cli_init_connection(ctlr, (TW_UINT16)(ctlr->max_simult_reqs), TWA_EXTENDED_INIT_CONNECT, TWA_BASE_FW_SRL, (TW_UINT16)(ctlr->arch_id), TWA_BASE_FW_BRANCH, TWA_BASE_FW_BUILD, &fw_on_ctlr_srl, &fw_on_ctlr_arch_id, &fw_on_ctlr_branch, &fw_on_ctlr_build, &init_connect_result))) { tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 0x1011, 0x1, TW_CL_SEVERITY_ERROR_STRING, "Can't initialize connection in " "base mode", " "); return(error); } if (!(init_connect_result & TWA_CTLR_FW_COMPATIBLE)) { /* * The firmware on the controller is not even * compatible with our base mode. We cannot * work with it. Bail... */ return(1); } /* * We can work with this firmware, but only in * base mode. */ ctlr->working_srl = TWA_BASE_FW_SRL; ctlr->working_branch = TWA_BASE_FW_BRANCH; ctlr->working_build = TWA_BASE_FW_BUILD; ctlr->operating_mode = TWA_BASE_MODE; } ctlr->fw_on_ctlr_srl = fw_on_ctlr_srl; ctlr->fw_on_ctlr_branch = fw_on_ctlr_branch; ctlr->fw_on_ctlr_build = fw_on_ctlr_build; } /* Drain the AEN queue */ if ((error = tw_cli_drain_aen_queue(ctlr))) /* * We will just print that we couldn't drain the AEN queue. * There's no need to bail out. */ tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 0x1014, 0x2, TW_CL_SEVERITY_WARNING_STRING, "Can't drain AEN queue", "error = %d", error); /* Enable interrupts. */ tw_cli_enable_interrupts(ctlr); return(TW_OSL_ESUCCESS); }