2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 #include "intel_ata.h"
57 #include "intel_sata.h"
58 #include "sci_base_state.h"
59 #include "sci_base_state_machine.h"
61 #include "scic_sds_controller.h"
62 #include "scic_sds_phy.h"
63 #include "scic_sds_phy_registers.h"
64 #include "scic_sds_port.h"
65 #include "scic_user_callback.h"
66 #include "sci_environment.h"
68 #include "scu_event_codes.h"
70 #define SCIC_SDS_PHY_MIN_TIMER_COUNT (SCI_MAX_PHYS)
71 #define SCIC_SDS_PHY_MAX_TIMER_COUNT (SCI_MAX_PHYS)
73 /* Maximum arbitration wait time in micro-seconds */
74 #define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700)
77 * *****************************************************************************
78 * * SCIC SDS PHY Internal Methods
79 * ***************************************************************************** */
82 * This method will initialize the phy link layer registers
84 * @link_layer_registers:
88 static enum sci_status scic_sds_phy_link_layer_initialization(
89 struct scic_sds_phy *this_phy,
90 struct scu_link_layer_registers *link_layer_registers)
92 u32 phy_configuration;
93 struct sas_capabilities phy_capabilities;
96 u32 link_layer_control;
98 this_phy->link_layer_registers = link_layer_registers;
100 /* Set our IDENTIFY frame data */
101 #define SCI_END_DEVICE 0x01
105 (SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR)
106 | SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR)
107 | SCU_SAS_TIID_GEN_BIT(STP_INITIATOR)
108 | SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST)
109 | SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE, SCI_END_DEVICE))
112 /* Write the device SAS Address */
113 SCU_SAS_TIDNH_WRITE(this_phy, 0xFEDCBA98);
114 SCU_SAS_TIDNL_WRITE(this_phy, this_phy->phy_index);
116 /* Write the source SAS Address */
117 SCU_SAS_TISSAH_WRITE(
119 this_phy->owning_port->owning_controller->oem_parameters.sds1.phys[
120 this_phy->phy_index].sas_address.high
122 SCU_SAS_TISSAL_WRITE(
124 this_phy->owning_port->owning_controller->oem_parameters.sds1.phys[
125 this_phy->phy_index].sas_address.low
128 /* Clear and Set the PHY Identifier */
129 SCU_SAS_TIPID_WRITE(this_phy, 0x00000000);
130 SCU_SAS_TIPID_WRITE(this_phy, SCU_SAS_TIPID_GEN_VALUE(ID, this_phy->phy_index));
132 /* Change the initial state of the phy configuration register */
133 phy_configuration = SCU_SAS_PCFG_READ(this_phy);
135 /* Hold OOB state machine in reset */
136 phy_configuration |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
137 SCU_SAS_PCFG_WRITE(this_phy, phy_configuration);
139 /* Configure the SNW capabilities */
140 phy_capabilities.u.all = 0;
141 phy_capabilities.u.bits.start = 1;
142 phy_capabilities.u.bits.gen3_without_ssc_supported = 1;
143 phy_capabilities.u.bits.gen2_without_ssc_supported = 1;
144 phy_capabilities.u.bits.gen1_without_ssc_supported = 1;
145 if (this_phy->owning_port->owning_controller->oem_parameters.sds1.
146 controller.do_enable_ssc == true) {
147 phy_capabilities.u.bits.gen3_with_ssc_supported = 1;
148 phy_capabilities.u.bits.gen2_with_ssc_supported = 1;
149 phy_capabilities.u.bits.gen1_with_ssc_supported = 1;
153 * The SAS specification indicates that the phy_capabilities that
154 * are transmitted shall have an even parity. Calculate the parity. */
155 parity_check = phy_capabilities.u.all;
156 while (parity_check != 0) {
157 if (parity_check & 0x1)
163 * If parity indicates there are an odd number of bits set, then
164 * set the parity bit to 1 in the phy capabilities. */
165 if ((parity_count % 2) != 0)
166 phy_capabilities.u.bits.parity = 1;
168 SCU_SAS_PHYCAP_WRITE(this_phy, phy_capabilities.u.all);
170 /* Set the enable spinup period but disable the ability to send notify enable spinup */
171 SCU_SAS_ENSPINUP_WRITE(this_phy, SCU_ENSPINUP_GEN_VAL(COUNT, 0x33));
173 #if defined(CONFIG_PBG_HBA_A0) || defined(CONFIG_PBG_HBA_A2) || defined(CONFIG_PBG_HBA_BETA)
174 /* / @todo Provide a way to write this register correctly */
175 scu_link_layer_register_write(this_phy, afe_lookup_table_control, 0x02108421);
177 /* / @todo Provide a way to write this register correctly */
178 scu_link_layer_register_write(this_phy, afe_lookup_table_control, 0x0e739ce7);
181 link_layer_control = SCU_SAS_LLCTL_GEN_VAL(
182 NO_OUTBOUND_TASK_TIMEOUT,
183 (u8)this_phy->owning_port->owning_controller->
184 user_parameters.sds1.no_outbound_task_timeout
187 /* #define COMPILED_MAX_LINK_RATE SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1 */
188 /* #define COMPILED_MAX_LINK_RATE SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2 */
189 #define COMPILED_MAX_LINK_RATE SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3
191 if (this_phy->owning_port->owning_controller->user_parameters.sds1.
192 phys[this_phy->phy_index].max_speed_generation == SCIC_SDS_PARM_GEN3_SPEED) {
193 link_layer_control |= SCU_SAS_LLCTL_GEN_VAL(
194 MAX_LINK_RATE, COMPILED_MAX_LINK_RATE
196 } else if (this_phy->owning_port->owning_controller->user_parameters.sds1.
197 phys[this_phy->phy_index].max_speed_generation == SCIC_SDS_PARM_GEN2_SPEED) {
198 link_layer_control |= SCU_SAS_LLCTL_GEN_VAL(
201 SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2,
202 COMPILED_MAX_LINK_RATE)
205 link_layer_control |= SCU_SAS_LLCTL_GEN_VAL(
208 SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1,
209 COMPILED_MAX_LINK_RATE)
213 scu_link_layer_register_write(
214 this_phy, link_layer_control, link_layer_control
218 * Program the max ARB time for the PHY to 700us so we inter-operate with
219 * the PMC expander which shuts down PHYs if the expander PHY generates too
220 * many breaks. This time value will guarantee that the initiator PHY will
221 * generate the break. */
222 #if defined(CONFIG_PBG_HBA_A0) || defined(CONFIG_PBG_HBA_A2)
223 scu_link_layer_register_write(
225 maximum_arbitration_wait_timer_timeout,
226 SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME
228 #endif /* defined(CONFIG_PBG_HBA_A0) || defined(CONFIG_PBG_HBA_A2) */
231 * Set the link layer hang detection to 500ms (0x1F4) from its default
232 * value of 128ms. Max value is 511 ms. */
233 scu_link_layer_register_write(
234 this_phy, link_layer_hang_detection_timeout, 0x1F4
237 /* We can exit the initial state to the stopped state */
238 sci_base_state_machine_change_state(
239 scic_sds_phy_get_base_state_machine(this_phy),
240 SCI_BASE_PHY_STATE_STOPPED
247 * This function will handle the sata SIGNATURE FIS timeout condition. It will
248 * restart the starting substate machine since we dont know what has actually
251 static void scic_sds_phy_sata_timeout(void *phy)
253 struct scic_sds_phy *sci_phy = phy;
255 dev_dbg(sciphy_to_dev(sci_phy),
256 "%s: SCIC SDS Phy 0x%p did not receive signature fis before "
261 sci_base_state_machine_stop(
262 scic_sds_phy_get_starting_substate_machine(sci_phy));
264 sci_base_state_machine_change_state(
265 scic_sds_phy_get_base_state_machine(sci_phy),
266 SCI_BASE_PHY_STATE_STARTING
271 * *****************************************************************************
272 * * SCIC SDS PHY External Methods
273 * ***************************************************************************** */
276 * This method returns the object size for a phy object.
282 * This method returns the minimum number of timers required for a phy object.
288 * This method returns the maximum number of timers required for a phy object.
293 #ifdef SCIC_DEBUG_ENABLED
295 * scic_sds_phy_observe_state_change() -
298 * Debug code to record the state transitions in the phy
300 void scic_sds_phy_observe_state_change(
301 struct sci_base_observer *our_observer,
302 struct sci_base_subject *the_subject)
304 struct scic_sds_phy *this_phy;
305 struct sci_base_state_machine *the_state_machine;
307 u8 transition_requestor;
309 u32 starting_substate_id;
311 the_state_machine = (struct sci_base_state_machine *)the_subject;
312 this_phy = (struct scic_sds_phy *)the_state_machine->state_machine_owner;
314 if (the_state_machine == &this_phy->parent.state_machine) {
315 transition_requestor = 0x01;
316 } else if (the_state_machine == &this_phy->starting_substate_machine) {
317 transition_requestor = 0x02;
319 transition_requestor = 0xFF;
323 sci_base_state_machine_get_state(&this_phy->parent.state_machine);
324 starting_substate_id =
325 sci_base_state_machine_get_state(&this_phy->starting_substate_machine);
327 this_phy->state_record.state_transition_table[
328 this_phy->state_record.index++] = ((transition_requestor << 24)
329 | ((u8)base_state_id << 8)
330 | ((u8)starting_substate_id));
332 this_phy->state_record.index =
333 this_phy->state_record.index & (MAX_STATE_TRANSITION_RECORD - 1);
336 #endif /* SCIC_DEBUG_ENABLED */
338 #ifdef SCIC_DEBUG_ENABLED
340 * scic_sds_phy_initialize_state_recording() -
342 * This method initializes the state record debug information for the phy
343 * object. The state machines for the phy object must be constructed before
344 * this function is called.
346 void scic_sds_phy_initialize_state_recording(
347 struct scic_sds_phy *this_phy)
349 this_phy->state_record.index = 0;
351 sci_base_observer_initialize(
352 &this_phy->state_record.base_state_observer,
353 scic_sds_phy_observe_state_change,
354 &this_phy->parent.state_machine.parent
357 sci_base_observer_initialize(
358 &this_phy->state_record.starting_state_observer,
359 scic_sds_phy_observe_state_change,
360 &this_phy->starting_substate_machine.parent
363 #endif /* SCIC_DEBUG_ENABLED */
366 * This method will construct the struct scic_sds_phy object
372 void scic_sds_phy_construct(
373 struct scic_sds_phy *this_phy,
374 struct scic_sds_port *owning_port,
378 * Call the base constructor first
380 sci_base_phy_construct(
382 scic_sds_phy_state_table
385 /* Copy the rest of the input data to our locals */
386 this_phy->owning_port = owning_port;
387 this_phy->phy_index = phy_index;
388 this_phy->bcn_received_while_port_unassigned = false;
389 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
390 this_phy->link_layer_registers = NULL;
391 this_phy->max_negotiated_speed = SCI_SAS_NO_LINK_RATE;
393 /* Clear out the identification buffer data */
394 memset(&this_phy->phy_type, 0, sizeof(this_phy->phy_type));
396 /* Initialize the the substate machines */
397 sci_base_state_machine_construct(
398 &this_phy->starting_substate_machine,
399 &this_phy->parent.parent,
400 scic_sds_phy_starting_substates,
401 SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
404 #ifdef SCIC_DEBUG_ENABLED
405 scic_sds_phy_initialize_state_recording(this_phy);
406 #endif /* SCIC_DEBUG_ENABLED */
410 * This method returns the port currently containing this phy. If the phy is
411 * currently contained by the dummy port, then the phy is considered to not
413 * @this_phy: This parameter specifies the phy for which to retrieve the
416 * This method returns a handle to a port that contains the supplied phy.
417 * SCI_INVALID_HANDLE This value is returned if the phy is not part of a real
418 * port (i.e. it's contained in the dummy port). !SCI_INVALID_HANDLE All other
419 * values indicate a handle/pointer to the port containing the phy.
421 struct scic_sds_port *scic_sds_phy_get_port(
422 struct scic_sds_phy *this_phy)
424 if (scic_sds_port_get_index(this_phy->owning_port) == SCIC_SDS_DUMMY_PORT)
425 return SCI_INVALID_HANDLE;
427 return this_phy->owning_port;
431 * This method will assign a port to the phy object.
432 * @out]: this_phy This parameter specifies the phy for which to assign a port
437 void scic_sds_phy_set_port(
438 struct scic_sds_phy *this_phy,
439 struct scic_sds_port *the_port)
441 this_phy->owning_port = the_port;
443 if (this_phy->bcn_received_while_port_unassigned) {
444 this_phy->bcn_received_while_port_unassigned = false;
445 scic_sds_port_broadcast_change_received(this_phy->owning_port, this_phy);
450 * This method will initialize the constructed phy
452 * @link_layer_registers:
456 enum sci_status scic_sds_phy_initialize(
457 struct scic_sds_phy *sci_phy,
458 struct scu_link_layer_registers *link_layer_registers)
460 /* Create the SIGNATURE FIS Timeout timer for this phy */
461 sci_phy->sata_timeout_timer = scic_cb_timer_create(
462 scic_sds_phy_get_controller(sci_phy),
463 scic_sds_phy_sata_timeout,
467 /* Perofrm the initialization of the PE hardware */
468 scic_sds_phy_link_layer_initialization(sci_phy, link_layer_registers);
471 * There is nothing that needs to be done in this state just
472 * transition to the stopped state. */
473 sci_base_state_machine_change_state(
474 scic_sds_phy_get_base_state_machine(sci_phy),
475 SCI_BASE_PHY_STATE_STOPPED
484 * @this_phy: The phy object to be suspended.
486 * This function will perform the register reads/writes to suspend the SCU
487 * hardware protocol engine. none
489 void scic_sds_phy_suspend(
490 struct scic_sds_phy *this_phy)
492 u32 scu_sas_pcfg_value;
494 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
496 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
498 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
503 * @this_phy: The phy object to resume.
505 * This function will perform the register reads/writes required to resume the
506 * SCU hardware protocol engine. none
508 void scic_sds_phy_resume(
509 struct scic_sds_phy *this_phy)
511 u32 scu_sas_pcfg_value;
513 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
515 scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
517 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
521 * This method returns the local sas address assigned to this phy.
522 * @this_phy: This parameter specifies the phy for which to retrieve the local
524 * @sas_address: This parameter specifies the location into which to copy the
528 void scic_sds_phy_get_sas_address(
529 struct scic_sds_phy *this_phy,
530 struct sci_sas_address *sas_address)
532 sas_address->high = SCU_SAS_TISSAH_READ(this_phy);
533 sas_address->low = SCU_SAS_TISSAL_READ(this_phy);
537 * This method returns the remote end-point (i.e. attached) sas address
538 * assigned to this phy.
539 * @this_phy: This parameter specifies the phy for which to retrieve the remote
540 * end-point SAS address.
541 * @sas_address: This parameter specifies the location into which to copy the
542 * remote end-point SAS address.
545 void scic_sds_phy_get_attached_sas_address(
546 struct scic_sds_phy *this_phy,
547 struct sci_sas_address *sas_address)
550 = this_phy->phy_type.sas.identify_address_frame_buffer.sas_address.high;
552 = this_phy->phy_type.sas.identify_address_frame_buffer.sas_address.low;
556 * This method returns the supported protocols assigned to this phy
561 void scic_sds_phy_get_protocols(
562 struct scic_sds_phy *this_phy,
563 struct sci_sas_identify_address_frame_protocols *protocols)
565 protocols->u.all = (u16)(SCU_SAS_TIID_READ(this_phy) & 0x0000FFFF);
570 * @this_phy: The parameter is the phy object for which the attached phy
571 * protcols are to be returned.
573 * This method returns the supported protocols for the attached phy. If this
574 * is a SAS phy the protocols are returned from the identify address frame. If
575 * this is a SATA phy then protocols are made up and the target phy is an STP
576 * target phy. The caller will get the entire set of bits for the protocol
579 void scic_sds_phy_get_attached_phy_protocols(
580 struct scic_sds_phy *this_phy,
581 struct sci_sas_identify_address_frame_protocols *protocols)
583 protocols->u.all = 0;
585 if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
587 this_phy->phy_type.sas.identify_address_frame_buffer.protocols.u.all;
588 } else if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) {
589 protocols->u.bits.stp_target = 1;
594 * *****************************************************************************
595 * * SCIC SDS PHY Handler Redirects
596 * ***************************************************************************** */
599 * This method will attempt to start the phy object. This request is only valid
600 * when the phy is in the stopped state
605 enum sci_status scic_sds_phy_start(
606 struct scic_sds_phy *this_phy)
608 return this_phy->state_handlers->parent.start_handler(&this_phy->parent);
612 * This method will attempt to stop the phy object.
615 * enum sci_status SCI_SUCCESS if the phy is going to stop SCI_INVALID_STATE if the
616 * phy is not in a valid state to stop
618 enum sci_status scic_sds_phy_stop(
619 struct scic_sds_phy *this_phy)
621 return this_phy->state_handlers->parent.stop_handler(&this_phy->parent);
625 * This method will attempt to reset the phy. This request is only valid when
626 * the phy is in an ready state
631 enum sci_status scic_sds_phy_reset(
632 struct scic_sds_phy *this_phy)
634 return this_phy->state_handlers->parent.reset_handler(
640 * This method will process the event code received.
646 enum sci_status scic_sds_phy_event_handler(
647 struct scic_sds_phy *this_phy,
650 return this_phy->state_handlers->event_handler(this_phy, event_code);
654 * This method will process the frame index received.
660 enum sci_status scic_sds_phy_frame_handler(
661 struct scic_sds_phy *this_phy,
664 return this_phy->state_handlers->frame_handler(this_phy, frame_index);
668 * This method will give the phy permission to consume power
673 enum sci_status scic_sds_phy_consume_power_handler(
674 struct scic_sds_phy *this_phy)
676 return this_phy->state_handlers->consume_power_handler(this_phy);
680 * *****************************************************************************
681 * * SCIC PHY Public Methods
682 * ***************************************************************************** */
685 enum sci_status scic_sas_phy_get_properties(
686 struct scic_sds_phy *sci_phy,
687 struct scic_sas_phy_properties *properties)
689 if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
691 &properties->received_iaf,
692 &sci_phy->phy_type.sas.identify_address_frame_buffer,
693 sizeof(struct sci_sas_identify_address_frame)
696 properties->received_capabilities.u.all
697 = SCU_SAS_RECPHYCAP_READ(sci_phy);
706 enum sci_status scic_sata_phy_get_properties(
707 struct scic_sds_phy *sci_phy,
708 struct scic_sata_phy_properties *properties)
710 if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) {
712 &properties->signature_fis,
713 &sci_phy->phy_type.sata.signature_fis_buffer,
714 sizeof(struct sata_fis_reg_d2h)
717 /* / @todo add support for port selectors. */
718 properties->is_port_selector_present = false;
727 * *****************************************************************************
728 * * SCIC SDS PHY HELPER FUNCTIONS
729 * ***************************************************************************** */
734 * @this_phy: The phy object that received SAS PHY DETECTED.
736 * This method continues the link training for the phy as if it were a SAS PHY
737 * instead of a SATA PHY. This is done because the completion queue had a SAS
738 * PHY DETECTED event when the state machine was expecting a SATA PHY event.
741 static void scic_sds_phy_start_sas_link_training(
742 struct scic_sds_phy *this_phy)
746 phy_control = SCU_SAS_PCFG_READ(this_phy);
747 phy_control |= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD);
748 SCU_SAS_PCFG_WRITE(this_phy, phy_control);
750 sci_base_state_machine_change_state(
751 &this_phy->starting_substate_machine,
752 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
755 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SAS;
760 * @this_phy: The phy object that received a SATA SPINUP HOLD event
762 * This method continues the link training for the phy as if it were a SATA PHY
763 * instead of a SAS PHY. This is done because the completion queue had a SATA
764 * SPINUP HOLD event when the state machine was expecting a SAS PHY event. none
766 static void scic_sds_phy_start_sata_link_training(
767 struct scic_sds_phy *this_phy)
769 sci_base_state_machine_change_state(
770 &this_phy->starting_substate_machine,
771 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
774 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
778 * This method performs processing common to all protocols upon completion of
780 * @this_phy: This parameter specifies the phy object for which link training
782 * @max_link_rate: This parameter specifies the maximum link rate to be
783 * associated with this phy.
784 * @next_state: This parameter specifies the next state for the phy's starting
788 static void scic_sds_phy_complete_link_training(
789 struct scic_sds_phy *this_phy,
790 enum sci_sas_link_rate max_link_rate,
793 this_phy->max_negotiated_speed = max_link_rate;
795 sci_base_state_machine_change_state(
796 scic_sds_phy_get_starting_substate_machine(this_phy), next_state
802 * @this_phy: The struct scic_sds_phy object to restart.
804 * This method restarts the struct scic_sds_phy objects base state machine in the
805 * starting state from any starting substate. none
807 static void scic_sds_phy_restart_starting_state(
808 struct scic_sds_phy *this_phy)
810 /* Stop the current substate machine */
811 sci_base_state_machine_stop(
812 scic_sds_phy_get_starting_substate_machine(this_phy)
815 /* Re-enter the base state machine starting state */
816 sci_base_state_machine_change_state(
817 scic_sds_phy_get_base_state_machine(this_phy),
818 SCI_BASE_PHY_STATE_STARTING
823 * *****************************************************************************
824 * * SCIC SDS PHY EVENT_HANDLERS
825 * ***************************************************************************** */
829 * @phy: This struct scic_sds_phy object which has received an event.
830 * @event_code: This is the event code which the phy object is to decode.
832 * This method is called when an event notification is received for the phy
833 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
834 * decode the event - sas phy detected causes a state transition to the wait
835 * for speed event notification. - any other events log a warning message and
836 * set a failure status enum sci_status SCI_SUCCESS on any valid event notification
837 * SCI_FAILURE on any unexpected event notifation
839 static enum sci_status scic_sds_phy_starting_substate_await_ossp_event_handler(
840 struct scic_sds_phy *this_phy,
843 u32 result = SCI_SUCCESS;
845 switch (scu_get_event_code(event_code)) {
846 case SCU_EVENT_SAS_PHY_DETECTED:
847 scic_sds_phy_start_sas_link_training(this_phy);
848 this_phy->is_in_link_training = true;
851 case SCU_EVENT_SATA_SPINUP_HOLD:
852 scic_sds_phy_start_sata_link_training(this_phy);
853 this_phy->is_in_link_training = true;
857 dev_warn(sciphy_to_dev(this_phy),
858 "%s: PHY starting substate machine received "
859 "unexpected event_code %x\n",
863 result = SCI_FAILURE;
872 * @phy: This struct scic_sds_phy object which has received an event.
873 * @event_code: This is the event code which the phy object is to decode.
875 * This method is called when an event notification is received for the phy
876 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
877 * decode the event - sas phy detected returns us back to this state. - speed
878 * event detected causes a state transition to the wait for iaf. - identify
879 * timeout is an un-expected event and the state machine is restarted. - link
880 * failure events restart the starting state machine - any other events log a
881 * warning message and set a failure status enum sci_status SCI_SUCCESS on any valid
882 * event notification SCI_FAILURE on any unexpected event notifation
884 static enum sci_status scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler(
885 struct scic_sds_phy *this_phy,
888 u32 result = SCI_SUCCESS;
890 switch (scu_get_event_code(event_code)) {
891 case SCU_EVENT_SAS_PHY_DETECTED:
893 * Why is this being reported again by the controller?
894 * We would re-enter this state so just stay here */
897 case SCU_EVENT_SAS_15:
898 case SCU_EVENT_SAS_15_SSC:
899 scic_sds_phy_complete_link_training(
900 this_phy, SCI_SAS_150_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
904 case SCU_EVENT_SAS_30:
905 case SCU_EVENT_SAS_30_SSC:
906 scic_sds_phy_complete_link_training(
907 this_phy, SCI_SAS_300_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
911 case SCU_EVENT_SAS_60:
912 case SCU_EVENT_SAS_60_SSC:
913 scic_sds_phy_complete_link_training(
914 this_phy, SCI_SAS_600_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
918 case SCU_EVENT_SATA_SPINUP_HOLD:
920 * We were doing SAS PHY link training and received a SATA PHY event
921 * continue OOB/SN as if this were a SATA PHY */
922 scic_sds_phy_start_sata_link_training(this_phy);
925 case SCU_EVENT_LINK_FAILURE:
926 /* Link failure change state back to the starting state */
927 scic_sds_phy_restart_starting_state(this_phy);
931 dev_warn(sciphy_to_dev(this_phy),
932 "%s: PHY starting substate machine received "
933 "unexpected event_code %x\n",
937 result = SCI_FAILURE;
946 * @phy: This struct scic_sds_phy object which has received an event.
947 * @event_code: This is the event code which the phy object is to decode.
949 * This method is called when an event notification is received for the phy
950 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. -
951 * decode the event - sas phy detected event backs up the state machine to the
952 * await speed notification. - identify timeout is an un-expected event and the
953 * state machine is restarted. - link failure events restart the starting state
954 * machine - any other events log a warning message and set a failure status
955 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
956 * unexpected event notifation
958 static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_event_handler(
959 struct scic_sds_phy *this_phy,
962 u32 result = SCI_SUCCESS;
964 switch (scu_get_event_code(event_code)) {
965 case SCU_EVENT_SAS_PHY_DETECTED:
966 /* Backup the state machine */
967 scic_sds_phy_start_sas_link_training(this_phy);
970 case SCU_EVENT_SATA_SPINUP_HOLD:
972 * We were doing SAS PHY link training and received a SATA PHY event
973 * continue OOB/SN as if this were a SATA PHY */
974 scic_sds_phy_start_sata_link_training(this_phy);
977 case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
978 case SCU_EVENT_LINK_FAILURE:
979 case SCU_EVENT_HARD_RESET_RECEIVED:
980 /* Start the oob/sn state machine over again */
981 scic_sds_phy_restart_starting_state(this_phy);
985 dev_warn(sciphy_to_dev(this_phy),
986 "%s: PHY starting substate machine received "
987 "unexpected event_code %x\n",
991 result = SCI_FAILURE;
1000 * @phy: This struct scic_sds_phy object which has received an event.
1001 * @event_code: This is the event code which the phy object is to decode.
1003 * This method is called when an event notification is received for the phy
1004 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_POWER. -
1005 * decode the event - link failure events restart the starting state machine -
1006 * any other events log a warning message and set a failure status enum sci_status
1007 * SCI_SUCCESS on a link failure event SCI_FAILURE on any unexpected event
1010 static enum sci_status scic_sds_phy_starting_substate_await_sas_power_event_handler(
1011 struct scic_sds_phy *this_phy,
1014 u32 result = SCI_SUCCESS;
1016 switch (scu_get_event_code(event_code)) {
1017 case SCU_EVENT_LINK_FAILURE:
1018 /* Link failure change state back to the starting state */
1019 scic_sds_phy_restart_starting_state(this_phy);
1023 dev_warn(sciphy_to_dev(this_phy),
1024 "%s: PHY starting substate machine received unexpected "
1029 result = SCI_FAILURE;
1038 * @phy: This struct scic_sds_phy object which has received an event.
1039 * @event_code: This is the event code which the phy object is to decode.
1041 * This method is called when an event notification is received for the phy
1042 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. -
1043 * decode the event - link failure events restart the starting state machine -
1044 * sata spinup hold events are ignored since they are expected - any other
1045 * events log a warning message and set a failure status enum sci_status SCI_SUCCESS
1046 * on a link failure event SCI_FAILURE on any unexpected event notifation
1048 static enum sci_status scic_sds_phy_starting_substate_await_sata_power_event_handler(
1049 struct scic_sds_phy *this_phy,
1052 u32 result = SCI_SUCCESS;
1054 switch (scu_get_event_code(event_code)) {
1055 case SCU_EVENT_LINK_FAILURE:
1056 /* Link failure change state back to the starting state */
1057 scic_sds_phy_restart_starting_state(this_phy);
1060 case SCU_EVENT_SATA_SPINUP_HOLD:
1061 /* These events are received every 10ms and are expected while in this state */
1064 case SCU_EVENT_SAS_PHY_DETECTED:
1066 * There has been a change in the phy type before OOB/SN for the
1067 * SATA finished start down the SAS link traning path. */
1068 scic_sds_phy_start_sas_link_training(this_phy);
1072 dev_warn(sciphy_to_dev(this_phy),
1073 "%s: PHY starting substate machine received "
1074 "unexpected event_code %x\n",
1078 result = SCI_FAILURE;
1087 * @phy: This struct scic_sds_phy object which has received an event.
1088 * @event_code: This is the event code which the phy object is to decode.
1090 * This method is called when an event notification is received for the phy
1091 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. -
1092 * decode the event - link failure events restart the starting state machine -
1093 * sata spinup hold events are ignored since they are expected - sata phy
1094 * detected event change to the wait speed event - any other events log a
1095 * warning message and set a failure status enum sci_status SCI_SUCCESS on a link
1096 * failure event SCI_FAILURE on any unexpected event notifation
1098 static enum sci_status scic_sds_phy_starting_substate_await_sata_phy_event_handler(
1099 struct scic_sds_phy *this_phy,
1102 u32 result = SCI_SUCCESS;
1104 switch (scu_get_event_code(event_code)) {
1105 case SCU_EVENT_LINK_FAILURE:
1106 /* Link failure change state back to the starting state */
1107 scic_sds_phy_restart_starting_state(this_phy);
1110 case SCU_EVENT_SATA_SPINUP_HOLD:
1112 * These events might be received since we dont know how many may be in
1113 * the completion queue while waiting for power */
1116 case SCU_EVENT_SATA_PHY_DETECTED:
1117 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
1119 /* We have received the SATA PHY notification change state */
1120 sci_base_state_machine_change_state(
1121 scic_sds_phy_get_starting_substate_machine(this_phy),
1122 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
1126 case SCU_EVENT_SAS_PHY_DETECTED:
1128 * There has been a change in the phy type before OOB/SN for the
1129 * SATA finished start down the SAS link traning path. */
1130 scic_sds_phy_start_sas_link_training(this_phy);
1134 dev_warn(sciphy_to_dev(this_phy),
1135 "%s: PHY starting substate machine received "
1136 "unexpected event_code %x\n",
1140 result = SCI_FAILURE;
1149 * @phy: This struct scic_sds_phy object which has received an event.
1150 * @event_code: This is the event code which the phy object is to decode.
1152 * This method is called when an event notification is received for the phy
1153 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN.
1154 * - decode the event - sata phy detected returns us back to this state. -
1155 * speed event detected causes a state transition to the wait for signature. -
1156 * link failure events restart the starting state machine - any other events
1157 * log a warning message and set a failure status enum sci_status SCI_SUCCESS on any
1158 * valid event notification SCI_FAILURE on any unexpected event notifation
1160 static enum sci_status scic_sds_phy_starting_substate_await_sata_speed_event_handler(
1161 struct scic_sds_phy *this_phy,
1164 u32 result = SCI_SUCCESS;
1166 switch (scu_get_event_code(event_code)) {
1167 case SCU_EVENT_SATA_PHY_DETECTED:
1169 * The hardware reports multiple SATA PHY detected events
1170 * ignore the extras */
1173 case SCU_EVENT_SATA_15:
1174 case SCU_EVENT_SATA_15_SSC:
1175 scic_sds_phy_complete_link_training(
1178 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
1182 case SCU_EVENT_SATA_30:
1183 case SCU_EVENT_SATA_30_SSC:
1184 scic_sds_phy_complete_link_training(
1187 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
1191 case SCU_EVENT_SATA_60:
1192 case SCU_EVENT_SATA_60_SSC:
1193 scic_sds_phy_complete_link_training(
1196 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
1200 case SCU_EVENT_LINK_FAILURE:
1201 /* Link failure change state back to the starting state */
1202 scic_sds_phy_restart_starting_state(this_phy);
1205 case SCU_EVENT_SAS_PHY_DETECTED:
1207 * There has been a change in the phy type before OOB/SN for the
1208 * SATA finished start down the SAS link traning path. */
1209 scic_sds_phy_start_sas_link_training(this_phy);
1213 dev_warn(sciphy_to_dev(this_phy),
1214 "%s: PHY starting substate machine received "
1215 "unexpected event_code %x\n",
1219 result = SCI_FAILURE;
1228 * @phy: This struct scic_sds_phy object which has received an event.
1229 * @event_code: This is the event code which the phy object is to decode.
1231 * This method is called when an event notification is received for the phy
1232 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. -
1233 * decode the event - sas phy detected event backs up the state machine to the
1234 * await speed notification. - identify timeout is an un-expected event and the
1235 * state machine is restarted. - link failure events restart the starting state
1236 * machine - any other events log a warning message and set a failure status
1237 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
1238 * unexpected event notifation
1240 static enum sci_status scic_sds_phy_starting_substate_await_sig_fis_event_handler(
1241 struct scic_sds_phy *this_phy,
1244 u32 result = SCI_SUCCESS;
1246 switch (scu_get_event_code(event_code)) {
1247 case SCU_EVENT_SATA_PHY_DETECTED:
1248 /* Backup the state machine */
1249 sci_base_state_machine_change_state(
1250 scic_sds_phy_get_starting_substate_machine(this_phy),
1251 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
1255 case SCU_EVENT_LINK_FAILURE:
1256 /* Link failure change state back to the starting state */
1257 scic_sds_phy_restart_starting_state(this_phy);
1261 dev_warn(sciphy_to_dev(this_phy),
1262 "%s: PHY starting substate machine received "
1263 "unexpected event_code %x\n",
1267 result = SCI_FAILURE;
1276 * *****************************************************************************
1277 * * SCIC SDS PHY FRAME_HANDLERS
1278 * ***************************************************************************** */
1282 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1284 * @frame_index: This is the index of the unsolicited frame which was received
1287 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1288 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - Get the UF Header - If the UF
1289 * is an IAF - Copy IAF data to local phy object IAF data buffer. - Change
1290 * starting substate to wait power. - else - log warning message of unexpected
1291 * unsolicted frame - release frame buffer enum sci_status SCI_SUCCESS
1293 static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_frame_handler(
1294 struct scic_sds_phy *this_phy,
1297 enum sci_status result;
1299 struct sci_sas_identify_address_frame *identify_frame;
1301 result = scic_sds_unsolicited_frame_control_get_header(
1302 &(scic_sds_phy_get_controller(this_phy)->uf_control),
1304 (void **)&frame_words);
1306 if (result != SCI_SUCCESS) {
1310 frame_words[0] = SCIC_SWAP_DWORD(frame_words[0]);
1311 identify_frame = (struct sci_sas_identify_address_frame *)frame_words;
1313 if (identify_frame->address_frame_type == 0) {
1315 * Byte swap the rest of the frame so we can make
1316 * a copy of the buffer */
1317 frame_words[1] = SCIC_SWAP_DWORD(frame_words[1]);
1318 frame_words[2] = SCIC_SWAP_DWORD(frame_words[2]);
1319 frame_words[3] = SCIC_SWAP_DWORD(frame_words[3]);
1320 frame_words[4] = SCIC_SWAP_DWORD(frame_words[4]);
1321 frame_words[5] = SCIC_SWAP_DWORD(frame_words[5]);
1324 &this_phy->phy_type.sas.identify_address_frame_buffer,
1326 sizeof(struct sci_sas_identify_address_frame)
1329 if (identify_frame->protocols.u.bits.smp_target) {
1331 * We got the IAF for an expander PHY go to the final state since
1332 * there are no power requirements for expander phys. */
1333 sci_base_state_machine_change_state(
1334 scic_sds_phy_get_starting_substate_machine(this_phy),
1335 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
1338 /* We got the IAF we can now go to the await spinup semaphore state */
1339 sci_base_state_machine_change_state(
1340 scic_sds_phy_get_starting_substate_machine(this_phy),
1341 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
1345 result = SCI_SUCCESS;
1347 dev_warn(sciphy_to_dev(this_phy),
1348 "%s: PHY starting substate machine received "
1349 "unexpected frame id %x\n",
1353 /* Regardless of the result release this frame since we are done with it */
1354 scic_sds_controller_release_frame(
1355 scic_sds_phy_get_controller(this_phy), frame_index
1363 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1365 * @frame_index: This is the index of the unsolicited frame which was received
1368 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1369 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Get the UF Header - If
1370 * the UF is an SIGNATURE FIS - Copy IAF data to local phy object SIGNATURE FIS
1371 * data buffer. - else - log warning message of unexpected unsolicted frame -
1372 * release frame buffer enum sci_status SCI_SUCCESS Must decode the SIGNATURE FIS
1375 static enum sci_status scic_sds_phy_starting_substate_await_sig_fis_frame_handler(
1376 struct scic_sds_phy *this_phy,
1379 enum sci_status result;
1381 struct sata_fis_header *fis_frame_header;
1382 u32 *fis_frame_data;
1384 result = scic_sds_unsolicited_frame_control_get_header(
1385 &(scic_sds_phy_get_controller(this_phy)->uf_control),
1387 (void **)&frame_words);
1389 if (result != SCI_SUCCESS) {
1393 fis_frame_header = (struct sata_fis_header *)frame_words;
1396 (fis_frame_header->fis_type == SATA_FIS_TYPE_REGD2H)
1397 && !(fis_frame_header->status & ATA_STATUS_REG_BSY_BIT)
1399 scic_sds_unsolicited_frame_control_get_buffer(
1400 &(scic_sds_phy_get_controller(this_phy)->uf_control),
1402 (void **)&fis_frame_data
1405 scic_sds_controller_copy_sata_response(
1406 &this_phy->phy_type.sata.signature_fis_buffer,
1411 /* We got the IAF we can now go to the await spinup semaphore state */
1412 sci_base_state_machine_change_state(
1413 scic_sds_phy_get_starting_substate_machine(this_phy),
1414 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
1417 result = SCI_SUCCESS;
1419 dev_warn(sciphy_to_dev(this_phy),
1420 "%s: PHY starting substate machine received "
1421 "unexpected frame id %x\n",
1425 /* Regardless of the result release this frame since we are done with it */
1426 scic_sds_controller_release_frame(
1427 scic_sds_phy_get_controller(this_phy), frame_index
1434 * *****************************************************************************
1435 * * SCIC SDS PHY POWER_HANDLERS
1436 * ***************************************************************************** */
1440 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
1443 * This method is called by the struct scic_sds_controller when the phy object is
1444 * granted power. - The notify enable spinups are turned on for this phy object
1445 * - The phy state machine is transitioned to the
1446 * SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. enum sci_status SCI_SUCCESS
1448 static enum sci_status scic_sds_phy_starting_substate_await_sas_power_consume_power_handler(
1449 struct scic_sds_phy *this_phy)
1453 enable_spinup = SCU_SAS_ENSPINUP_READ(this_phy);
1454 enable_spinup |= SCU_ENSPINUP_GEN_BIT(ENABLE);
1455 SCU_SAS_ENSPINUP_WRITE(this_phy, enable_spinup);
1457 /* Change state to the final state this substate machine has run to completion */
1458 sci_base_state_machine_change_state(
1459 scic_sds_phy_get_starting_substate_machine(this_phy),
1460 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
1468 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
1471 * This method is called by the struct scic_sds_controller when the phy object is
1472 * granted power. - The phy state machine is transitioned to the
1473 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. enum sci_status SCI_SUCCESS
1475 static enum sci_status scic_sds_phy_starting_substate_await_sata_power_consume_power_handler(
1476 struct scic_sds_phy *this_phy)
1478 u32 scu_sas_pcfg_value;
1480 /* Release the spinup hold state and reset the OOB state machine */
1481 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
1482 scu_sas_pcfg_value &=
1483 ~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE));
1484 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
1485 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
1487 /* Now restart the OOB operation */
1488 scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
1489 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
1490 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
1492 /* Change state to the final state this substate machine has run to completion */
1493 sci_base_state_machine_change_state(
1494 scic_sds_phy_get_starting_substate_machine(this_phy),
1495 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
1501 /* --------------------------------------------------------------------------- */
1503 struct scic_sds_phy_state_handler
1504 scic_sds_phy_starting_substate_handler_table[SCIC_SDS_PHY_STARTING_MAX_SUBSTATES] =
1506 /* SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL */
1509 scic_sds_phy_default_start_handler,
1510 scic_sds_phy_default_stop_handler,
1511 scic_sds_phy_default_reset_handler,
1512 scic_sds_phy_default_destroy_handler
1514 scic_sds_phy_default_frame_handler,
1515 scic_sds_phy_default_event_handler,
1516 scic_sds_phy_default_consume_power_handler
1518 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN */
1521 scic_sds_phy_default_start_handler,
1522 scic_sds_phy_default_stop_handler,
1523 scic_sds_phy_default_reset_handler,
1524 scic_sds_phy_default_destroy_handler
1526 scic_sds_phy_default_frame_handler,
1527 scic_sds_phy_starting_substate_await_ossp_event_handler,
1528 scic_sds_phy_default_consume_power_handler
1530 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN */
1533 scic_sds_phy_default_start_handler,
1534 scic_sds_phy_default_stop_handler,
1535 scic_sds_phy_default_reset_handler,
1536 scic_sds_phy_default_destroy_handler
1538 scic_sds_phy_default_frame_handler,
1539 scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler,
1540 scic_sds_phy_default_consume_power_handler
1542 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF */
1545 scic_sds_phy_default_start_handler,
1546 scic_sds_phy_default_stop_handler,
1547 scic_sds_phy_default_reset_handler,
1548 scic_sds_phy_default_destroy_handler
1550 scic_sds_phy_starting_substate_await_iaf_uf_frame_handler,
1551 scic_sds_phy_starting_substate_await_iaf_uf_event_handler,
1552 scic_sds_phy_default_consume_power_handler
1554 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER */
1557 scic_sds_phy_default_start_handler,
1558 scic_sds_phy_default_stop_handler,
1559 scic_sds_phy_default_reset_handler,
1560 scic_sds_phy_default_destroy_handler
1562 scic_sds_phy_default_frame_handler,
1563 scic_sds_phy_starting_substate_await_sas_power_event_handler,
1564 scic_sds_phy_starting_substate_await_sas_power_consume_power_handler
1566 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER, */
1569 scic_sds_phy_default_start_handler,
1570 scic_sds_phy_default_stop_handler,
1571 scic_sds_phy_default_reset_handler,
1572 scic_sds_phy_default_destroy_handler
1574 scic_sds_phy_default_frame_handler,
1575 scic_sds_phy_starting_substate_await_sata_power_event_handler,
1576 scic_sds_phy_starting_substate_await_sata_power_consume_power_handler
1578 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN, */
1581 scic_sds_phy_default_start_handler,
1582 scic_sds_phy_default_stop_handler,
1583 scic_sds_phy_default_reset_handler,
1584 scic_sds_phy_default_destroy_handler
1586 scic_sds_phy_default_frame_handler,
1587 scic_sds_phy_starting_substate_await_sata_phy_event_handler,
1588 scic_sds_phy_default_consume_power_handler
1590 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN, */
1593 scic_sds_phy_default_start_handler,
1594 scic_sds_phy_default_stop_handler,
1595 scic_sds_phy_default_reset_handler,
1596 scic_sds_phy_default_destroy_handler
1598 scic_sds_phy_default_frame_handler,
1599 scic_sds_phy_starting_substate_await_sata_speed_event_handler,
1600 scic_sds_phy_default_consume_power_handler
1602 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF, */
1605 scic_sds_phy_default_start_handler,
1606 scic_sds_phy_default_stop_handler,
1607 scic_sds_phy_default_reset_handler,
1608 scic_sds_phy_default_destroy_handler
1610 scic_sds_phy_starting_substate_await_sig_fis_frame_handler,
1611 scic_sds_phy_starting_substate_await_sig_fis_event_handler,
1612 scic_sds_phy_default_consume_power_handler
1614 /* SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL */
1617 scic_sds_phy_default_start_handler,
1618 scic_sds_phy_default_stop_handler,
1619 scic_sds_phy_default_reset_handler,
1620 scic_sds_phy_default_destroy_handler
1622 scic_sds_phy_default_frame_handler,
1623 scic_sds_phy_default_event_handler,
1624 scic_sds_phy_default_consume_power_handler
1629 * scic_sds_phy_set_starting_substate_handlers() -
1631 * This macro sets the starting substate handlers by state_id
1633 #define scic_sds_phy_set_starting_substate_handlers(phy, state_id) \
1634 scic_sds_phy_set_state_handlers(\
1636 &scic_sds_phy_starting_substate_handler_table[(state_id)] \
1640 * ****************************************************************************
1641 * * PHY STARTING SUBSTATE METHODS
1642 * **************************************************************************** */
1646 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1648 * This method will perform the actions required by the struct scic_sds_phy on
1649 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL. - The initial state
1650 * handlers are put in place for the struct scic_sds_phy object. - The state is
1651 * changed to the wait phy type event notification. none
1653 static void scic_sds_phy_starting_initial_substate_enter(
1654 struct sci_base_object *object)
1656 struct scic_sds_phy *this_phy;
1658 this_phy = (struct scic_sds_phy *)object;
1660 scic_sds_phy_set_starting_substate_handlers(
1661 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL);
1663 /* This is just an temporary state go off to the starting state */
1664 sci_base_state_machine_change_state(
1665 scic_sds_phy_get_starting_substate_machine(this_phy),
1666 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
1672 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1674 * This method will perform the actions required by the struct scic_sds_phy on
1675 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_PHY_TYPE_EN. - Set the
1676 * struct scic_sds_phy object state handlers for this state. none
1678 static void scic_sds_phy_starting_await_ossp_en_substate_enter(
1679 struct sci_base_object *object)
1681 struct scic_sds_phy *this_phy;
1683 this_phy = (struct scic_sds_phy *)object;
1685 scic_sds_phy_set_starting_substate_handlers(
1686 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
1692 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1694 * This method will perform the actions required by the struct scic_sds_phy on
1695 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. - Set the
1696 * struct scic_sds_phy object state handlers for this state. none
1698 static void scic_sds_phy_starting_await_sas_speed_en_substate_enter(
1699 struct sci_base_object *object)
1701 struct scic_sds_phy *this_phy;
1703 this_phy = (struct scic_sds_phy *)object;
1705 scic_sds_phy_set_starting_substate_handlers(
1706 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
1712 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1714 * This method will perform the actions required by the struct scic_sds_phy on
1715 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - Set the
1716 * struct scic_sds_phy object state handlers for this state. none
1718 static void scic_sds_phy_starting_await_iaf_uf_substate_enter(
1719 struct sci_base_object *object)
1721 struct scic_sds_phy *this_phy;
1723 this_phy = (struct scic_sds_phy *)object;
1725 scic_sds_phy_set_starting_substate_handlers(
1726 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
1732 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1734 * This method will perform the actions required by the struct scic_sds_phy on
1735 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Set the
1736 * struct scic_sds_phy object state handlers for this state. - Add this phy object to
1737 * the power control queue none
1739 static void scic_sds_phy_starting_await_sas_power_substate_enter(
1740 struct sci_base_object *object)
1742 struct scic_sds_phy *this_phy;
1744 this_phy = (struct scic_sds_phy *)object;
1746 scic_sds_phy_set_starting_substate_handlers(
1747 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
1750 scic_sds_controller_power_control_queue_insert(
1751 scic_sds_phy_get_controller(this_phy),
1758 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1760 * This method will perform the actions required by the struct scic_sds_phy on exiting
1761 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Remove the
1762 * struct scic_sds_phy object from the power control queue. none
1764 static void scic_sds_phy_starting_await_sas_power_substate_exit(
1765 struct sci_base_object *object)
1767 struct scic_sds_phy *this_phy;
1769 this_phy = (struct scic_sds_phy *)object;
1771 scic_sds_controller_power_control_queue_remove(
1772 scic_sds_phy_get_controller(this_phy), this_phy
1778 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1780 * This method will perform the actions required by the struct scic_sds_phy on
1781 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. - Set the
1782 * struct scic_sds_phy object state handlers for this state. - Add this phy object to
1783 * the power control queue none
1785 static void scic_sds_phy_starting_await_sata_power_substate_enter(
1786 struct sci_base_object *object)
1788 struct scic_sds_phy *this_phy;
1790 this_phy = (struct scic_sds_phy *)object;
1792 scic_sds_phy_set_starting_substate_handlers(
1793 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
1796 scic_sds_controller_power_control_queue_insert(
1797 scic_sds_phy_get_controller(this_phy),
1804 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1806 * This method will perform the actions required by the struct scic_sds_phy on exiting
1807 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. - Remove the
1808 * struct scic_sds_phy object from the power control queue. none
1810 static void scic_sds_phy_starting_await_sata_power_substate_exit(
1811 struct sci_base_object *object)
1813 struct scic_sds_phy *this_phy;
1815 this_phy = (struct scic_sds_phy *)object;
1817 scic_sds_controller_power_control_queue_remove(
1818 scic_sds_phy_get_controller(this_phy),
1825 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1827 * This method will perform the actions required by the struct scic_sds_phy on
1828 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. - Set the
1829 * struct scic_sds_phy object state handlers for this state. none
1831 static void scic_sds_phy_starting_await_sata_phy_substate_enter(
1832 struct sci_base_object *object)
1834 struct scic_sds_phy *this_phy;
1836 this_phy = (struct scic_sds_phy *)object;
1838 scic_sds_phy_set_starting_substate_handlers(
1839 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
1842 scic_cb_timer_start(
1843 scic_sds_phy_get_controller(this_phy),
1844 this_phy->sata_timeout_timer,
1845 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
1851 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1853 * This method will perform the actions required by the struct scic_sds_phy on exiting
1854 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1855 * that was started on entry to await sata phy event notification none
1857 static void scic_sds_phy_starting_await_sata_phy_substate_exit(
1858 struct sci_base_object *object)
1860 struct scic_sds_phy *this_phy;
1862 this_phy = (struct scic_sds_phy *)object;
1865 scic_sds_phy_get_controller(this_phy),
1866 this_phy->sata_timeout_timer
1872 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1874 * This method will perform the actions required by the struct scic_sds_phy on
1875 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - Set the
1876 * struct scic_sds_phy object state handlers for this state. none
1878 static void scic_sds_phy_starting_await_sata_speed_substate_enter(
1879 struct sci_base_object *object)
1881 struct scic_sds_phy *this_phy;
1883 this_phy = (struct scic_sds_phy *)object;
1885 scic_sds_phy_set_starting_substate_handlers(
1886 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
1889 scic_cb_timer_start(
1890 scic_sds_phy_get_controller(this_phy),
1891 this_phy->sata_timeout_timer,
1892 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
1898 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1900 * This method will perform the actions required by the struct scic_sds_phy on exiting
1901 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1902 * that was started on entry to await sata phy event notification none
1904 static void scic_sds_phy_starting_await_sata_speed_substate_exit(
1905 struct sci_base_object *object)
1907 struct scic_sds_phy *this_phy;
1909 this_phy = (struct scic_sds_phy *)object;
1912 scic_sds_phy_get_controller(this_phy),
1913 this_phy->sata_timeout_timer
1919 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1921 * This method will perform the actions required by the struct scic_sds_phy on
1922 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Set the
1923 * struct scic_sds_phy object state handlers for this state. - Start the SIGNATURE FIS
1924 * timeout timer none
1926 static void scic_sds_phy_starting_await_sig_fis_uf_substate_enter(
1927 struct sci_base_object *object)
1929 bool continue_to_ready_state;
1930 struct scic_sds_phy *this_phy;
1932 this_phy = (struct scic_sds_phy *)object;
1934 scic_sds_phy_set_starting_substate_handlers(
1935 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
1938 continue_to_ready_state = scic_sds_port_link_detected(
1939 this_phy->owning_port,
1943 if (continue_to_ready_state) {
1945 * Clear the PE suspend condition so we can actually receive SIG FIS
1946 * The hardware will not respond to the XRDY until the PE suspend
1947 * condition is cleared. */
1948 scic_sds_phy_resume(this_phy);
1950 scic_cb_timer_start(
1951 scic_sds_phy_get_controller(this_phy),
1952 this_phy->sata_timeout_timer,
1953 SCIC_SDS_SIGNATURE_FIS_TIMEOUT
1956 this_phy->is_in_link_training = false;
1962 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1964 * This method will perform the actions required by the struct scic_sds_phy on exiting
1965 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Stop the SIGNATURE
1966 * FIS timeout timer. none
1968 static void scic_sds_phy_starting_await_sig_fis_uf_substate_exit(
1969 struct sci_base_object *object)
1971 struct scic_sds_phy *this_phy;
1973 this_phy = (struct scic_sds_phy *)object;
1976 scic_sds_phy_get_controller(this_phy),
1977 this_phy->sata_timeout_timer
1983 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1985 * This method will perform the actions required by the struct scic_sds_phy on
1986 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. - Set the struct scic_sds_phy
1987 * object state handlers for this state. - Change base state machine to the
1990 static void scic_sds_phy_starting_final_substate_enter(
1991 struct sci_base_object *object)
1993 struct scic_sds_phy *this_phy;
1995 this_phy = (struct scic_sds_phy *)object;
1997 scic_sds_phy_set_starting_substate_handlers(
1998 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
2002 * State machine has run to completion so exit out and change
2003 * the base state machine to the ready state */
2004 sci_base_state_machine_change_state(
2005 scic_sds_phy_get_base_state_machine(this_phy),
2006 SCI_BASE_PHY_STATE_READY);
2009 /* --------------------------------------------------------------------------- */
2011 const struct sci_base_state scic_sds_phy_starting_substates[] = {
2012 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = {
2013 .enter_state = scic_sds_phy_starting_initial_substate_enter,
2015 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN] = {
2016 .enter_state = scic_sds_phy_starting_await_ossp_en_substate_enter,
2018 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN] = {
2019 .enter_state = scic_sds_phy_starting_await_sas_speed_en_substate_enter,
2021 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF] = {
2022 .enter_state = scic_sds_phy_starting_await_iaf_uf_substate_enter,
2024 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER] = {
2025 .enter_state = scic_sds_phy_starting_await_sas_power_substate_enter,
2026 .exit_state = scic_sds_phy_starting_await_sas_power_substate_exit,
2028 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER] = {
2029 .enter_state = scic_sds_phy_starting_await_sata_power_substate_enter,
2030 .exit_state = scic_sds_phy_starting_await_sata_power_substate_exit
2032 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN] = {
2033 .enter_state = scic_sds_phy_starting_await_sata_phy_substate_enter,
2034 .exit_state = scic_sds_phy_starting_await_sata_phy_substate_exit
2036 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN] = {
2037 .enter_state = scic_sds_phy_starting_await_sata_speed_substate_enter,
2038 .exit_state = scic_sds_phy_starting_await_sata_speed_substate_exit
2040 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF] = {
2041 .enter_state = scic_sds_phy_starting_await_sig_fis_uf_substate_enter,
2042 .exit_state = scic_sds_phy_starting_await_sig_fis_uf_substate_exit
2044 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL] = {
2045 .enter_state = scic_sds_phy_starting_final_substate_enter,
2050 * ***************************************************************************
2051 * * DEFAULT HANDLERS
2052 * *************************************************************************** */
2056 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2059 * This is the default method for phy a start request. It will report a
2060 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2062 enum sci_status scic_sds_phy_default_start_handler(
2063 struct sci_base_phy *phy)
2065 struct scic_sds_phy *this_phy;
2067 this_phy = (struct scic_sds_phy *)phy;
2069 dev_warn(sciphy_to_dev(this_phy),
2070 "%s: SCIC Phy 0x%p requested to start from invalid "
2074 sci_base_state_machine_get_state(
2075 &this_phy->parent.state_machine));
2077 return SCI_FAILURE_INVALID_STATE;
2083 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2086 * This is the default method for phy a stop request. It will report a warning
2087 * and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2089 enum sci_status scic_sds_phy_default_stop_handler(
2090 struct sci_base_phy *phy)
2092 struct scic_sds_phy *this_phy;
2094 this_phy = (struct scic_sds_phy *)phy;
2096 dev_warn(sciphy_to_dev(this_phy),
2097 "%s: SCIC Phy 0x%p requested to stop from invalid "
2101 sci_base_state_machine_get_state(
2102 &this_phy->parent.state_machine));
2104 return SCI_FAILURE_INVALID_STATE;
2109 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2112 * This is the default method for phy a reset request. It will report a
2113 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2115 enum sci_status scic_sds_phy_default_reset_handler(
2116 struct sci_base_phy *phy)
2118 struct scic_sds_phy *this_phy;
2120 this_phy = (struct scic_sds_phy *)phy;
2122 dev_warn(sciphy_to_dev(this_phy),
2123 "%s: SCIC Phy 0x%p requested to reset from invalid state "
2127 sci_base_state_machine_get_state(
2128 &this_phy->parent.state_machine));
2130 return SCI_FAILURE_INVALID_STATE;
2135 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2138 * This is the default method for phy a destruct request. It will report a
2139 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2141 enum sci_status scic_sds_phy_default_destroy_handler(
2142 struct sci_base_phy *phy)
2144 struct scic_sds_phy *this_phy;
2146 this_phy = (struct scic_sds_phy *)phy;
2148 /* / @todo Implement something for the default */
2149 dev_warn(sciphy_to_dev(this_phy),
2150 "%s: SCIC Phy 0x%p requested to destroy from invalid "
2154 sci_base_state_machine_get_state(
2155 &this_phy->parent.state_machine));
2157 return SCI_FAILURE_INVALID_STATE;
2162 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2164 * @frame_index: This is the frame index that was received from the SCU
2167 * This is the default method for a phy frame handling request. It will report
2168 * a warning, release the frame and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2170 enum sci_status scic_sds_phy_default_frame_handler(
2171 struct scic_sds_phy *this_phy,
2174 dev_warn(sciphy_to_dev(this_phy),
2175 "%s: SCIC Phy 0x%p received unexpected frame data %d "
2176 "while in state %d\n",
2180 sci_base_state_machine_get_state(
2181 &this_phy->parent.state_machine));
2183 scic_sds_controller_release_frame(
2184 scic_sds_phy_get_controller(this_phy), frame_index);
2186 return SCI_FAILURE_INVALID_STATE;
2191 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2193 * @event_code: This is the event code that was received from the SCU hardware.
2195 * This is the default method for a phy event handler. It will report a
2196 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2198 enum sci_status scic_sds_phy_default_event_handler(
2199 struct scic_sds_phy *this_phy,
2202 dev_warn(sciphy_to_dev(this_phy),
2203 "%s: SCIC Phy 0x%p received unexpected event status %x "
2204 "while in state %d\n",
2208 sci_base_state_machine_get_state(
2209 &this_phy->parent.state_machine));
2211 return SCI_FAILURE_INVALID_STATE;
2216 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2219 * This is the default method for a phy consume power handler. It will report
2220 * a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2222 enum sci_status scic_sds_phy_default_consume_power_handler(
2223 struct scic_sds_phy *this_phy)
2225 dev_warn(sciphy_to_dev(this_phy),
2226 "%s: SCIC Phy 0x%p given unexpected permission to consume "
2227 "power while in state %d\n",
2230 sci_base_state_machine_get_state(
2231 &this_phy->parent.state_machine));
2233 return SCI_FAILURE_INVALID_STATE;
2237 * ******************************************************************************
2238 * * PHY STOPPED STATE HANDLERS
2239 * ****************************************************************************** */
2243 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2246 * This method takes the struct scic_sds_phy from a stopped state and attempts to
2247 * start it. - The phy state machine is transitioned to the
2248 * SCI_BASE_PHY_STATE_STARTING. enum sci_status SCI_SUCCESS
2250 static enum sci_status scic_sds_phy_stopped_state_start_handler(
2251 struct sci_base_phy *phy)
2253 struct scic_sds_phy *this_phy;
2255 this_phy = (struct scic_sds_phy *)phy;
2257 sci_base_state_machine_change_state(
2258 scic_sds_phy_get_base_state_machine(this_phy),
2259 SCI_BASE_PHY_STATE_STARTING
2267 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2270 * This method takes the struct scic_sds_phy from a stopped state and destroys it. -
2271 * This function takes no action. Shouldnt this function transition the
2272 * struct sci_base_phy::state_machine to the SCI_BASE_PHY_STATE_FINAL? enum sci_status
2275 static enum sci_status scic_sds_phy_stopped_state_destroy_handler(
2276 struct sci_base_phy *phy)
2278 struct scic_sds_phy *this_phy;
2280 this_phy = (struct scic_sds_phy *)phy;
2282 /* / @todo what do we actually need to do here? */
2287 * ******************************************************************************
2288 * * PHY STARTING STATE HANDLERS
2289 * ****************************************************************************** */
2291 /* All of these state handlers are mapped to the starting sub-state machine */
2294 * ******************************************************************************
2295 * * PHY READY STATE HANDLERS
2296 * ****************************************************************************** */
2300 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2303 * This method takes the struct scic_sds_phy from a ready state and attempts to stop
2304 * it. - The phy state machine is transitioned to the
2305 * SCI_BASE_PHY_STATE_STOPPED. enum sci_status SCI_SUCCESS
2307 static enum sci_status scic_sds_phy_ready_state_stop_handler(
2308 struct sci_base_phy *phy)
2310 struct scic_sds_phy *this_phy;
2312 this_phy = (struct scic_sds_phy *)phy;
2314 sci_base_state_machine_change_state(
2315 scic_sds_phy_get_base_state_machine(this_phy),
2316 SCI_BASE_PHY_STATE_STOPPED
2324 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2327 * This method takes the struct scic_sds_phy from a ready state and attempts to reset
2328 * it. - The phy state machine is transitioned to the
2329 * SCI_BASE_PHY_STATE_STARTING. enum sci_status SCI_SUCCESS
2331 static enum sci_status scic_sds_phy_ready_state_reset_handler(
2332 struct sci_base_phy *phy)
2334 struct scic_sds_phy *this_phy;
2336 this_phy = (struct scic_sds_phy *)phy;
2338 sci_base_state_machine_change_state(
2339 scic_sds_phy_get_base_state_machine(this_phy),
2340 SCI_BASE_PHY_STATE_RESETTING
2348 * @phy: This is the struct scic_sds_phy object which has received the event.
2350 * This method request the struct scic_sds_phy handle the received event. The only
2351 * event that we are interested in while in the ready state is the link failure
2352 * event. - decoded event is a link failure - transition the struct scic_sds_phy back
2353 * to the SCI_BASE_PHY_STATE_STARTING state. - any other event recived will
2354 * report a warning message enum sci_status SCI_SUCCESS if the event received is a
2355 * link failure SCI_FAILURE_INVALID_STATE for any other event received.
2357 static enum sci_status scic_sds_phy_ready_state_event_handler(
2358 struct scic_sds_phy *this_phy,
2361 enum sci_status result = SCI_FAILURE;
2363 switch (scu_get_event_code(event_code)) {
2364 case SCU_EVENT_LINK_FAILURE:
2365 /* Link failure change state back to the starting state */
2366 sci_base_state_machine_change_state(
2367 scic_sds_phy_get_base_state_machine(this_phy),
2368 SCI_BASE_PHY_STATE_STARTING
2371 result = SCI_SUCCESS;
2374 case SCU_EVENT_BROADCAST_CHANGE:
2375 /* Broadcast change received. Notify the port. */
2376 if (scic_sds_phy_get_port(this_phy) != SCI_INVALID_HANDLE)
2377 scic_sds_port_broadcast_change_received(this_phy->owning_port, this_phy);
2379 this_phy->bcn_received_while_port_unassigned = true;
2383 dev_warn(sciphy_to_dev(this_phy),
2384 "%sP SCIC PHY 0x%p ready state machine received "
2385 "unexpected event_code %x\n",
2390 result = SCI_FAILURE_INVALID_STATE;
2397 /* --------------------------------------------------------------------------- */
2401 * @this_phy: This is the struct scic_sds_phy object which is receiving the event.
2402 * @event_code: This is the event code to be processed.
2404 * This is the resetting state event handler. enum sci_status
2405 * SCI_FAILURE_INVALID_STATE
2407 static enum sci_status scic_sds_phy_resetting_state_event_handler(
2408 struct scic_sds_phy *this_phy,
2411 enum sci_status result = SCI_FAILURE;
2413 switch (scu_get_event_code(event_code)) {
2414 case SCU_EVENT_HARD_RESET_TRANSMITTED:
2415 /* Link failure change state back to the starting state */
2416 sci_base_state_machine_change_state(
2417 scic_sds_phy_get_base_state_machine(this_phy),
2418 SCI_BASE_PHY_STATE_STARTING
2421 result = SCI_SUCCESS;
2425 dev_warn(sciphy_to_dev(this_phy),
2426 "%s: SCIC PHY 0x%p resetting state machine received "
2427 "unexpected event_code %x\n",
2432 result = SCI_FAILURE_INVALID_STATE;
2439 /* --------------------------------------------------------------------------- */
2441 struct scic_sds_phy_state_handler
2442 scic_sds_phy_state_handler_table[SCI_BASE_PHY_MAX_STATES] =
2444 /* SCI_BASE_PHY_STATE_INITIAL */
2447 scic_sds_phy_default_start_handler,
2448 scic_sds_phy_default_stop_handler,
2449 scic_sds_phy_default_reset_handler,
2450 scic_sds_phy_default_destroy_handler
2452 scic_sds_phy_default_frame_handler,
2453 scic_sds_phy_default_event_handler,
2454 scic_sds_phy_default_consume_power_handler
2456 /* SCI_BASE_PHY_STATE_STOPPED */
2459 scic_sds_phy_stopped_state_start_handler,
2460 scic_sds_phy_default_stop_handler,
2461 scic_sds_phy_default_reset_handler,
2462 scic_sds_phy_stopped_state_destroy_handler
2464 scic_sds_phy_default_frame_handler,
2465 scic_sds_phy_default_event_handler,
2466 scic_sds_phy_default_consume_power_handler
2468 /* SCI_BASE_PHY_STATE_STARTING */
2471 scic_sds_phy_default_start_handler,
2472 scic_sds_phy_default_stop_handler,
2473 scic_sds_phy_default_reset_handler,
2474 scic_sds_phy_default_destroy_handler
2476 scic_sds_phy_default_frame_handler,
2477 scic_sds_phy_default_event_handler,
2478 scic_sds_phy_default_consume_power_handler
2480 /* SCI_BASE_PHY_STATE_READY */
2483 scic_sds_phy_default_start_handler,
2484 scic_sds_phy_ready_state_stop_handler,
2485 scic_sds_phy_ready_state_reset_handler,
2486 scic_sds_phy_default_destroy_handler
2488 scic_sds_phy_default_frame_handler,
2489 scic_sds_phy_ready_state_event_handler,
2490 scic_sds_phy_default_consume_power_handler
2492 /* SCI_BASE_PHY_STATE_RESETTING */
2495 scic_sds_phy_default_start_handler,
2496 scic_sds_phy_default_stop_handler,
2497 scic_sds_phy_default_reset_handler,
2498 scic_sds_phy_default_destroy_handler
2500 scic_sds_phy_default_frame_handler,
2501 scic_sds_phy_resetting_state_event_handler,
2502 scic_sds_phy_default_consume_power_handler
2504 /* SCI_BASE_PHY_STATE_FINAL */
2507 scic_sds_phy_default_start_handler,
2508 scic_sds_phy_default_stop_handler,
2509 scic_sds_phy_default_reset_handler,
2510 scic_sds_phy_default_destroy_handler
2512 scic_sds_phy_default_frame_handler,
2513 scic_sds_phy_default_event_handler,
2514 scic_sds_phy_default_consume_power_handler
2519 * ****************************************************************************
2520 * * PHY STATE PRIVATE METHODS
2521 * **************************************************************************** */
2525 * @this_phy: This is the struct scic_sds_phy object to stop.
2527 * This method will stop the struct scic_sds_phy object. This does not reset the
2528 * protocol engine it just suspends it and places it in a state where it will
2529 * not cause the end device to power up. none
2531 static void scu_link_layer_stop_protocol_engine(
2532 struct scic_sds_phy *this_phy)
2534 u32 scu_sas_pcfg_value;
2535 u32 enable_spinup_value;
2537 /* Suspend the protocol engine and place it in a sata spinup hold state */
2538 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
2539 scu_sas_pcfg_value |= (
2540 SCU_SAS_PCFG_GEN_BIT(OOB_RESET)
2541 | SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE)
2542 | SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD)
2544 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
2546 /* Disable the notify enable spinup primitives */
2547 enable_spinup_value = SCU_SAS_ENSPINUP_READ(this_phy);
2548 enable_spinup_value &= ~SCU_ENSPINUP_GEN_BIT(ENABLE);
2549 SCU_SAS_ENSPINUP_WRITE(this_phy, enable_spinup_value);
2555 * This method will start the OOB/SN state machine for this struct scic_sds_phy object.
2557 static void scu_link_layer_start_oob(
2558 struct scic_sds_phy *this_phy)
2560 u32 scu_sas_pcfg_value;
2562 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
2563 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
2564 scu_sas_pcfg_value &=
2565 ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) | SCU_SAS_PCFG_GEN_BIT(HARD_RESET));
2567 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
2573 * This method will transmit a hard reset request on the specified phy. The SCU
2574 * hardware requires that we reset the OOB state machine and set the hard reset
2575 * bit in the phy configuration register. We then must start OOB over with the
2576 * hard reset bit set.
2578 static void scu_link_layer_tx_hard_reset(
2579 struct scic_sds_phy *this_phy)
2581 u32 phy_configuration_value;
2584 * SAS Phys must wait for the HARD_RESET_TX event notification to transition
2585 * to the starting state. */
2586 phy_configuration_value = SCU_SAS_PCFG_READ(this_phy);
2587 phy_configuration_value |=
2588 (SCU_SAS_PCFG_GEN_BIT(HARD_RESET) | SCU_SAS_PCFG_GEN_BIT(OOB_RESET));
2589 SCU_SAS_PCFG_WRITE(this_phy, phy_configuration_value);
2591 /* Now take the OOB state machine out of reset */
2592 phy_configuration_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
2593 phy_configuration_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
2594 SCU_SAS_PCFG_WRITE(this_phy, phy_configuration_value);
2598 * ****************************************************************************
2599 * * PHY BASE STATE METHODS
2600 * **************************************************************************** */
2604 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2606 * This method will perform the actions required by the struct scic_sds_phy on
2607 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
2608 * handlers for the phy object base state machine initial state. none
2610 static void scic_sds_phy_initial_state_enter(
2611 struct sci_base_object *object)
2613 struct scic_sds_phy *this_phy;
2615 this_phy = (struct scic_sds_phy *)object;
2617 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_STOPPED);
2622 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2624 * This method will perform the actions required by the struct scic_sds_phy on
2625 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
2626 * handlers for the phy object base state machine initial state. - The SCU
2627 * hardware is requested to stop the protocol engine. none
2629 static void scic_sds_phy_stopped_state_enter(
2630 struct sci_base_object *object)
2632 struct scic_sds_phy *this_phy;
2634 this_phy = (struct scic_sds_phy *)object;
2636 /* / @todo We need to get to the controller to place this PE in a reset state */
2638 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_STOPPED);
2640 scu_link_layer_stop_protocol_engine(this_phy);
2645 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2647 * This method will perform the actions required by the struct scic_sds_phy on
2648 * entering the SCI_BASE_PHY_STATE_STARTING. - This function sets the state
2649 * handlers for the phy object base state machine starting state. - The SCU
2650 * hardware is requested to start OOB/SN on this protocl engine. - The phy
2651 * starting substate machine is started. - If the previous state was the ready
2652 * state then the struct scic_sds_controller is informed that the phy has gone link
2655 static void scic_sds_phy_starting_state_enter(
2656 struct sci_base_object *object)
2658 struct scic_sds_phy *this_phy;
2660 this_phy = (struct scic_sds_phy *)object;
2662 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_STARTING);
2664 scu_link_layer_stop_protocol_engine(this_phy);
2665 scu_link_layer_start_oob(this_phy);
2667 /* We don't know what kind of phy we are going to be just yet */
2668 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
2669 this_phy->bcn_received_while_port_unassigned = false;
2671 /* Change over to the starting substate machine to continue */
2672 sci_base_state_machine_start(&this_phy->starting_substate_machine);
2674 if (this_phy->parent.state_machine.previous_state_id
2675 == SCI_BASE_PHY_STATE_READY) {
2676 scic_sds_controller_link_down(
2677 scic_sds_phy_get_controller(this_phy),
2678 scic_sds_phy_get_port(this_phy),
2686 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2688 * This method will perform the actions required by the struct scic_sds_phy on
2689 * entering the SCI_BASE_PHY_STATE_READY. - This function sets the state
2690 * handlers for the phy object base state machine ready state. - The SCU
2691 * hardware protocol engine is resumed. - The struct scic_sds_controller is informed
2692 * that the phy object has gone link up. none
2694 static void scic_sds_phy_ready_state_enter(
2695 struct sci_base_object *object)
2697 struct scic_sds_phy *this_phy;
2699 this_phy = (struct scic_sds_phy *)object;
2701 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_READY);
2703 scic_sds_controller_link_up(
2704 scic_sds_phy_get_controller(this_phy),
2705 scic_sds_phy_get_port(this_phy),
2712 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2714 * This method will perform the actions required by the struct scic_sds_phy on exiting
2715 * the SCI_BASE_PHY_STATE_INITIAL. This function suspends the SCU hardware
2716 * protocol engine represented by this struct scic_sds_phy object. none
2718 static void scic_sds_phy_ready_state_exit(
2719 struct sci_base_object *object)
2721 struct scic_sds_phy *this_phy;
2723 this_phy = (struct scic_sds_phy *)object;
2725 scic_sds_phy_suspend(this_phy);
2730 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2732 * This method will perform the actions required by the struct scic_sds_phy on
2733 * entering the SCI_BASE_PHY_STATE_RESETTING. - This function sets the state
2734 * handlers for the phy object base state machine resetting state. none
2736 static void scic_sds_phy_resetting_state_enter(
2737 struct sci_base_object *object)
2739 struct scic_sds_phy *this_phy;
2741 this_phy = (struct scic_sds_phy *)object;
2743 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_RESETTING);
2746 * The phy is being reset, therefore deactivate it from the port.
2747 * In the resetting state we don't notify the user regarding
2748 * link up and link down notifications. */
2749 scic_sds_port_deactivate_phy(this_phy->owning_port, this_phy, false);
2751 if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
2752 scu_link_layer_tx_hard_reset(this_phy);
2755 * The SCU does not need to have a descrete reset state so just go back to
2756 * the starting state. */
2757 sci_base_state_machine_change_state(
2758 &this_phy->parent.state_machine,
2759 SCI_BASE_PHY_STATE_STARTING
2766 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2768 * This method will perform the actions required by the struct scic_sds_phy on
2769 * entering the SCI_BASE_PHY_STATE_FINAL. - This function sets the state
2770 * handlers for the phy object base state machine final state. none
2772 static void scic_sds_phy_final_state_enter(
2773 struct sci_base_object *object)
2775 struct scic_sds_phy *this_phy;
2777 this_phy = (struct scic_sds_phy *)object;
2779 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_FINAL);
2781 /* Nothing to do here */
2784 /* --------------------------------------------------------------------------- */
2786 const struct sci_base_state scic_sds_phy_state_table[] = {
2787 [SCI_BASE_PHY_STATE_INITIAL] = {
2788 .enter_state = scic_sds_phy_initial_state_enter,
2790 [SCI_BASE_PHY_STATE_STOPPED] = {
2791 .enter_state = scic_sds_phy_stopped_state_enter,
2793 [SCI_BASE_PHY_STATE_STARTING] = {
2794 .enter_state = scic_sds_phy_starting_state_enter,
2796 [SCI_BASE_PHY_STATE_READY] = {
2797 .enter_state = scic_sds_phy_ready_state_enter,
2798 .exit_state = scic_sds_phy_ready_state_exit,
2800 [SCI_BASE_PHY_STATE_RESETTING] = {
2801 .enter_state = scic_sds_phy_resetting_state_enter,
2803 [SCI_BASE_PHY_STATE_FINAL] = {
2804 .enter_state = scic_sds_phy_final_state_enter,