/* * This file is provided under a dual BSD/GPLv2 license. When using or * redistributing this file, you may do so under either license. * * GPL LICENSE SUMMARY * * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * The full GNU General Public License is included in this distribution * in the file called LICENSE.GPL. * * BSD LICENSE * * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "isci.h" #include "host.h" #include "phy.h" #include "scu_event_codes.h" #include "probe_roms.h" #undef C #define C … static const char *phy_state_name(enum sci_phy_states state) { … } #undef C /* Maximum arbitration wait time in micro-seconds */ #define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME … enum sas_linkrate sci_phy_linkrate(struct isci_phy *iphy) { … } static struct isci_host *phy_to_host(struct isci_phy *iphy) { … } static struct device *sciphy_to_dev(struct isci_phy *iphy) { … } static enum sci_status sci_phy_transport_layer_initialization(struct isci_phy *iphy, struct scu_transport_layer_registers __iomem *reg) { … } static enum sci_status sci_phy_link_layer_initialization(struct isci_phy *iphy, struct scu_link_layer_registers __iomem *llr) { … } static void phy_sata_timeout(struct timer_list *t) { … } /** * phy_get_non_dummy_port() - This method returns the port currently containing * this phy. If the phy is currently contained by the dummy port, then the phy * is considered to not be part of a port. * * @iphy: This parameter specifies the phy for which to retrieve the * containing port. * * This method returns a handle to a port that contains the supplied phy. * NULL This value is returned if the phy is not part of a real * port (i.e. it's contained in the dummy port). !NULL All other * values indicate a handle/pointer to the port containing the phy. */ struct isci_port *phy_get_non_dummy_port(struct isci_phy *iphy) { … } /* * sci_phy_set_port() - This method will assign a port to the phy object. */ void sci_phy_set_port( struct isci_phy *iphy, struct isci_port *iport) { … } enum sci_status sci_phy_initialize(struct isci_phy *iphy, struct scu_transport_layer_registers __iomem *tl, struct scu_link_layer_registers __iomem *ll) { … } /** * sci_phy_setup_transport() - This method assigns the direct attached device ID for this phy. * * @iphy: The phy for which the direct attached device id is to * be assigned. * @device_id: The direct attached device ID to assign to the phy. * This will either be the RNi for the device or an invalid RNi if there * is no current device assigned to the phy. */ void sci_phy_setup_transport(struct isci_phy *iphy, u32 device_id) { … } static void sci_phy_suspend(struct isci_phy *iphy) { … } void sci_phy_resume(struct isci_phy *iphy) { … } void sci_phy_get_sas_address(struct isci_phy *iphy, struct sci_sas_address *sas) { … } void sci_phy_get_attached_sas_address(struct isci_phy *iphy, struct sci_sas_address *sas) { … } void sci_phy_get_protocols(struct isci_phy *iphy, struct sci_phy_proto *proto) { … } enum sci_status sci_phy_start(struct isci_phy *iphy) { … } enum sci_status sci_phy_stop(struct isci_phy *iphy) { … } enum sci_status sci_phy_reset(struct isci_phy *iphy) { … } enum sci_status sci_phy_consume_power_handler(struct isci_phy *iphy) { … } static void sci_phy_start_sas_link_training(struct isci_phy *iphy) { … } static void sci_phy_start_sata_link_training(struct isci_phy *iphy) { … } /** * sci_phy_complete_link_training - perform processing common to * all protocols upon completion of link training. * @iphy: This parameter specifies the phy object for which link training * has completed. * @max_link_rate: This parameter specifies the maximum link rate to be * associated with this phy. * @next_state: This parameter specifies the next state for the phy's starting * sub-state machine. * */ static void sci_phy_complete_link_training(struct isci_phy *iphy, enum sas_linkrate max_link_rate, u32 next_state) { … } static const char *phy_event_name(u32 event_code) { … } #define phy_event_dbg(iphy, state, code) … #define phy_event_warn(iphy, state, code) … static void scu_link_layer_set_txcomsas_timeout(struct isci_phy *iphy, u32 timeout) { … } enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code) { … } enum sci_status sci_phy_frame_handler(struct isci_phy *iphy, u32 frame_index) { … } static void sci_phy_starting_initial_substate_enter(struct sci_base_state_machine *sm) { … } static void sci_phy_starting_await_sas_power_substate_enter(struct sci_base_state_machine *sm) { … } static void sci_phy_starting_await_sas_power_substate_exit(struct sci_base_state_machine *sm) { … } static void sci_phy_starting_await_sata_power_substate_enter(struct sci_base_state_machine *sm) { … } static void sci_phy_starting_await_sata_power_substate_exit(struct sci_base_state_machine *sm) { … } static void sci_phy_starting_await_sata_phy_substate_enter(struct sci_base_state_machine *sm) { … } static void sci_phy_starting_await_sata_phy_substate_exit(struct sci_base_state_machine *sm) { … } static void sci_phy_starting_await_sata_speed_substate_enter(struct sci_base_state_machine *sm) { … } static void sci_phy_starting_await_sata_speed_substate_exit(struct sci_base_state_machine *sm) { … } static void sci_phy_starting_await_sig_fis_uf_substate_enter(struct sci_base_state_machine *sm) { … } static void sci_phy_starting_await_sig_fis_uf_substate_exit(struct sci_base_state_machine *sm) { … } static void sci_phy_starting_final_substate_enter(struct sci_base_state_machine *sm) { … } /** * scu_link_layer_stop_protocol_engine() * @iphy: This is the struct isci_phy object to stop. * * This method will stop the struct isci_phy object. This does not reset the * protocol engine it just suspends it and places it in a state where it will * not cause the end device to power up. none */ static void scu_link_layer_stop_protocol_engine( struct isci_phy *iphy) { … } static void scu_link_layer_start_oob(struct isci_phy *iphy) { … } /** * scu_link_layer_tx_hard_reset() * @iphy: This is the struct isci_phy object to stop. * * This method will transmit a hard reset request on the specified phy. The SCU * hardware requires that we reset the OOB state machine and set the hard reset * bit in the phy configuration register. We then must start OOB over with the * hard reset bit set. */ static void scu_link_layer_tx_hard_reset( struct isci_phy *iphy) { … } static void sci_phy_stopped_state_enter(struct sci_base_state_machine *sm) { … } static void sci_phy_starting_state_enter(struct sci_base_state_machine *sm) { … } static void sci_phy_ready_state_enter(struct sci_base_state_machine *sm) { … } static void sci_phy_ready_state_exit(struct sci_base_state_machine *sm) { … } static void sci_phy_resetting_state_enter(struct sci_base_state_machine *sm) { … } static const struct sci_base_state sci_phy_state_table[] = …; void sci_phy_construct(struct isci_phy *iphy, struct isci_port *iport, u8 phy_index) { … } void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index) { … } /** * isci_phy_control() - This function is one of the SAS Domain Template * functions. This is a phy management function. * @sas_phy: This parameter specifies the sphy being controlled. * @func: This parameter specifies the phy control function being invoked. * @buf: This parameter is specific to the phy function being invoked. * * status, zero indicates success. */ int isci_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, void *buf) { … }