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.
57 #include "scic_port.h"
58 #include "scic_sds_port.h"
59 #include "remote_device.h"
60 #include "remote_node_context.h"
61 #include "registers.h"
63 #include "scu_task_context.h"
65 #define SCIC_SDS_PORT_MIN_TIMER_COUNT (SCI_MAX_PORTS)
66 #define SCIC_SDS_PORT_MAX_TIMER_COUNT (SCI_MAX_PORTS)
68 #define SCIC_SDS_PORT_HARD_RESET_TIMEOUT (1000)
69 #define SCU_DUMMY_INDEX (0xFFFF)
74 * @sci_port: This is the port object to which the phy is being assigned.
75 * @phy_index: This is the phy index that is being assigned to the port.
77 * This method will return a true value if the specified phy can be assigned to
78 * this port The following is a list of phys for each port that are allowed: -
79 * Port 0 - 3 2 1 0 - Port 1 - 1 - Port 2 - 3 2 - Port 3 - 3 This method
80 * doesn't preclude all configurations. It merely ensures that a phy is part
81 * of the allowable set of phy identifiers for that port. For example, one
82 * could assign phy 3 to port 0 and no other phys. Please refer to
83 * scic_sds_port_is_phy_mask_valid() for information regarding whether the
84 * phy_mask for a port can be supported. bool true if this is a valid phy
85 * assignment for the port false if this is not a valid phy assignment for the
88 bool scic_sds_port_is_valid_phy_assignment(
89 struct scic_sds_port *sci_port,
92 /* Initialize to invalid value. */
93 u32 existing_phy_index = SCI_MAX_PHYS;
96 if ((sci_port->physical_port_index == 1) && (phy_index != 1)) {
100 if (sci_port->physical_port_index == 3 && phy_index != 3) {
105 (sci_port->physical_port_index == 2)
106 && ((phy_index == 0) || (phy_index == 1))
111 for (index = 0; index < SCI_MAX_PHYS; index++) {
112 if ((sci_port->phy_table[index] != NULL)
113 && (index != phy_index)) {
114 existing_phy_index = index;
119 * Ensure that all of the phys in the port are capable of
120 * operating at the same maximum link rate. */
122 (existing_phy_index < SCI_MAX_PHYS)
123 && (sci_port->owning_controller->user_parameters.sds1.phys[
124 phy_index].max_speed_generation !=
125 sci_port->owning_controller->user_parameters.sds1.phys[
126 existing_phy_index].max_speed_generation)
134 * This method requests a list (mask) of the phys contained in the supplied SAS
136 * @sci_port: a handle corresponding to the SAS port for which to return the
139 * Return a bit mask indicating which phys are a part of this port. Each bit
140 * corresponds to a phy identifier (e.g. bit 0 = phy id 0).
142 static u32 scic_sds_port_get_phys(struct scic_sds_port *sci_port)
149 for (index = 0; index < SCI_MAX_PHYS; index++) {
150 if (sci_port->phy_table[index] != NULL) {
151 mask |= (1 << index);
160 * @sci_port: This is the port object for which to determine if the phy mask
163 * This method will return a true value if the port's phy mask can be supported
164 * by the SCU. The following is a list of valid PHY mask configurations for
165 * each port: - Port 0 - [[3 2] 1] 0 - Port 1 - [1] - Port 2 - [[3] 2]
166 * - Port 3 - [3] This method returns a boolean indication specifying if the
167 * phy mask can be supported. true if this is a valid phy assignment for the
168 * port false if this is not a valid phy assignment for the port
170 static bool scic_sds_port_is_phy_mask_valid(
171 struct scic_sds_port *sci_port,
174 if (sci_port->physical_port_index == 0) {
175 if (((phy_mask & 0x0F) == 0x0F)
176 || ((phy_mask & 0x03) == 0x03)
177 || ((phy_mask & 0x01) == 0x01)
180 } else if (sci_port->physical_port_index == 1) {
181 if (((phy_mask & 0x02) == 0x02)
184 } else if (sci_port->physical_port_index == 2) {
185 if (((phy_mask & 0x0C) == 0x0C)
186 || ((phy_mask & 0x04) == 0x04)
189 } else if (sci_port->physical_port_index == 3) {
190 if (((phy_mask & 0x08) == 0x08)
200 * @sci_port: This parameter specifies the port from which to return a
203 * This method retrieves a currently active (i.e. connected) phy contained in
204 * the port. Currently, the lowest order phy that is connected is returned.
205 * This method returns a pointer to a SCIS_SDS_PHY object. NULL This value is
206 * returned if there are no currently active (i.e. connected to a remote end
207 * point) phys contained in the port. All other values specify a struct scic_sds_phy
208 * object that is active in the port.
210 static struct scic_sds_phy *scic_sds_port_get_a_connected_phy(
211 struct scic_sds_port *sci_port
214 struct scic_sds_phy *phy;
216 for (index = 0; index < SCI_MAX_PHYS; index++) {
218 * Ensure that the phy is both part of the port and currently
219 * connected to the remote end-point. */
220 phy = sci_port->phy_table[index];
223 && scic_sds_port_active_phy(sci_port, phy)
233 * scic_sds_port_set_phy() -
234 * @out]: port The port object to which the phy assignement is being made.
235 * @out]: phy The phy which is being assigned to the port.
237 * This method attempts to make the assignment of the phy to the port. If
238 * successful the phy is assigned to the ports phy table. bool true if the phy
239 * assignment can be made. false if the phy assignement can not be made. This
240 * is a functional test that only fails if the phy is currently assigned to a
243 static enum sci_status scic_sds_port_set_phy(
244 struct scic_sds_port *port,
245 struct scic_sds_phy *phy)
248 * Check to see if we can add this phy to a port
249 * that means that the phy is not part of a port and that the port does
250 * not already have a phy assinged to the phy index. */
252 (port->phy_table[phy->phy_index] == NULL)
253 && (scic_sds_phy_get_port(phy) == NULL)
254 && scic_sds_port_is_valid_phy_assignment(port, phy->phy_index)
257 * Phy is being added in the stopped state so we are in MPC mode
258 * make logical port index = physical port index */
259 port->logical_port_index = port->physical_port_index;
260 port->phy_table[phy->phy_index] = phy;
261 scic_sds_phy_set_port(phy, port);
270 * scic_sds_port_clear_phy() -
271 * @out]: port The port from which the phy is being cleared.
272 * @out]: phy The phy being cleared from the port.
274 * This method will clear the phy assigned to this port. This method fails if
275 * this phy is not currently assinged to this port. bool true if the phy is
276 * removed from the port. false if this phy is not assined to this port.
278 static enum sci_status scic_sds_port_clear_phy(
279 struct scic_sds_port *port,
280 struct scic_sds_phy *phy)
282 /* Make sure that this phy is part of this port */
283 if (port->phy_table[phy->phy_index] == phy &&
284 scic_sds_phy_get_port(phy) == port) {
285 struct scic_sds_controller *scic = port->owning_controller;
286 struct isci_host *ihost = scic_to_ihost(scic);
288 /* Yep it is assigned to this port so remove it */
289 scic_sds_phy_set_port(phy, &ihost->ports[SCI_MAX_PORTS].sci);
290 port->phy_table[phy->phy_index] = NULL;
298 * scic_sds_port_add_phy() -
299 * @sci_port: This parameter specifies the port in which the phy will be added.
300 * @sci_phy: This parameter is the phy which is to be added to the port.
302 * This method will add a PHY to the selected port. This method returns an
303 * enum sci_status. SCI_SUCCESS the phy has been added to the port. Any other status
304 * is failre to add the phy to the port.
306 enum sci_status scic_sds_port_add_phy(
307 struct scic_sds_port *sci_port,
308 struct scic_sds_phy *sci_phy)
310 return sci_port->state_handlers->add_phy_handler(
316 * scic_sds_port_remove_phy() -
317 * @sci_port: This parameter specifies the port in which the phy will be added.
318 * @sci_phy: This parameter is the phy which is to be added to the port.
320 * This method will remove the PHY from the selected PORT. This method returns
321 * an enum sci_status. SCI_SUCCESS the phy has been removed from the port. Any other
322 * status is failre to add the phy to the port.
324 enum sci_status scic_sds_port_remove_phy(
325 struct scic_sds_port *sci_port,
326 struct scic_sds_phy *sci_phy)
328 return sci_port->state_handlers->remove_phy_handler(
333 * This method requests the SAS address for the supplied SAS port from the SCI
335 * @sci_port: a handle corresponding to the SAS port for which to return the
337 * @sas_address: This parameter specifies a pointer to a SAS address structure
338 * into which the core will copy the SAS address for the port.
341 void scic_sds_port_get_sas_address(
342 struct scic_sds_port *sci_port,
343 struct sci_sas_address *sas_address)
347 sas_address->high = 0;
348 sas_address->low = 0;
350 for (index = 0; index < SCI_MAX_PHYS; index++) {
351 if (sci_port->phy_table[index] != NULL) {
352 scic_sds_phy_get_sas_address(sci_port->phy_table[index], sas_address);
358 * This function will indicate which protocols are supported by this port.
359 * @sci_port: a handle corresponding to the SAS port for which to return the
360 * supported protocols.
361 * @protocols: This parameter specifies a pointer to a data structure
362 * which the core will copy the protocol values for the port from the
363 * transmit_identification register.
366 scic_sds_port_get_protocols(struct scic_sds_port *sci_port,
367 struct scic_phy_proto *protocols)
373 for (index = 0; index < SCI_MAX_PHYS; index++) {
374 if (sci_port->phy_table[index] != NULL) {
375 scic_sds_phy_get_protocols(sci_port->phy_table[index],
382 * This function requests the SAS address for the device directly attached to
384 * @sci_port: a handle corresponding to the SAS port for which to return the
386 * @sas_address: This parameter specifies a pointer to a SAS address structure
387 * into which the core will copy the SAS address for the device directly
388 * attached to the port.
391 void scic_sds_port_get_attached_sas_address(
392 struct scic_sds_port *sci_port,
393 struct sci_sas_address *sas_address)
395 struct scic_sds_phy *sci_phy;
398 * Ensure that the phy is both part of the port and currently
399 * connected to the remote end-point.
401 sci_phy = scic_sds_port_get_a_connected_phy(sci_port);
403 if (sci_phy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA) {
404 scic_sds_phy_get_attached_sas_address(sci_phy,
407 scic_sds_phy_get_sas_address(sci_phy, sas_address);
408 sas_address->low += sci_phy->phy_index;
411 sas_address->high = 0;
412 sas_address->low = 0;
417 * scic_sds_port_construct_dummy_rnc() - create dummy rnc for si workaround
419 * @sci_port: logical port on which we need to create the remote node context
420 * @rni: remote node index for this remote node context.
422 * This routine will construct a dummy remote node context data structure
423 * This structure will be posted to the hardware to work around a scheduler
424 * error in the hardware.
426 static void scic_sds_port_construct_dummy_rnc(struct scic_sds_port *sci_port, u16 rni)
428 union scu_remote_node_context *rnc;
430 rnc = &sci_port->owning_controller->remote_node_context_table[rni];
432 memset(rnc, 0, sizeof(union scu_remote_node_context));
434 rnc->ssp.remote_sas_address_hi = 0;
435 rnc->ssp.remote_sas_address_lo = 0;
437 rnc->ssp.remote_node_index = rni;
438 rnc->ssp.remote_node_port_width = 1;
439 rnc->ssp.logical_port_index = sci_port->physical_port_index;
441 rnc->ssp.nexus_loss_timer_enable = false;
442 rnc->ssp.check_bit = false;
443 rnc->ssp.is_valid = true;
444 rnc->ssp.is_remote_node_context = true;
445 rnc->ssp.function_number = 0;
446 rnc->ssp.arbitration_wait_time = 0;
450 * scic_sds_port_construct_dummy_task() - create dummy task for si workaround
451 * @sci_port The logical port on which we need to create the
452 * remote node context.
454 * @tci The remote node index for this remote node context.
456 * This routine will construct a dummy task context data structure. This
457 * structure will be posted to the hardwre to work around a scheduler error
461 static void scic_sds_port_construct_dummy_task(struct scic_sds_port *sci_port, u16 tci)
463 struct scu_task_context *task_context;
465 task_context = scic_sds_controller_get_task_context_buffer(sci_port->owning_controller, tci);
467 memset(task_context, 0, sizeof(struct scu_task_context));
469 task_context->abort = 0;
470 task_context->priority = 0;
471 task_context->initiator_request = 1;
472 task_context->connection_rate = 1;
473 task_context->protocol_engine_index = 0;
474 task_context->logical_port_index = sci_port->physical_port_index;
475 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
476 task_context->task_index = scic_sds_io_tag_get_index(tci);
477 task_context->valid = SCU_TASK_CONTEXT_VALID;
478 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
480 task_context->remote_node_index = sci_port->reserved_rni;
481 task_context->command_code = 0;
483 task_context->link_layer_control = 0;
484 task_context->do_not_dma_ssp_good_response = 1;
485 task_context->strict_ordering = 0;
486 task_context->control_frame = 0;
487 task_context->timeout_enable = 0;
488 task_context->block_guard_enable = 0;
490 task_context->address_modifier = 0;
492 task_context->task_phase = 0x01;
495 static void scic_sds_port_destroy_dummy_resources(struct scic_sds_port *sci_port)
497 struct scic_sds_controller *scic = sci_port->owning_controller;
499 if (sci_port->reserved_tci != SCU_DUMMY_INDEX)
500 scic_controller_free_io_tag(scic, sci_port->reserved_tci);
502 if (sci_port->reserved_rni != SCU_DUMMY_INDEX)
503 scic_sds_remote_node_table_release_remote_node_index(&scic->available_remote_nodes,
504 1, sci_port->reserved_rni);
506 sci_port->reserved_rni = SCU_DUMMY_INDEX;
507 sci_port->reserved_tci = SCU_DUMMY_INDEX;
511 * This method performs initialization of the supplied port. Initialization
512 * includes: - state machine initialization - member variable initialization
513 * - configuring the phy_mask
515 * @transport_layer_registers:
516 * @port_task_scheduler_registers:
517 * @port_configuration_regsiter:
519 * enum sci_status SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION This value is returned
520 * if the phy being added to the port
522 enum sci_status scic_sds_port_initialize(
523 struct scic_sds_port *sci_port,
524 void __iomem *port_task_scheduler_registers,
525 void __iomem *port_configuration_regsiter,
526 void __iomem *viit_registers)
528 sci_port->port_task_scheduler_registers = port_task_scheduler_registers;
529 sci_port->port_pe_configuration_register = port_configuration_regsiter;
530 sci_port->viit_registers = viit_registers;
536 * scic_port_get_properties() - This method simply returns the properties
537 * regarding the port, such as: physical index, protocols, sas address, etc.
538 * @port: this parameter specifies the port for which to retrieve the physical
540 * @properties: This parameter specifies the properties structure into which to
541 * copy the requested information.
543 * Indicate if the user specified a valid port. SCI_SUCCESS This value is
544 * returned if the specified port was valid. SCI_FAILURE_INVALID_PORT This
545 * value is returned if the specified port is not valid. When this value is
546 * returned, no data is copied to the properties output parameter.
548 enum sci_status scic_port_get_properties(
549 struct scic_sds_port *port,
550 struct scic_port_properties *prop)
552 if ((port == NULL) ||
553 (port->logical_port_index == SCIC_SDS_DUMMY_PORT))
554 return SCI_FAILURE_INVALID_PORT;
556 prop->index = port->logical_port_index;
557 prop->phy_mask = scic_sds_port_get_phys(port);
558 scic_sds_port_get_sas_address(port, &prop->local.sas_address);
559 scic_sds_port_get_protocols(port, &prop->local.protocols);
560 scic_sds_port_get_attached_sas_address(port, &prop->remote.sas_address);
566 * scic_port_hard_reset() - perform port hard reset
567 * @port: a handle corresponding to the SAS port to be hard reset.
568 * @reset_timeout: This parameter specifies the number of milliseconds in which
569 * the port reset operation should complete.
571 * The SCI User callback in scic_user_callbacks_t will only be called once for
572 * each phy in the SAS Port at completion of the hard reset sequence. Return a
573 * status indicating whether the hard reset started successfully. SCI_SUCCESS
574 * This value is returned if the hard reset operation started successfully.
576 enum sci_status scic_port_hard_reset(
577 struct scic_sds_port *port,
580 return port->state_handlers->reset_handler(
581 port, reset_timeout);
585 * This method assigns the direct attached device ID for this port.
587 * @param[in] sci_port The port for which the direct attached device id is to
589 * @param[in] device_id The direct attached device ID to assign to the port.
590 * This will be the RNi for the device
592 void scic_sds_port_setup_transports(
593 struct scic_sds_port *sci_port,
598 for (index = 0; index < SCI_MAX_PHYS; index++) {
599 if (sci_port->active_phy_mask & (1 << index))
600 scic_sds_phy_setup_transport(sci_port->phy_table[index], device_id);
606 * @sci_port: This is the port on which the phy should be enabled.
607 * @sci_phy: This is the specific phy which to enable.
608 * @do_notify_user: This parameter specifies whether to inform the user (via
609 * scic_cb_port_link_up()) as to the fact that a new phy as become ready.
611 * This function will activate the phy in the port.
612 * Activation includes: - adding
613 * the phy to the port - enabling the Protocol Engine in the silicon. -
614 * notifying the user that the link is up. none
616 static void scic_sds_port_activate_phy(struct scic_sds_port *sci_port,
617 struct scic_sds_phy *sci_phy,
620 struct scic_sds_controller *scic = sci_port->owning_controller;
621 struct isci_host *ihost = scic_to_ihost(scic);
623 if (sci_phy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA)
624 scic_sds_phy_resume(sci_phy);
626 sci_port->active_phy_mask |= 1 << sci_phy->phy_index;
628 scic_sds_controller_clear_invalid_phy(scic, sci_phy);
630 if (do_notify_user == true)
631 isci_port_link_up(ihost, sci_port, sci_phy);
634 void scic_sds_port_deactivate_phy(struct scic_sds_port *sci_port,
635 struct scic_sds_phy *sci_phy,
638 struct scic_sds_controller *scic = scic_sds_port_get_controller(sci_port);
639 struct isci_port *iport = sci_port_to_iport(sci_port);
640 struct isci_host *ihost = scic_to_ihost(scic);
641 struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);
643 sci_port->active_phy_mask &= ~(1 << sci_phy->phy_index);
645 sci_phy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;
647 /* Re-assign the phy back to the LP as if it were a narrow port */
648 writel(sci_phy->phy_index,
649 &sci_port->port_pe_configuration_register[sci_phy->phy_index]);
651 if (do_notify_user == true)
652 isci_port_link_down(ihost, iphy, iport);
657 * @sci_port: This is the port on which the phy should be disabled.
658 * @sci_phy: This is the specific phy which to disabled.
660 * This function will disable the phy and report that the phy is not valid for
661 * this port object. None
663 static void scic_sds_port_invalid_link_up(struct scic_sds_port *sci_port,
664 struct scic_sds_phy *sci_phy)
666 struct scic_sds_controller *scic = sci_port->owning_controller;
669 * Check to see if we have alreay reported this link as bad and if
670 * not go ahead and tell the SCI_USER that we have discovered an
673 if ((scic->invalid_phy_mask & (1 << sci_phy->phy_index)) == 0) {
674 scic_sds_controller_set_invalid_phy(scic, sci_phy);
675 dev_warn(&scic_to_ihost(scic)->pdev->dev, "Invalid link up!\n");
680 * scic_sds_port_general_link_up_handler - phy can be assigned to port?
681 * @sci_port: scic_sds_port object for which has a phy that has gone link up.
682 * @sci_phy: This is the struct scic_sds_phy object that has gone link up.
683 * @do_notify_user: This parameter specifies whether to inform the user (via
684 * scic_cb_port_link_up()) as to the fact that a new phy as become ready.
686 * Determine if this phy can be assigned to this
687 * port . If the phy is not a valid PHY for
688 * this port then the function will notify the user. A PHY can only be
689 * part of a port if it's attached SAS ADDRESS is the same as all other PHYs in
690 * the same port. none
692 static void scic_sds_port_general_link_up_handler(struct scic_sds_port *sci_port,
693 struct scic_sds_phy *sci_phy,
696 struct sci_sas_address port_sas_address;
697 struct sci_sas_address phy_sas_address;
699 scic_sds_port_get_attached_sas_address(sci_port, &port_sas_address);
700 scic_sds_phy_get_attached_sas_address(sci_phy, &phy_sas_address);
702 /* If the SAS address of the new phy matches the SAS address of
703 * other phys in the port OR this is the first phy in the port,
704 * then activate the phy and allow it to be used for operations
707 if ((phy_sas_address.high == port_sas_address.high &&
708 phy_sas_address.low == port_sas_address.low) ||
709 sci_port->active_phy_mask == 0) {
710 struct sci_base_state_machine *sm = &sci_port->state_machine;
712 scic_sds_port_activate_phy(sci_port, sci_phy, do_notify_user);
713 if (sm->current_state_id == SCI_BASE_PORT_STATE_RESETTING)
714 sci_base_state_machine_change_state(sm, SCI_BASE_PORT_STATE_READY);
716 scic_sds_port_invalid_link_up(sci_port, sci_phy);
722 * This method returns false if the port only has a single phy object assigned.
723 * If there are no phys or more than one phy then the method will return
725 * @sci_port: The port for which the wide port condition is to be checked.
727 * bool true Is returned if this is a wide ported port. false Is returned if
728 * this is a narrow port.
730 static bool scic_sds_port_is_wide(struct scic_sds_port *sci_port)
735 for (index = 0; index < SCI_MAX_PHYS; index++) {
736 if (sci_port->phy_table[index] != NULL) {
741 return phy_count != 1;
745 * This method is called by the PHY object when the link is detected. if the
746 * port wants the PHY to continue on to the link up state then the port
747 * layer must return true. If the port object returns false the phy object
748 * must halt its attempt to go link up.
749 * @sci_port: The port associated with the phy object.
750 * @sci_phy: The phy object that is trying to go link up.
752 * true if the phy object can continue to the link up condition. true Is
753 * returned if this phy can continue to the ready state. false Is returned if
754 * can not continue on to the ready state. This notification is in place for
755 * wide ports and direct attached phys. Since there are no wide ported SATA
756 * devices this could become an invalid port configuration.
758 bool scic_sds_port_link_detected(
759 struct scic_sds_port *sci_port,
760 struct scic_sds_phy *sci_phy)
762 if ((sci_port->logical_port_index != SCIC_SDS_DUMMY_PORT) &&
763 (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) &&
764 scic_sds_port_is_wide(sci_port)) {
765 scic_sds_port_invalid_link_up(sci_port, sci_phy);
774 * This method is the entry point for the phy to inform the port that it is now
780 void scic_sds_port_link_up(
781 struct scic_sds_port *sci_port,
782 struct scic_sds_phy *sci_phy)
784 sci_phy->is_in_link_training = false;
786 sci_port->state_handlers->link_up_handler(sci_port, sci_phy);
790 * This method is the entry point for the phy to inform the port that it is no
791 * longer in a ready state
796 void scic_sds_port_link_down(
797 struct scic_sds_port *sci_port,
798 struct scic_sds_phy *sci_phy)
800 sci_port->state_handlers->link_down_handler(sci_port, sci_phy);
804 * This method is called to start an IO request on this port.
811 enum sci_status scic_sds_port_start_io(
812 struct scic_sds_port *sci_port,
813 struct scic_sds_remote_device *sci_dev,
814 struct scic_sds_request *sci_req)
816 return sci_port->state_handlers->start_io_handler(
817 sci_port, sci_dev, sci_req);
821 * This method is called to complete an IO request to the port.
828 enum sci_status scic_sds_port_complete_io(
829 struct scic_sds_port *sci_port,
830 struct scic_sds_remote_device *sci_dev,
831 struct scic_sds_request *sci_req)
833 return sci_port->state_handlers->complete_io_handler(
834 sci_port, sci_dev, sci_req);
838 * This method is provided to timeout requests for port operations. Mostly its
839 * for the port reset operation.
843 static void scic_sds_port_timeout_handler(void *port)
845 struct scic_sds_port *sci_port = port;
848 current_state = sci_base_state_machine_get_state(
849 &sci_port->state_machine);
851 if (current_state == SCI_BASE_PORT_STATE_RESETTING) {
853 * if the port is still in the resetting state then the
854 * timeout fired before the reset completed.
856 sci_base_state_machine_change_state(
857 &sci_port->state_machine,
858 SCI_BASE_PORT_STATE_FAILED);
859 } else if (current_state == SCI_BASE_PORT_STATE_STOPPED) {
861 * if the port is stopped then the start request failed
862 * In this case stay in the stopped state.
864 dev_err(sciport_to_dev(sci_port),
865 "%s: SCIC Port 0x%p failed to stop before tiemout.\n",
868 } else if (current_state == SCI_BASE_PORT_STATE_STOPPING) {
870 * if the port is still stopping then the stop has not
873 isci_port_stop_complete(
874 scic_sds_port_get_controller(sci_port),
876 SCI_FAILURE_TIMEOUT);
879 * The port is in the ready state and we have a timer
880 * reporting a timeout this should not happen.
882 dev_err(sciport_to_dev(sci_port),
883 "%s: SCIC Port 0x%p is processing a timeout operation "
891 /* --------------------------------------------------------------------------- */
894 * This function updates the hardwares VIIT entry for this port.
898 static void scic_sds_port_update_viit_entry(struct scic_sds_port *sci_port)
900 struct sci_sas_address sas_address;
902 scic_sds_port_get_sas_address(sci_port, &sas_address);
904 writel(sas_address.high,
905 &sci_port->viit_registers->initiator_sas_address_hi);
906 writel(sas_address.low,
907 &sci_port->viit_registers->initiator_sas_address_lo);
909 /* This value get cleared just in case its not already cleared */
910 writel(0, &sci_port->viit_registers->reserved);
912 /* We are required to update the status register last */
913 writel(SCU_VIIT_ENTRY_ID_VIIT |
914 SCU_VIIT_IPPT_INITIATOR |
915 ((1 << sci_port->physical_port_index) << SCU_VIIT_ENTRY_LPVIE_SHIFT) |
916 SCU_VIIT_STATUS_ALL_VALID,
917 &sci_port->viit_registers->status);
921 * This method returns the maximum allowed speed for data transfers on this
922 * port. This maximum allowed speed evaluates to the maximum speed of the
923 * slowest phy in the port.
924 * @sci_port: This parameter specifies the port for which to retrieve the
925 * maximum allowed speed.
927 * This method returns the maximum negotiated speed of the slowest phy in the
930 enum sas_linkrate scic_sds_port_get_max_allowed_speed(
931 struct scic_sds_port *sci_port)
934 enum sas_linkrate max_allowed_speed = SAS_LINK_RATE_6_0_GBPS;
935 struct scic_sds_phy *phy = NULL;
938 * Loop through all of the phys in this port and find the phy with the
939 * lowest maximum link rate. */
940 for (index = 0; index < SCI_MAX_PHYS; index++) {
941 phy = sci_port->phy_table[index];
944 && (scic_sds_port_active_phy(sci_port, phy) == true)
945 && (phy->max_negotiated_speed < max_allowed_speed)
947 max_allowed_speed = phy->max_negotiated_speed;
950 return max_allowed_speed;
955 * This method passes the event to core user.
956 * @sci_port: The port that a BCN happens.
957 * @sci_phy: The phy that receives BCN.
960 void scic_sds_port_broadcast_change_received(
961 struct scic_sds_port *sci_port,
962 struct scic_sds_phy *sci_phy)
964 struct scic_sds_controller *scic = sci_port->owning_controller;
965 struct isci_host *ihost = scic_to_ihost(scic);
967 /* notify the user. */
968 isci_port_bc_change_received(ihost, sci_port, sci_phy);
973 * This API methhod enables the broadcast change notification from underneath
975 * @sci_port: The port that a BCN had been disabled from.
978 void scic_port_enable_broadcast_change_notification(
979 struct scic_sds_port *port)
981 struct scic_sds_phy *phy;
985 /* Loop through all of the phys to enable BCN. */
986 for (index = 0; index < SCI_MAX_PHYS; index++) {
987 phy = port->phy_table[index];
990 readl(&phy->link_layer_registers->link_layer_control);
992 /* clear the bit by writing 1. */
993 writel(register_value,
994 &phy->link_layer_registers->link_layer_control);
1000 * ****************************************************************************
1001 * * READY SUBSTATE HANDLERS
1002 * **************************************************************************** */
1005 * This method is the general ready state stop handler for the struct scic_sds_port
1006 * object. This function will transition the ready substate machine to its
1007 * final state. enum sci_status SCI_SUCCESS
1009 static enum sci_status scic_sds_port_ready_substate_stop_handler(
1010 struct scic_sds_port *port)
1012 sci_base_state_machine_change_state(
1013 &port->state_machine,
1014 SCI_BASE_PORT_STATE_STOPPING
1021 * This method is the general ready substate complete io handler for the
1022 * struct scic_sds_port object. This function decrments the outstanding request count
1023 * for this port object. enum sci_status SCI_SUCCESS
1025 static enum sci_status scic_sds_port_ready_substate_complete_io_handler(
1026 struct scic_sds_port *port,
1027 struct scic_sds_remote_device *device,
1028 struct scic_sds_request *io_request)
1030 scic_sds_port_decrement_request_count(port);
1035 static enum sci_status scic_sds_port_ready_substate_add_phy_handler(
1036 struct scic_sds_port *port,
1037 struct scic_sds_phy *phy)
1039 enum sci_status status;
1041 status = scic_sds_port_set_phy(port, phy);
1043 if (status == SCI_SUCCESS) {
1044 scic_sds_port_general_link_up_handler(port, phy, true);
1046 port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
1048 sci_base_state_machine_change_state(
1049 &port->ready_substate_machine,
1050 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1058 static enum sci_status scic_sds_port_ready_substate_remove_phy_handler(
1059 struct scic_sds_port *port,
1060 struct scic_sds_phy *phy)
1062 enum sci_status status;
1064 status = scic_sds_port_clear_phy(port, phy);
1066 if (status == SCI_SUCCESS) {
1067 scic_sds_port_deactivate_phy(port, phy, true);
1069 port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
1071 sci_base_state_machine_change_state(
1072 &port->ready_substate_machine,
1073 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1081 * ****************************************************************************
1082 * * READY SUBSTATE WAITING HANDLERS
1083 * **************************************************************************** */
1087 * @sci_port: This is the struct scic_sds_port object that which has a phy that has
1089 * @sci_phy: This is the struct scic_sds_phy object that has gone link up.
1091 * This method is the ready waiting substate link up handler for the
1092 * struct scic_sds_port object. This methos will report the link up condition for
1093 * this port and will transition to the ready operational substate. none
1095 static void scic_sds_port_ready_waiting_substate_link_up_handler(
1096 struct scic_sds_port *sci_port,
1097 struct scic_sds_phy *sci_phy)
1100 * Since this is the first phy going link up for the port we can just enable
1101 * it and continue. */
1102 scic_sds_port_activate_phy(sci_port, sci_phy, true);
1104 sci_base_state_machine_change_state(
1105 &sci_port->ready_substate_machine,
1106 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1111 * This method is the ready waiting substate start io handler for the
1112 * struct scic_sds_port object. The port object can not accept new requests so the
1113 * request is failed. enum sci_status SCI_FAILURE_INVALID_STATE
1115 static enum sci_status scic_sds_port_ready_waiting_substate_start_io_handler(
1116 struct scic_sds_port *port,
1117 struct scic_sds_remote_device *device,
1118 struct scic_sds_request *io_request)
1120 return SCI_FAILURE_INVALID_STATE;
1124 * ****************************************************************************
1125 * * READY SUBSTATE OPERATIONAL HANDLERS
1126 * **************************************************************************** */
1129 * This method will casue the port to reset. enum sci_status SCI_SUCCESS
1132 sci_status scic_sds_port_ready_operational_substate_reset_handler(
1133 struct scic_sds_port *port,
1136 enum sci_status status = SCI_FAILURE_INVALID_PHY;
1138 struct scic_sds_phy *selected_phy = NULL;
1141 /* Select a phy on which we can send the hard reset request. */
1143 (phy_index < SCI_MAX_PHYS) && (selected_phy == NULL);
1145 selected_phy = port->phy_table[phy_index];
1147 if ((selected_phy != NULL) &&
1148 !scic_sds_port_active_phy(port, selected_phy)) {
1150 * We found a phy but it is not ready select
1153 selected_phy = NULL;
1157 /* If we have a phy then go ahead and start the reset procedure */
1158 if (selected_phy != NULL) {
1159 status = scic_sds_phy_reset(selected_phy);
1161 if (status == SCI_SUCCESS) {
1162 isci_timer_start(port->timer_handle, timeout);
1163 port->not_ready_reason =
1164 SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED;
1166 sci_base_state_machine_change_state(
1167 &port->state_machine,
1168 SCI_BASE_PORT_STATE_RESETTING);
1176 * scic_sds_port_ready_operational_substate_link_up_handler() -
1177 * @sci_port: This is the struct scic_sds_port object that which has a phy that has
1179 * @sci_phy: This is the struct scic_sds_phy object that has gone link up.
1181 * This method is the ready operational substate link up handler for the
1182 * struct scic_sds_port object. This function notifies the SCI User that the phy has
1183 * gone link up. none
1185 static void scic_sds_port_ready_operational_substate_link_up_handler(
1186 struct scic_sds_port *sci_port,
1187 struct scic_sds_phy *sci_phy)
1189 scic_sds_port_general_link_up_handler(sci_port, sci_phy, true);
1193 * scic_sds_port_ready_operational_substate_link_down_handler() -
1194 * @sci_port: This is the struct scic_sds_port object that which has a phy that has
1196 * @sci_phy: This is the struct scic_sds_phy object that has gone link down.
1198 * This method is the ready operational substate link down handler for the
1199 * struct scic_sds_port object. This function notifies the SCI User that the phy has
1200 * gone link down and if this is the last phy in the port the port will change
1201 * state to the ready waiting substate. none
1203 static void scic_sds_port_ready_operational_substate_link_down_handler(
1204 struct scic_sds_port *sci_port,
1205 struct scic_sds_phy *sci_phy)
1207 scic_sds_port_deactivate_phy(sci_port, sci_phy, true);
1210 * If there are no active phys left in the port, then transition
1211 * the port to the WAITING state until such time as a phy goes
1213 if (sci_port->active_phy_mask == 0)
1214 sci_base_state_machine_change_state(&sci_port->ready_substate_machine,
1215 SCIC_SDS_PORT_READY_SUBSTATE_WAITING);
1219 * This method is the ready operational substate start io handler for the
1220 * struct scic_sds_port object. This function incremetns the outstanding request
1221 * count for this port object. enum sci_status SCI_SUCCESS
1223 static enum sci_status scic_sds_port_ready_operational_substate_start_io_handler(
1224 struct scic_sds_port *port,
1225 struct scic_sds_remote_device *device,
1226 struct scic_sds_request *io_request)
1228 port->started_request_count++;
1233 * ****************************************************************************
1234 * * READY SUBSTATE OPERATIONAL HANDLERS
1235 * **************************************************************************** */
1238 * This is the default method for a port add phy request. It will report a
1239 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1241 static enum sci_status scic_sds_port_ready_configuring_substate_add_phy_handler(
1242 struct scic_sds_port *port,
1243 struct scic_sds_phy *phy)
1245 enum sci_status status;
1247 status = scic_sds_port_set_phy(port, phy);
1249 if (status == SCI_SUCCESS) {
1250 scic_sds_port_general_link_up_handler(port, phy, true);
1253 * Re-enter the configuring state since this may be the last phy in
1255 sci_base_state_machine_change_state(
1256 &port->ready_substate_machine,
1257 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1265 * This is the default method for a port remove phy request. It will report a
1266 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1268 static enum sci_status scic_sds_port_ready_configuring_substate_remove_phy_handler(
1269 struct scic_sds_port *port,
1270 struct scic_sds_phy *phy)
1272 enum sci_status status;
1274 status = scic_sds_port_clear_phy(port, phy);
1276 if (status == SCI_SUCCESS) {
1277 scic_sds_port_deactivate_phy(port, phy, true);
1280 * Re-enter the configuring state since this may be the last phy in
1282 sci_base_state_machine_change_state(
1283 &port->ready_substate_machine,
1284 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1292 * scic_sds_port_ready_configuring_substate_complete_io_handler() -
1293 * @port: This is the port that is being requested to complete the io request.
1294 * @device: This is the device on which the io is completing.
1296 * This method will decrement the outstanding request count for this port. If
1297 * the request count goes to 0 then the port can be reprogrammed with its new
1300 static enum sci_status
1301 scic_sds_port_ready_configuring_substate_complete_io_handler(
1302 struct scic_sds_port *port,
1303 struct scic_sds_remote_device *device,
1304 struct scic_sds_request *io_request)
1306 scic_sds_port_decrement_request_count(port);
1308 if (port->started_request_count == 0) {
1309 sci_base_state_machine_change_state(
1310 &port->ready_substate_machine,
1311 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1318 static enum sci_status default_port_handler(struct scic_sds_port *sci_port,
1321 dev_warn(sciport_to_dev(sci_port),
1322 "%s: in wrong state: %d\n", func,
1323 sci_base_state_machine_get_state(&sci_port->state_machine));
1324 return SCI_FAILURE_INVALID_STATE;
1327 static enum sci_status
1328 scic_sds_port_default_start_handler(struct scic_sds_port *sci_port)
1330 return default_port_handler(sci_port, __func__);
1333 static enum sci_status
1334 scic_sds_port_default_stop_handler(struct scic_sds_port *sci_port)
1336 return default_port_handler(sci_port, __func__);
1339 static enum sci_status
1340 scic_sds_port_default_destruct_handler(struct scic_sds_port *sci_port)
1342 return default_port_handler(sci_port, __func__);
1345 static enum sci_status
1346 scic_sds_port_default_reset_handler(struct scic_sds_port *sci_port,
1349 return default_port_handler(sci_port, __func__);
1352 static enum sci_status
1353 scic_sds_port_default_add_phy_handler(struct scic_sds_port *sci_port,
1354 struct scic_sds_phy *base_phy)
1356 return default_port_handler(sci_port, __func__);
1359 static enum sci_status
1360 scic_sds_port_default_remove_phy_handler(struct scic_sds_port *sci_port,
1361 struct scic_sds_phy *base_phy)
1363 return default_port_handler(sci_port, __func__);
1367 * This is the default method for a port unsolicited frame request. It will
1368 * report a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE Is it even
1369 * possible to receive an unsolicited frame directed to a port object? It
1370 * seems possible if we implementing virtual functions but until then?
1372 static enum sci_status
1373 scic_sds_port_default_frame_handler(struct scic_sds_port *sci_port,
1376 struct scic_sds_controller *scic = scic_sds_port_get_controller(sci_port);
1378 default_port_handler(sci_port, __func__);
1379 scic_sds_controller_release_frame(scic, frame_index);
1381 return SCI_FAILURE_INVALID_STATE;
1384 static enum sci_status scic_sds_port_default_event_handler(struct scic_sds_port *sci_port,
1387 return default_port_handler(sci_port, __func__);
1390 static void scic_sds_port_default_link_up_handler(struct scic_sds_port *sci_port,
1391 struct scic_sds_phy *sci_phy)
1393 default_port_handler(sci_port, __func__);
1396 static void scic_sds_port_default_link_down_handler(struct scic_sds_port *sci_port,
1397 struct scic_sds_phy *sci_phy)
1399 default_port_handler(sci_port, __func__);
1402 static enum sci_status scic_sds_port_default_start_io_handler(struct scic_sds_port *sci_port,
1403 struct scic_sds_remote_device *sci_dev,
1404 struct scic_sds_request *sci_req)
1406 return default_port_handler(sci_port, __func__);
1409 static enum sci_status scic_sds_port_default_complete_io_handler(struct scic_sds_port *sci_port,
1410 struct scic_sds_remote_device *sci_dev,
1411 struct scic_sds_request *sci_req)
1413 return default_port_handler(sci_port, __func__);
1418 static struct scic_sds_port_state_handler
1419 scic_sds_port_ready_substate_handler_table[SCIC_SDS_PORT_READY_MAX_SUBSTATES] = {
1421 /* SCIC_SDS_PORT_READY_SUBSTATE_WAITING */
1422 scic_sds_port_default_start_handler,
1423 scic_sds_port_ready_substate_stop_handler,
1424 scic_sds_port_default_destruct_handler,
1425 scic_sds_port_default_reset_handler,
1426 scic_sds_port_ready_substate_add_phy_handler,
1427 scic_sds_port_default_remove_phy_handler,
1428 scic_sds_port_default_frame_handler,
1429 scic_sds_port_default_event_handler,
1430 scic_sds_port_ready_waiting_substate_link_up_handler,
1431 scic_sds_port_default_link_down_handler,
1432 scic_sds_port_ready_waiting_substate_start_io_handler,
1433 scic_sds_port_ready_substate_complete_io_handler,
1437 /* SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL */
1438 scic_sds_port_default_start_handler,
1439 scic_sds_port_ready_substate_stop_handler,
1440 scic_sds_port_default_destruct_handler,
1441 scic_sds_port_ready_operational_substate_reset_handler,
1442 scic_sds_port_ready_substate_add_phy_handler,
1443 scic_sds_port_ready_substate_remove_phy_handler,
1444 scic_sds_port_default_frame_handler,
1445 scic_sds_port_default_event_handler,
1446 scic_sds_port_ready_operational_substate_link_up_handler,
1447 scic_sds_port_ready_operational_substate_link_down_handler,
1448 scic_sds_port_ready_operational_substate_start_io_handler,
1449 scic_sds_port_ready_substate_complete_io_handler,
1453 /* SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING */
1454 scic_sds_port_default_start_handler,
1455 scic_sds_port_ready_substate_stop_handler,
1456 scic_sds_port_default_destruct_handler,
1457 scic_sds_port_default_reset_handler,
1458 scic_sds_port_ready_configuring_substate_add_phy_handler,
1459 scic_sds_port_ready_configuring_substate_remove_phy_handler,
1460 scic_sds_port_default_frame_handler,
1461 scic_sds_port_default_event_handler,
1462 scic_sds_port_default_link_up_handler,
1463 scic_sds_port_default_link_down_handler,
1464 scic_sds_port_default_start_io_handler,
1465 scic_sds_port_ready_configuring_substate_complete_io_handler
1470 * scic_sds_port_set_ready_state_handlers() -
1472 * This macro sets the port ready substate handlers.
1474 #define scic_sds_port_set_ready_state_handlers(port, state_id) \
1475 scic_sds_port_set_state_handlers(\
1476 port, &scic_sds_port_ready_substate_handler_table[(state_id)] \
1480 * ******************************************************************************
1481 * * PORT STATE PRIVATE METHODS
1482 * ****************************************************************************** */
1486 * @sci_port: This is the struct scic_sds_port object to suspend.
1488 * This method will susped the port task scheduler for this port object. none
1491 scic_sds_port_suspend_port_task_scheduler(struct scic_sds_port *port)
1493 u32 pts_control_value;
1495 pts_control_value = readl(&port->port_task_scheduler_registers->control);
1496 pts_control_value |= SCU_PTSxCR_GEN_BIT(SUSPEND);
1497 writel(pts_control_value, &port->port_task_scheduler_registers->control);
1501 * scic_sds_port_post_dummy_request() - post dummy/workaround request
1502 * @sci_port: port to post task
1504 * Prevent the hardware scheduler from posting new requests to the front
1505 * of the scheduler queue causing a starvation problem for currently
1509 static void scic_sds_port_post_dummy_request(struct scic_sds_port *sci_port)
1512 struct scu_task_context *task_context;
1513 struct scic_sds_controller *scic = sci_port->owning_controller;
1514 u16 tci = sci_port->reserved_tci;
1516 task_context = scic_sds_controller_get_task_context_buffer(scic, tci);
1518 task_context->abort = 0;
1520 command = SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
1521 sci_port->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
1524 scic_sds_controller_post_request(scic, command);
1528 * This routine will abort the dummy request. This will alow the hardware to
1529 * power down parts of the silicon to save power.
1531 * @sci_port: The port on which the task must be aborted.
1534 static void scic_sds_port_abort_dummy_request(struct scic_sds_port *sci_port)
1536 struct scic_sds_controller *scic = sci_port->owning_controller;
1537 u16 tci = sci_port->reserved_tci;
1538 struct scu_task_context *tc;
1541 tc = scic_sds_controller_get_task_context_buffer(scic, tci);
1545 command = SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT |
1546 sci_port->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
1549 scic_sds_controller_post_request(scic, command);
1554 * @sci_port: This is the struct scic_sds_port object to resume.
1556 * This method will resume the port task scheduler for this port object. none
1559 scic_sds_port_resume_port_task_scheduler(struct scic_sds_port *port)
1561 u32 pts_control_value;
1563 pts_control_value = readl(&port->port_task_scheduler_registers->control);
1564 pts_control_value &= ~SCU_PTSxCR_GEN_BIT(SUSPEND);
1565 writel(pts_control_value, &port->port_task_scheduler_registers->control);
1569 * ******************************************************************************
1570 * * PORT READY SUBSTATE METHODS
1571 * ****************************************************************************** */
1575 * @object: This is the object which is cast to a struct scic_sds_port object.
1577 * This method will perform the actions required by the struct scic_sds_port on
1578 * entering the SCIC_SDS_PORT_READY_SUBSTATE_WAITING. This function checks the
1579 * port for any ready phys. If there is at least one phy in a ready state then
1580 * the port transitions to the ready operational substate. none
1582 static void scic_sds_port_ready_substate_waiting_enter(void *object)
1584 struct scic_sds_port *sci_port = object;
1586 scic_sds_port_set_ready_state_handlers(
1587 sci_port, SCIC_SDS_PORT_READY_SUBSTATE_WAITING
1590 scic_sds_port_suspend_port_task_scheduler(sci_port);
1592 sci_port->not_ready_reason = SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS;
1594 if (sci_port->active_phy_mask != 0) {
1595 /* At least one of the phys on the port is ready */
1596 sci_base_state_machine_change_state(
1597 &sci_port->ready_substate_machine,
1598 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1605 * @object: This is the object which is cast to a struct scic_sds_port object.
1607 * This function will perform the actions required by the struct scic_sds_port
1608 * on entering the SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL. This function sets
1609 * the state handlers for the port object, notifies the SCI User that the port
1610 * is ready, and resumes port operations. none
1612 static void scic_sds_port_ready_substate_operational_enter(void *object)
1615 struct scic_sds_port *sci_port = object;
1616 struct scic_sds_controller *scic = sci_port->owning_controller;
1617 struct isci_host *ihost = scic_to_ihost(scic);
1618 struct isci_port *iport = sci_port_to_iport(sci_port);
1620 scic_sds_port_set_ready_state_handlers(
1622 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL);
1624 isci_port_ready(ihost, iport);
1626 for (index = 0; index < SCI_MAX_PHYS; index++) {
1627 if (sci_port->phy_table[index]) {
1628 writel(sci_port->physical_port_index,
1629 &sci_port->port_pe_configuration_register[
1630 sci_port->phy_table[index]->phy_index]);
1634 scic_sds_port_update_viit_entry(sci_port);
1636 scic_sds_port_resume_port_task_scheduler(sci_port);
1639 * Post the dummy task for the port so the hardware can schedule
1642 scic_sds_port_post_dummy_request(sci_port);
1647 * @object: This is the object which is cast to a struct scic_sds_port object.
1649 * This method will perform the actions required by the struct scic_sds_port on
1650 * exiting the SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL. This function reports
1651 * the port not ready and suspends the port task scheduler. none
1653 static void scic_sds_port_ready_substate_operational_exit(void *object)
1655 struct scic_sds_port *sci_port = object;
1656 struct scic_sds_controller *scic = sci_port->owning_controller;
1657 struct isci_host *ihost = scic_to_ihost(scic);
1658 struct isci_port *iport = sci_port_to_iport(sci_port);
1661 * Kill the dummy task for this port if it has not yet posted
1662 * the hardware will treat this as a NOP and just return abort
1665 scic_sds_port_abort_dummy_request(sci_port);
1667 isci_port_not_ready(ihost, iport);
1671 * ******************************************************************************
1672 * * PORT READY CONFIGURING METHODS
1673 * ****************************************************************************** */
1676 * scic_sds_port_ready_substate_configuring_enter() -
1677 * @object: This is the object which is cast to a struct scic_sds_port object.
1679 * This method will perform the actions required by the struct scic_sds_port on
1680 * exiting the SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL. This function reports
1681 * the port not ready and suspends the port task scheduler. none
1683 static void scic_sds_port_ready_substate_configuring_enter(void *object)
1685 struct scic_sds_port *sci_port = object;
1686 struct scic_sds_controller *scic = sci_port->owning_controller;
1687 struct isci_host *ihost = scic_to_ihost(scic);
1688 struct isci_port *iport = sci_port_to_iport(sci_port);
1690 scic_sds_port_set_ready_state_handlers(
1692 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING);
1694 if (sci_port->active_phy_mask == 0) {
1695 isci_port_not_ready(ihost, iport);
1697 sci_base_state_machine_change_state(
1698 &sci_port->ready_substate_machine,
1699 SCIC_SDS_PORT_READY_SUBSTATE_WAITING);
1700 } else if (sci_port->started_request_count == 0)
1701 sci_base_state_machine_change_state(
1702 &sci_port->ready_substate_machine,
1703 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL);
1706 static void scic_sds_port_ready_substate_configuring_exit(void *object)
1708 struct scic_sds_port *sci_port = object;
1710 scic_sds_port_suspend_port_task_scheduler(sci_port);
1713 /* --------------------------------------------------------------------------- */
1715 static const struct sci_base_state scic_sds_port_ready_substate_table[] = {
1716 [SCIC_SDS_PORT_READY_SUBSTATE_WAITING] = {
1717 .enter_state = scic_sds_port_ready_substate_waiting_enter,
1719 [SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL] = {
1720 .enter_state = scic_sds_port_ready_substate_operational_enter,
1721 .exit_state = scic_sds_port_ready_substate_operational_exit
1723 [SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING] = {
1724 .enter_state = scic_sds_port_ready_substate_configuring_enter,
1725 .exit_state = scic_sds_port_ready_substate_configuring_exit
1731 * @port: This is the struct scic_sds_port object on which the io request count will
1733 * @device: This is the struct scic_sds_remote_device object to which the io request
1734 * is being directed. This parameter is not required to complete this
1736 * @io_request: This is the request that is being completed on this port
1737 * object. This parameter is not required to complete this operation.
1739 * This is a general complete io request handler for the struct scic_sds_port object.
1740 * enum sci_status SCI_SUCCESS
1742 static enum sci_status scic_sds_port_general_complete_io_handler(
1743 struct scic_sds_port *port,
1744 struct scic_sds_remote_device *device,
1745 struct scic_sds_request *io_request)
1747 scic_sds_port_decrement_request_count(port);
1753 * scic_sds_port_stopped_state_start_handler() - stop a port from "started"
1755 * @port: This is the struct scic_sds_port object which is cast into a
1756 * struct scic_sds_port object.
1758 * This function takes the struct scic_sds_port from a stopped state and
1759 * attempts to start it. To start a port it must have no assiged devices and
1760 * it must have at least one phy assigned to it. If those conditions are
1761 * met then the port can transition to the ready state.
1763 * SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION
1764 * This struct scic_sds_port object could not be started because the port
1765 * configuration is not valid.
1767 * the start request is successful and the struct scic_sds_port object
1768 * has transitioned to the SCI_BASE_PORT_STATE_READY.
1770 static enum sci_status
1771 scic_sds_port_stopped_state_start_handler(struct scic_sds_port *sci_port)
1773 struct scic_sds_controller *scic = sci_port->owning_controller;
1774 struct isci_host *ihost = scic_to_ihost(scic);
1775 enum sci_status status = SCI_SUCCESS;
1778 if (sci_port->assigned_device_count > 0) {
1780 * @todo This is a start failure operation because
1781 * there are still devices assigned to this port.
1782 * There must be no devices assigned to a port on a
1785 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
1788 sci_port->timer_handle =
1789 isci_timer_create(ihost,
1791 scic_sds_port_timeout_handler);
1793 if (!sci_port->timer_handle)
1794 return SCI_FAILURE_INSUFFICIENT_RESOURCES;
1796 if (sci_port->reserved_rni == SCU_DUMMY_INDEX) {
1797 u16 rni = scic_sds_remote_node_table_allocate_remote_node(
1798 &scic->available_remote_nodes, 1);
1800 if (rni != SCU_DUMMY_INDEX)
1801 scic_sds_port_construct_dummy_rnc(sci_port, rni);
1803 status = SCI_FAILURE_INSUFFICIENT_RESOURCES;
1804 sci_port->reserved_rni = rni;
1807 if (sci_port->reserved_tci == SCU_DUMMY_INDEX) {
1808 /* Allocate a TCI and remove the sequence nibble */
1809 u16 tci = scic_controller_allocate_io_tag(scic);
1811 if (tci != SCU_DUMMY_INDEX)
1812 scic_sds_port_construct_dummy_task(sci_port, tci);
1814 status = SCI_FAILURE_INSUFFICIENT_RESOURCES;
1815 sci_port->reserved_tci = tci;
1818 if (status == SCI_SUCCESS) {
1819 phy_mask = scic_sds_port_get_phys(sci_port);
1822 * There are one or more phys assigned to this port. Make sure
1823 * the port's phy mask is in fact legal and supported by the
1826 if (scic_sds_port_is_phy_mask_valid(sci_port, phy_mask) == true) {
1827 sci_base_state_machine_change_state(
1828 &sci_port->state_machine,
1829 SCI_BASE_PORT_STATE_READY);
1833 status = SCI_FAILURE;
1836 if (status != SCI_SUCCESS)
1837 scic_sds_port_destroy_dummy_resources(sci_port);
1843 * This method takes the struct scic_sds_port that is in a stopped state and handles a
1844 * stop request. This function takes no action. enum sci_status SCI_SUCCESS the
1845 * stop request is successful as the struct scic_sds_port object is already stopped.
1847 static enum sci_status scic_sds_port_stopped_state_stop_handler(
1848 struct scic_sds_port *port)
1850 /* We are already stopped so there is nothing to do here */
1855 * This method takes the struct scic_sds_port that is in a stopped state and handles
1856 * the destruct request. The stopped state is the only state in which the
1857 * struct scic_sds_port can be destroyed. This function causes the port object to
1858 * transition to the SCI_BASE_PORT_STATE_FINAL. enum sci_status SCI_SUCCESS
1860 static enum sci_status scic_sds_port_stopped_state_destruct_handler(
1861 struct scic_sds_port *port)
1863 sci_base_state_machine_stop(&port->state_machine);
1869 * This method takes the struct scic_sds_port that is in a stopped state and handles
1870 * the add phy request. In MPC mode the only time a phy can be added to a port
1871 * is in the SCI_BASE_PORT_STATE_STOPPED. enum sci_status
1872 * SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION is returned when the phy can not
1873 * be added to the port. SCI_SUCCESS if the phy is added to the port.
1875 static enum sci_status scic_sds_port_stopped_state_add_phy_handler(
1876 struct scic_sds_port *port,
1877 struct scic_sds_phy *phy)
1879 struct sci_sas_address port_sas_address;
1881 /* Read the port assigned SAS Address if there is one */
1882 scic_sds_port_get_sas_address(port, &port_sas_address);
1884 if (port_sas_address.high != 0 && port_sas_address.low != 0) {
1885 struct sci_sas_address phy_sas_address;
1888 * Make sure that the PHY SAS Address matches the SAS Address
1890 scic_sds_phy_get_sas_address(phy, &phy_sas_address);
1893 (port_sas_address.high != phy_sas_address.high)
1894 || (port_sas_address.low != phy_sas_address.low)
1896 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
1900 return scic_sds_port_set_phy(port, phy);
1904 * This method takes the struct scic_sds_port that is in a stopped state and handles
1905 * the remove phy request. In MPC mode the only time a phy can be removed from
1906 * a port is in the SCI_BASE_PORT_STATE_STOPPED. enum sci_status
1907 * SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION is returned when the phy can not
1908 * be added to the port. SCI_SUCCESS if the phy is added to the port.
1910 static enum sci_status scic_sds_port_stopped_state_remove_phy_handler(
1911 struct scic_sds_port *port,
1912 struct scic_sds_phy *phy)
1914 return scic_sds_port_clear_phy(port, phy);
1918 * ****************************************************************************
1919 * * READY STATE HANDLERS
1920 * **************************************************************************** */
1923 * ****************************************************************************
1924 * * RESETTING STATE HANDLERS
1925 * **************************************************************************** */
1928 * ****************************************************************************
1929 * * STOPPING STATE HANDLERS
1930 * **************************************************************************** */
1933 * This method takes the struct scic_sds_port that is in a stopping state and handles
1934 * the complete io request. Should the request count reach 0 then the port
1935 * object will transition to the stopped state. enum sci_status SCI_SUCCESS
1937 static enum sci_status scic_sds_port_stopping_state_complete_io_handler(
1938 struct scic_sds_port *sci_port,
1939 struct scic_sds_remote_device *device,
1940 struct scic_sds_request *io_request)
1942 scic_sds_port_decrement_request_count(sci_port);
1944 if (sci_port->started_request_count == 0) {
1945 sci_base_state_machine_change_state(&sci_port->state_machine,
1946 SCI_BASE_PORT_STATE_STOPPED);
1953 * ****************************************************************************
1954 * * RESETTING STATE HANDLERS
1955 * **************************************************************************** */
1959 * @port: This is the port object which is being requested to stop.
1961 * This method will stop a failed port. This causes a transition to the
1962 * stopping state. enum sci_status SCI_SUCCESS
1964 static enum sci_status scic_sds_port_reset_state_stop_handler(
1965 struct scic_sds_port *port)
1967 sci_base_state_machine_change_state(
1968 &port->state_machine,
1969 SCI_BASE_PORT_STATE_STOPPING
1976 * This method will transition a failed port to its ready state. The port
1977 * failed because a hard reset request timed out but at some time later one or
1978 * more phys in the port became ready. enum sci_status SCI_SUCCESS
1980 static void scic_sds_port_reset_state_link_up_handler(
1981 struct scic_sds_port *port,
1982 struct scic_sds_phy *phy)
1985 * / @todo We should make sure that the phy that has gone link up is the same
1986 * / one on which we sent the reset. It is possible that the phy on
1987 * / which we sent the reset is not the one that has gone link up and we
1988 * / want to make sure that phy being reset comes back. Consider the
1989 * / case where a reset is sent but before the hardware processes the
1990 * / reset it get a link up on the port because of a hot plug event.
1991 * / because of the reset request this phy will go link down almost
1995 * In the resetting state we don't notify the user regarding
1996 * link up and link down notifications. */
1997 scic_sds_port_general_link_up_handler(port, phy, false);
2001 * This method process link down notifications that occur during a port reset
2002 * operation. Link downs can occur during the reset operation. enum sci_status
2005 static void scic_sds_port_reset_state_link_down_handler(
2006 struct scic_sds_port *port,
2007 struct scic_sds_phy *phy)
2010 * In the resetting state we don't notify the user regarding
2011 * link up and link down notifications. */
2012 scic_sds_port_deactivate_phy(port, phy, false);
2015 static struct scic_sds_port_state_handler
2016 scic_sds_port_state_handler_table[SCI_BASE_PORT_MAX_STATES] =
2018 /* SCI_BASE_PORT_STATE_STOPPED */
2020 scic_sds_port_stopped_state_start_handler,
2021 scic_sds_port_stopped_state_stop_handler,
2022 scic_sds_port_stopped_state_destruct_handler,
2023 scic_sds_port_default_reset_handler,
2024 scic_sds_port_stopped_state_add_phy_handler,
2025 scic_sds_port_stopped_state_remove_phy_handler,
2026 scic_sds_port_default_frame_handler,
2027 scic_sds_port_default_event_handler,
2028 scic_sds_port_default_link_up_handler,
2029 scic_sds_port_default_link_down_handler,
2030 scic_sds_port_default_start_io_handler,
2031 scic_sds_port_default_complete_io_handler
2033 /* SCI_BASE_PORT_STATE_STOPPING */
2035 scic_sds_port_default_start_handler,
2036 scic_sds_port_default_stop_handler,
2037 scic_sds_port_default_destruct_handler,
2038 scic_sds_port_default_reset_handler,
2039 scic_sds_port_default_add_phy_handler,
2040 scic_sds_port_default_remove_phy_handler,
2041 scic_sds_port_default_frame_handler,
2042 scic_sds_port_default_event_handler,
2043 scic_sds_port_default_link_up_handler,
2044 scic_sds_port_default_link_down_handler,
2045 scic_sds_port_default_start_io_handler,
2046 scic_sds_port_stopping_state_complete_io_handler
2048 /* SCI_BASE_PORT_STATE_READY */
2050 scic_sds_port_default_start_handler,
2051 scic_sds_port_default_stop_handler,
2052 scic_sds_port_default_destruct_handler,
2053 scic_sds_port_default_reset_handler,
2054 scic_sds_port_default_add_phy_handler,
2055 scic_sds_port_default_remove_phy_handler,
2056 scic_sds_port_default_frame_handler,
2057 scic_sds_port_default_event_handler,
2058 scic_sds_port_default_link_up_handler,
2059 scic_sds_port_default_link_down_handler,
2060 scic_sds_port_default_start_io_handler,
2061 scic_sds_port_general_complete_io_handler
2063 /* SCI_BASE_PORT_STATE_RESETTING */
2065 scic_sds_port_default_start_handler,
2066 scic_sds_port_reset_state_stop_handler,
2067 scic_sds_port_default_destruct_handler,
2068 scic_sds_port_default_reset_handler,
2069 scic_sds_port_default_add_phy_handler,
2070 scic_sds_port_default_remove_phy_handler,
2071 scic_sds_port_default_frame_handler,
2072 scic_sds_port_default_event_handler,
2073 scic_sds_port_reset_state_link_up_handler,
2074 scic_sds_port_reset_state_link_down_handler,
2075 scic_sds_port_default_start_io_handler,
2076 scic_sds_port_general_complete_io_handler
2078 /* SCI_BASE_PORT_STATE_FAILED */
2080 scic_sds_port_default_start_handler,
2081 scic_sds_port_default_stop_handler,
2082 scic_sds_port_default_destruct_handler,
2083 scic_sds_port_default_reset_handler,
2084 scic_sds_port_default_add_phy_handler,
2085 scic_sds_port_default_remove_phy_handler,
2086 scic_sds_port_default_frame_handler,
2087 scic_sds_port_default_event_handler,
2088 scic_sds_port_default_link_up_handler,
2089 scic_sds_port_default_link_down_handler,
2090 scic_sds_port_default_start_io_handler,
2091 scic_sds_port_general_complete_io_handler
2096 * ******************************************************************************
2097 * * PORT STATE PRIVATE METHODS
2098 * ****************************************************************************** */
2102 * @sci_port: This is the port object which to suspend.
2104 * This method will enable the SCU Port Task Scheduler for this port object but
2105 * will leave the port task scheduler in a suspended state. none
2108 scic_sds_port_enable_port_task_scheduler(struct scic_sds_port *port)
2110 u32 pts_control_value;
2112 pts_control_value = readl(&port->port_task_scheduler_registers->control);
2113 pts_control_value |= SCU_PTSxCR_GEN_BIT(ENABLE) | SCU_PTSxCR_GEN_BIT(SUSPEND);
2114 writel(pts_control_value, &port->port_task_scheduler_registers->control);
2119 * @sci_port: This is the port object which to resume.
2121 * This method will disable the SCU port task scheduler for this port object.
2125 scic_sds_port_disable_port_task_scheduler(struct scic_sds_port *port)
2127 u32 pts_control_value;
2129 pts_control_value = readl(&port->port_task_scheduler_registers->control);
2130 pts_control_value &=
2131 ~(SCU_PTSxCR_GEN_BIT(ENABLE) | SCU_PTSxCR_GEN_BIT(SUSPEND));
2132 writel(pts_control_value, &port->port_task_scheduler_registers->control);
2135 static void scic_sds_port_post_dummy_remote_node(struct scic_sds_port *sci_port)
2137 struct scic_sds_controller *scic = sci_port->owning_controller;
2138 u8 phys_index = sci_port->physical_port_index;
2139 union scu_remote_node_context *rnc;
2140 u16 rni = sci_port->reserved_rni;
2143 rnc = &scic->remote_node_context_table[rni];
2144 rnc->ssp.is_valid = true;
2146 command = SCU_CONTEXT_COMMAND_POST_RNC_32 |
2147 phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
2149 scic_sds_controller_post_request(scic, command);
2151 /* ensure hardware has seen the post rnc command and give it
2152 * ample time to act before sending the suspend
2154 readl(&scic->smu_registers->interrupt_status); /* flush */
2157 command = SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX |
2158 phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
2160 scic_sds_controller_post_request(scic, command);
2163 static void scic_sds_port_invalidate_dummy_remote_node(struct scic_sds_port *sci_port)
2165 struct scic_sds_controller *scic = sci_port->owning_controller;
2166 u8 phys_index = sci_port->physical_port_index;
2167 union scu_remote_node_context *rnc;
2168 u16 rni = sci_port->reserved_rni;
2171 rnc = &scic->remote_node_context_table[rni];
2173 rnc->ssp.is_valid = false;
2175 /* ensure the preceding tc abort request has reached the
2176 * controller and give it ample time to act before posting the rnc
2179 readl(&scic->smu_registers->interrupt_status); /* flush */
2182 command = SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE |
2183 phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
2185 scic_sds_controller_post_request(scic, command);
2189 * ******************************************************************************
2190 * * PORT STATE METHODS
2191 * ****************************************************************************** */
2195 * @object: This is the object which is cast to a struct scic_sds_port object.
2197 * This method will perform the actions required by the struct scic_sds_port on
2198 * entering the SCI_BASE_PORT_STATE_STOPPED. This function sets the stopped
2199 * state handlers for the struct scic_sds_port object and disables the port task
2200 * scheduler in the hardware. none
2202 static void scic_sds_port_stopped_state_enter(void *object)
2204 struct scic_sds_port *sci_port = object;
2206 scic_sds_port_set_base_state_handlers(
2207 sci_port, SCI_BASE_PORT_STATE_STOPPED
2211 SCI_BASE_PORT_STATE_STOPPING
2212 == sci_port->state_machine.previous_state_id
2215 * If we enter this state becasuse of a request to stop
2216 * the port then we want to disable the hardwares port
2217 * task scheduler. */
2218 scic_sds_port_disable_port_task_scheduler(sci_port);
2224 * @object: This is the object which is cast to a struct scic_sds_port object.
2226 * This method will perform the actions required by the struct scic_sds_port on
2227 * exiting the SCI_BASE_STATE_STOPPED. This function enables the SCU hardware
2228 * port task scheduler. none
2230 static void scic_sds_port_stopped_state_exit(void *object)
2232 struct scic_sds_port *sci_port = object;
2234 /* Enable and suspend the port task scheduler */
2235 scic_sds_port_enable_port_task_scheduler(sci_port);
2239 * scic_sds_port_ready_state_enter -
2240 * @object: This is the object which is cast to a struct scic_sds_port object.
2242 * This method will perform the actions required by the struct scic_sds_port on
2243 * entering the SCI_BASE_PORT_STATE_READY. This function sets the ready state
2244 * handlers for the struct scic_sds_port object, reports the port object as
2245 * not ready and starts the ready substate machine. none
2247 static void scic_sds_port_ready_state_enter(void *object)
2249 struct scic_sds_port *sci_port = object;
2250 struct scic_sds_controller *scic = sci_port->owning_controller;
2251 struct isci_host *ihost = scic_to_ihost(scic);
2252 struct isci_port *iport = sci_port_to_iport(sci_port);
2255 /* Put the ready state handlers in place though they will not be there long */
2256 scic_sds_port_set_base_state_handlers(sci_port, SCI_BASE_PORT_STATE_READY);
2258 prev_state = sci_port->state_machine.previous_state_id;
2259 if (prev_state == SCI_BASE_PORT_STATE_RESETTING)
2260 isci_port_hard_reset_complete(iport, SCI_SUCCESS);
2262 isci_port_not_ready(ihost, iport);
2264 /* Post and suspend the dummy remote node context for this port. */
2265 scic_sds_port_post_dummy_remote_node(sci_port);
2267 /* Start the ready substate machine */
2268 sci_base_state_machine_start(&sci_port->ready_substate_machine);
2271 static void scic_sds_port_ready_state_exit(void *object)
2273 struct scic_sds_port *sci_port = object;
2275 sci_base_state_machine_stop(&sci_port->ready_substate_machine);
2276 scic_sds_port_invalidate_dummy_remote_node(sci_port);
2281 * @object: This is the object which is cast to a struct scic_sds_port object.
2283 * This method will perform the actions required by the struct scic_sds_port on
2284 * entering the SCI_BASE_PORT_STATE_RESETTING. This function sets the resetting
2285 * state handlers for the struct scic_sds_port object. none
2287 static void scic_sds_port_resetting_state_enter(void *object)
2289 struct scic_sds_port *sci_port = object;
2291 scic_sds_port_set_base_state_handlers(
2292 sci_port, SCI_BASE_PORT_STATE_RESETTING
2298 * @object: This is the object which is cast to a struct scic_sds_port object.
2300 * This function will perform the actions required by the
2301 * struct scic_sds_port on
2302 * exiting the SCI_BASE_STATE_RESETTING. This function does nothing. none
2304 static inline void scic_sds_port_resetting_state_exit(void *object)
2306 struct scic_sds_port *sci_port = object;
2308 isci_timer_stop(sci_port->timer_handle);
2313 * @object: This is the void object which is cast to a
2314 * struct scic_sds_port object.
2316 * This method will perform the actions required by the struct scic_sds_port on
2317 * entering the SCI_BASE_PORT_STATE_STOPPING. This function sets the stopping
2318 * state handlers for the struct scic_sds_port object. none
2320 static void scic_sds_port_stopping_state_enter(void *object)
2322 struct scic_sds_port *sci_port = object;
2324 scic_sds_port_set_base_state_handlers(
2325 sci_port, SCI_BASE_PORT_STATE_STOPPING
2331 * @object: This is the object which is cast to a struct scic_sds_port object.
2333 * This function will perform the actions required by the
2334 * struct scic_sds_port on
2335 * exiting the SCI_BASE_STATE_STOPPING. This function does nothing. none
2338 scic_sds_port_stopping_state_exit(void *object)
2340 struct scic_sds_port *sci_port = object;
2342 isci_timer_stop(sci_port->timer_handle);
2344 scic_sds_port_destroy_dummy_resources(sci_port);
2349 * @object: This is the object which is cast to a struct scic_sds_port object.
2351 * This function will perform the actions required by the
2352 * struct scic_sds_port on
2353 * entering the SCI_BASE_PORT_STATE_STOPPING. This function sets the stopping
2354 * state handlers for the struct scic_sds_port object. none
2356 static void scic_sds_port_failed_state_enter(void *object)
2358 struct scic_sds_port *sci_port = object;
2359 struct isci_port *iport = sci_port_to_iport(sci_port);
2361 scic_sds_port_set_base_state_handlers(sci_port,
2362 SCI_BASE_PORT_STATE_FAILED);
2364 isci_port_hard_reset_complete(iport, SCI_FAILURE_TIMEOUT);
2367 /* --------------------------------------------------------------------------- */
2369 static const struct sci_base_state scic_sds_port_state_table[] = {
2370 [SCI_BASE_PORT_STATE_STOPPED] = {
2371 .enter_state = scic_sds_port_stopped_state_enter,
2372 .exit_state = scic_sds_port_stopped_state_exit
2374 [SCI_BASE_PORT_STATE_STOPPING] = {
2375 .enter_state = scic_sds_port_stopping_state_enter,
2376 .exit_state = scic_sds_port_stopping_state_exit
2378 [SCI_BASE_PORT_STATE_READY] = {
2379 .enter_state = scic_sds_port_ready_state_enter,
2380 .exit_state = scic_sds_port_ready_state_exit
2382 [SCI_BASE_PORT_STATE_RESETTING] = {
2383 .enter_state = scic_sds_port_resetting_state_enter,
2384 .exit_state = scic_sds_port_resetting_state_exit
2386 [SCI_BASE_PORT_STATE_FAILED] = {
2387 .enter_state = scic_sds_port_failed_state_enter,
2391 void scic_sds_port_construct(struct scic_sds_port *sci_port, u8 index,
2392 struct scic_sds_controller *scic)
2394 sci_base_state_machine_construct(&sci_port->state_machine,
2396 scic_sds_port_state_table,
2397 SCI_BASE_PORT_STATE_STOPPED);
2399 sci_base_state_machine_start(&sci_port->state_machine);
2401 sci_base_state_machine_construct(&sci_port->ready_substate_machine,
2403 scic_sds_port_ready_substate_table,
2404 SCIC_SDS_PORT_READY_SUBSTATE_WAITING);
2406 sci_port->logical_port_index = SCIC_SDS_DUMMY_PORT;
2407 sci_port->physical_port_index = index;
2408 sci_port->active_phy_mask = 0;
2410 sci_port->owning_controller = scic;
2412 sci_port->started_request_count = 0;
2413 sci_port->assigned_device_count = 0;
2415 sci_port->reserved_rni = SCU_DUMMY_INDEX;
2416 sci_port->reserved_tci = SCU_DUMMY_INDEX;
2418 sci_port->timer_handle = NULL;
2419 sci_port->port_task_scheduler_registers = NULL;
2421 for (index = 0; index < SCI_MAX_PHYS; index++)
2422 sci_port->phy_table[index] = NULL;