isci: Intel(R) C600 Series Chipset Storage Control Unit Driver
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / scsi / isci / core / scic_sds_port.c
1 /*
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.
4  *
5  * GPL LICENSE SUMMARY
6  *
7  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8  *
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.
12  *
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.
17  *
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.
23  *
24  * BSD LICENSE
25  *
26  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27  * All rights reserved.
28  *
29  * Redistribution and use in source and binary forms, with or without
30  * modification, are permitted provided that the following conditions
31  * are met:
32  *
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
38  *     distribution.
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.
42  *
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.
54  */
55
56 #include "intel_sas.h"
57 #include "sci_base_port.h"
58 #include "scic_controller.h"
59 #include "scic_phy.h"
60 #include "scic_port.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_sds_port_registers.h"
66 #include "scic_sds_remote_device.h"
67 #include "scic_sds_remote_node_context.h"
68 #include "scic_sds_request.h"
69 #include "scic_user_callback.h"
70 #include "sci_environment.h"
71
72
73 static void scic_sds_port_invalid_link_up(
74         struct scic_sds_port *this_port,
75         struct scic_sds_phy *phy);
76 static void scic_sds_port_timeout_handler(
77         void *port);
78 #define SCIC_SDS_PORT_MIN_TIMER_COUNT  (SCI_MAX_PORTS)
79 #define SCIC_SDS_PORT_MAX_TIMER_COUNT  (SCI_MAX_PORTS)
80
81 #define SCIC_SDS_PORT_HARD_RESET_TIMEOUT  (1000)
82
83 void sci_base_port_construct(
84         struct sci_base_port *base_port,
85         const struct sci_base_state *state_table)
86 {
87         base_port->parent.private = NULL;
88         sci_base_state_machine_construct(
89                 &base_port->state_machine,
90                 &base_port->parent,
91                 state_table,
92                 SCI_BASE_PORT_STATE_STOPPED
93                 );
94
95         sci_base_state_machine_start(
96                 &base_port->state_machine
97                 );
98 }
99
100 /**
101  *
102  * @this_port: This is the port object to which the phy is being assigned.
103  * @phy_index: This is the phy index that is being assigned to the port.
104  *
105  * This method will return a true value if the specified phy can be assigned to
106  * this port The following is a list of phys for each port that are allowed: -
107  * Port 0 - 3 2 1 0 - Port 1 -     1 - Port 2 - 3 2 - Port 3 - 3 This method
108  * doesn't preclude all configurations.  It merely ensures that a phy is part
109  * of the allowable set of phy identifiers for that port.  For example, one
110  * could assign phy 3 to port 0 and no other phys.  Please refer to
111  * scic_sds_port_is_phy_mask_valid() for information regarding whether the
112  * phy_mask for a port can be supported. bool true if this is a valid phy
113  * assignment for the port false if this is not a valid phy assignment for the
114  * port
115  */
116 bool scic_sds_port_is_valid_phy_assignment(
117         struct scic_sds_port *this_port,
118         u32 phy_index)
119 {
120         /* Initialize to invalid value. */
121         u32 existing_phy_index = SCI_MAX_PHYS;
122         u32 index;
123
124         if ((this_port->physical_port_index == 1) && (phy_index != 1)) {
125                 return false;
126         }
127
128         if (this_port->physical_port_index == 3 && phy_index != 3) {
129                 return false;
130         }
131
132         if (
133                 (this_port->physical_port_index == 2)
134                 && ((phy_index == 0) || (phy_index == 1))
135                 ) {
136                 return false;
137         }
138
139         for (index = 0; index < SCI_MAX_PHYS; index++) {
140                 if ((this_port->phy_table[index] != NULL)
141                     && (index != phy_index)) {
142                         existing_phy_index = index;
143                 }
144         }
145
146         /*
147          * Ensure that all of the phys in the port are capable of
148          * operating at the same maximum link rate. */
149         if (
150                 (existing_phy_index < SCI_MAX_PHYS)
151                 && (this_port->owning_controller->user_parameters.sds1.phys[
152                             phy_index].max_speed_generation !=
153                     this_port->owning_controller->user_parameters.sds1.phys[
154                             existing_phy_index].max_speed_generation)
155                 )
156                 return false;
157
158         return true;
159 }
160
161 /**
162  * This method requests a list (mask) of the phys contained in the supplied SAS
163  *    port.
164  * @this_port: a handle corresponding to the SAS port for which to return the
165  *    phy mask.
166  *
167  * Return a bit mask indicating which phys are a part of this port. Each bit
168  * corresponds to a phy identifier (e.g. bit 0 = phy id 0).
169  */
170 u32 scic_sds_port_get_phys(struct scic_sds_port *this_port)
171 {
172         u32 index;
173         u32 mask;
174
175         mask = 0;
176
177         for (index = 0; index < SCI_MAX_PHYS; index++) {
178                 if (this_port->phy_table[index] != NULL) {
179                         mask |= (1 << index);
180                 }
181         }
182
183         return mask;
184 }
185
186 /**
187  *
188  * @this_port: This is the port object for which to determine if the phy mask
189  *    can be supported.
190  *
191  * This method will return a true value if the port's phy mask can be supported
192  * by the SCU. The following is a list of valid PHY mask configurations for
193  * each port: - Port 0 - [[3  2] 1] 0 - Port 1 -        [1] - Port 2 - [[3] 2]
194  * - Port 3 -  [3] This method returns a boolean indication specifying if the
195  * phy mask can be supported. true if this is a valid phy assignment for the
196  * port false if this is not a valid phy assignment for the port
197  */
198 bool scic_sds_port_is_phy_mask_valid(
199         struct scic_sds_port *this_port,
200         u32 phy_mask)
201 {
202         if (this_port->physical_port_index == 0) {
203                 if (((phy_mask & 0x0F) == 0x0F)
204                     || ((phy_mask & 0x03) == 0x03)
205                     || ((phy_mask & 0x01) == 0x01)
206                     || (phy_mask == 0))
207                         return true;
208         } else if (this_port->physical_port_index == 1) {
209                 if (((phy_mask & 0x02) == 0x02)
210                     || (phy_mask == 0))
211                         return true;
212         } else if (this_port->physical_port_index == 2) {
213                 if (((phy_mask & 0x0C) == 0x0C)
214                     || ((phy_mask & 0x04) == 0x04)
215                     || (phy_mask == 0))
216                         return true;
217         } else if (this_port->physical_port_index == 3) {
218                 if (((phy_mask & 0x08) == 0x08)
219                     || (phy_mask == 0))
220                         return true;
221         }
222
223         return false;
224 }
225
226 /**
227  *
228  * @this_port: This parameter specifies the port from which to return a
229  *    connected phy.
230  *
231  * This method retrieves a currently active (i.e. connected) phy contained in
232  * the port.  Currently, the lowest order phy that is connected is returned.
233  * This method returns a pointer to a SCIS_SDS_PHY object. NULL This value is
234  * returned if there are no currently active (i.e. connected to a remote end
235  * point) phys contained in the port. All other values specify a struct scic_sds_phy
236  * object that is active in the port.
237  */
238 static struct scic_sds_phy *scic_sds_port_get_a_connected_phy(
239         struct scic_sds_port *this_port
240         ) {
241         u32 index;
242         struct scic_sds_phy *phy;
243
244         for (index = 0; index < SCI_MAX_PHYS; index++) {
245                 /*
246                  * Ensure that the phy is both part of the port and currently
247                  * connected to the remote end-point. */
248                 phy = this_port->phy_table[index];
249                 if (
250                         (phy != NULL)
251                         && scic_sds_port_active_phy(this_port, phy)
252                         ) {
253                         return phy;
254                 }
255         }
256
257         return NULL;
258 }
259
260 /**
261  * scic_sds_port_set_phy() -
262  * @out]: port The port object to which the phy assignement is being made.
263  * @out]: phy The phy which is being assigned to the port.
264  *
265  * This method attempts to make the assignment of the phy to the port. If
266  * successful the phy is assigned to the ports phy table. bool true if the phy
267  * assignment can be made. false if the phy assignement can not be made. This
268  * is a functional test that only fails if the phy is currently assigned to a
269  * different port.
270  */
271 enum sci_status scic_sds_port_set_phy(
272         struct scic_sds_port *port,
273         struct scic_sds_phy *phy)
274 {
275         /*
276          * Check to see if we can add this phy to a port
277          * that means that the phy is not part of a port and that the port does
278          * not already have a phy assinged to the phy index. */
279         if (
280                 (port->phy_table[phy->phy_index] == SCI_INVALID_HANDLE)
281                 && (scic_sds_phy_get_port(phy) == SCI_INVALID_HANDLE)
282                 && scic_sds_port_is_valid_phy_assignment(port, phy->phy_index)
283                 ) {
284                 /*
285                  * Phy is being added in the stopped state so we are in MPC mode
286                  * make logical port index = physical port index */
287                 port->logical_port_index = port->physical_port_index;
288                 port->phy_table[phy->phy_index] = phy;
289                 scic_sds_phy_set_port(phy, port);
290
291                 return SCI_SUCCESS;
292         }
293
294         return SCI_FAILURE;
295 }
296
297 /**
298  * scic_sds_port_clear_phy() -
299  * @out]: port The port from which the phy is being cleared.
300  * @out]: phy The phy being cleared from the port.
301  *
302  * This method will clear the phy assigned to this port.  This method fails if
303  * this phy is not currently assinged to this port. bool true if the phy is
304  * removed from the port. false if this phy is not assined to this port.
305  */
306 enum sci_status scic_sds_port_clear_phy(
307         struct scic_sds_port *port,
308         struct scic_sds_phy *phy)
309 {
310         /* Make sure that this phy is part of this port */
311         if (
312                 (port->phy_table[phy->phy_index] == phy)
313                 && (scic_sds_phy_get_port(phy) == port)
314                 ) {
315                 /* Yep it is assigned to this port so remove it */
316                 scic_sds_phy_set_port(
317                         phy,
318                         &scic_sds_port_get_controller(port)->port_table[SCI_MAX_PORTS]
319                         );
320
321                 port->phy_table[phy->phy_index] = SCI_INVALID_HANDLE;
322
323                 return SCI_SUCCESS;
324         }
325
326         return SCI_FAILURE;
327 }
328
329 /**
330  * scic_sds_port_add_phy() -
331  * @this_port: This parameter specifies the port in which the phy will be added.
332  * @the_phy: This parameter is the phy which is to be added to the port.
333  *
334  * This method will add a PHY to the selected port. This method returns an
335  * enum sci_status. SCI_SUCCESS the phy has been added to the port. Any other status
336  * is failre to add the phy to the port.
337  */
338 enum sci_status scic_sds_port_add_phy(
339         struct scic_sds_port *this_port,
340         struct scic_sds_phy *the_phy)
341 {
342         return this_port->state_handlers->parent.add_phy_handler(
343                        &this_port->parent, &the_phy->parent);
344 }
345
346
347 /**
348  * scic_sds_port_remove_phy() -
349  * @this_port: This parameter specifies the port in which the phy will be added.
350  * @the_phy: This parameter is the phy which is to be added to the port.
351  *
352  * This method will remove the PHY from the selected PORT. This method returns
353  * an enum sci_status. SCI_SUCCESS the phy has been removed from the port. Any other
354  * status is failre to add the phy to the port.
355  */
356 enum sci_status scic_sds_port_remove_phy(
357         struct scic_sds_port *this_port,
358         struct scic_sds_phy *the_phy)
359 {
360         return this_port->state_handlers->parent.remove_phy_handler(
361                        &this_port->parent, &the_phy->parent);
362 }
363
364 /**
365  * This method requests the SAS address for the supplied SAS port from the SCI
366  *    implementation.
367  * @this_port: a handle corresponding to the SAS port for which to return the
368  *    SAS address.
369  * @sas_address: This parameter specifies a pointer to a SAS address structure
370  *    into which the core will copy the SAS address for the port.
371  *
372  */
373 void scic_sds_port_get_sas_address(
374         struct scic_sds_port *this_port,
375         struct sci_sas_address *sas_address)
376 {
377         u32 index;
378
379         sas_address->high = 0;
380         sas_address->low  = 0;
381
382         for (index = 0; index < SCI_MAX_PHYS; index++) {
383                 if (this_port->phy_table[index] != NULL) {
384                         scic_sds_phy_get_sas_address(this_port->phy_table[index], sas_address);
385                 }
386         }
387 }
388
389 /**
390  * This method will indicate which protocols are supported by this port.
391  * @this_port: a handle corresponding to the SAS port for which to return the
392  *    supported protocols.
393  * @protocols: This parameter specifies a pointer to an IAF protocol field
394  *    structure into which the core will copy the protocol values for the port.
395  *     The values are returned as part of a bit mask in order to allow for
396  *    multi-protocol support.
397  *
398  */
399 static void scic_sds_port_get_protocols(
400         struct scic_sds_port *this_port,
401         struct sci_sas_identify_address_frame_protocols *protocols)
402 {
403         u8 index;
404
405         protocols->u.all = 0;
406
407         for (index = 0; index < SCI_MAX_PHYS; index++) {
408                 if (this_port->phy_table[index] != NULL) {
409                         scic_sds_phy_get_protocols(this_port->phy_table[index], protocols);
410                 }
411         }
412 }
413
414 /**
415  * This method requests the SAS address for the device directly attached to
416  *    this SAS port.
417  * @this_port: a handle corresponding to the SAS port for which to return the
418  *    SAS address.
419  * @sas_address: This parameter specifies a pointer to a SAS address structure
420  *    into which the core will copy the SAS address for the device directly
421  *    attached to the port.
422  *
423  */
424 void scic_sds_port_get_attached_sas_address(
425         struct scic_sds_port *this_port,
426         struct sci_sas_address *sas_address)
427 {
428         struct sci_sas_identify_address_frame_protocols protocols;
429         struct scic_sds_phy *phy;
430
431         /*
432          * Ensure that the phy is both part of the port and currently
433          * connected to the remote end-point. */
434         phy = scic_sds_port_get_a_connected_phy(this_port);
435         if (phy != NULL) {
436                 scic_sds_phy_get_attached_phy_protocols(phy, &protocols);
437
438                 if (!protocols.u.bits.stp_target) {
439                         scic_sds_phy_get_attached_sas_address(phy, sas_address);
440                 } else {
441                         scic_sds_phy_get_sas_address(phy, sas_address);
442                         sas_address->low += phy->phy_index;
443                 }
444         } else {
445                 sas_address->high = 0;
446                 sas_address->low  = 0;
447         }
448 }
449
450 /**
451  * This method will indicate which protocols are supported by this remote
452  *    device.
453  * @this_port: a handle corresponding to the SAS port for which to return the
454  *    supported protocols.
455  * @protocols: This parameter specifies a pointer to an IAF protocol field
456  *    structure into which the core will copy the protocol values for the port.
457  *     The values are returned as part of a bit mask in order to allow for
458  *    multi-protocol support.
459  *
460  */
461 void scic_sds_port_get_attached_protocols(
462         struct scic_sds_port *this_port,
463         struct sci_sas_identify_address_frame_protocols *protocols)
464 {
465         struct scic_sds_phy *phy;
466
467         /*
468          * Ensure that the phy is both part of the port and currently
469          * connected to the remote end-point. */
470         phy = scic_sds_port_get_a_connected_phy(this_port);
471         if (phy != NULL)
472                 scic_sds_phy_get_attached_phy_protocols(phy, protocols);
473         else
474                 protocols->u.all = 0;
475 }
476
477 /**
478  * This method returns the amount of memory requred for a port object.
479  *
480  * u32
481  */
482
483 /**
484  * This method returns the minimum number of timers required for all port
485  *    objects.
486  *
487  * u32
488  */
489
490 /**
491  * This method returns the maximum number of timers required for all port
492  *    objects.
493  *
494  * u32
495  */
496
497 /**
498  *
499  * @this_port:
500  * @port_index:
501  *
502  *
503  */
504 void scic_sds_port_construct(
505         struct scic_sds_port *this_port,
506         u8 port_index,
507         struct scic_sds_controller *owning_controller)
508 {
509         u32 index;
510
511         sci_base_port_construct(
512                 &this_port->parent,
513                 scic_sds_port_state_table
514                 );
515
516         sci_base_state_machine_construct(
517                 scic_sds_port_get_ready_substate_machine(this_port),
518                 &this_port->parent.parent,
519                 scic_sds_port_ready_substate_table,
520                 SCIC_SDS_PORT_READY_SUBSTATE_WAITING
521                 );
522
523         this_port->logical_port_index  = SCIC_SDS_DUMMY_PORT;
524         this_port->physical_port_index = port_index;
525         this_port->active_phy_mask     = 0;
526
527         this_port->owning_controller = owning_controller;
528
529         this_port->started_request_count = 0;
530         this_port->assigned_device_count = 0;
531
532         this_port->timer_handle = SCI_INVALID_HANDLE;
533
534         this_port->transport_layer_registers = NULL;
535         this_port->port_task_scheduler_registers = NULL;
536
537         for (index = 0; index < SCI_MAX_PHYS; index++) {
538                 this_port->phy_table[index] = NULL;
539         }
540 }
541
542 /**
543  * This method performs initialization of the supplied port. Initialization
544  *    includes: - state machine initialization - member variable initialization
545  *    - configuring the phy_mask
546  * @this_port:
547  * @transport_layer_registers:
548  * @port_task_scheduler_registers:
549  * @port_configuration_regsiter:
550  *
551  * enum sci_status SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION This value is returned
552  * if the phy being added to the port
553  */
554 enum sci_status scic_sds_port_initialize(
555         struct scic_sds_port *this_port,
556         void *transport_layer_registers,
557         void *port_task_scheduler_registers,
558         void *port_configuration_regsiter,
559         void *viit_registers)
560 {
561         u32 tl_control;
562
563         this_port->transport_layer_registers      = transport_layer_registers;
564         this_port->port_task_scheduler_registers  = port_task_scheduler_registers;
565         this_port->port_pe_configuration_register = port_configuration_regsiter;
566         this_port->viit_registers                 = viit_registers;
567
568         scic_sds_port_set_direct_attached_device_id(
569                 this_port,
570                 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
571                 );
572
573         /*
574          * Hardware team recommends that we enable the STP prefetch
575          * for all ports */
576         tl_control = SCU_TLCR_READ(this_port);
577         tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
578         SCU_TLCR_WRITE(this_port, tl_control);
579
580         /*
581          * If this is not the dummy port make the assignment of
582          * the timer and start the state machine */
583         if (this_port->physical_port_index != SCI_MAX_PORTS) {
584                 /* / @todo should we create the timer at create time? */
585                 this_port->timer_handle = scic_cb_timer_create(
586                         scic_sds_port_get_controller(this_port),
587                         scic_sds_port_timeout_handler,
588                         this_port
589                         );
590
591         } else {
592                 /*
593                  * Force the dummy port into a condition where it rejects all requests
594                  * as its in an invalid state for any operation.
595                  * / @todo should we set a set of specical handlers for the dummy port? */
596                 scic_sds_port_set_base_state_handlers(
597                         this_port, SCI_BASE_PORT_STATE_STOPPED
598                         );
599         }
600
601         return SCI_SUCCESS;
602 }
603
604 /**
605  *
606  * @this_port: This is the struct scic_sds_port object for which has a phy that has
607  *    gone link up.
608  * @the_phy: This is the struct scic_sds_phy object that has gone link up.
609  * @do_notify_user: This parameter specifies whether to inform the user (via
610  *    scic_cb_port_link_up()) as to the fact that a new phy as become ready.
611  *
612  * This method is the a general link up handler for the struct scic_sds_port object.
613  * This function will determine if this struct scic_sds_phy can be assigned to this
614  * struct scic_sds_port object. If the struct scic_sds_phy object can is not a valid PHY for
615  * this port then the function will notify the SCIC_USER. A PHY can only be
616  * part of a port if it's attached SAS ADDRESS is the same as all other PHYs in
617  * the same port. none
618  */
619 void scic_sds_port_general_link_up_handler(
620         struct scic_sds_port *this_port,
621         struct scic_sds_phy *the_phy,
622         bool do_notify_user)
623 {
624         struct sci_sas_address port_sas_address;
625         struct sci_sas_address phy_sas_address;
626
627         scic_sds_port_get_attached_sas_address(this_port, &port_sas_address);
628         scic_sds_phy_get_attached_sas_address(the_phy, &phy_sas_address);
629
630         /*
631          * If the SAS address of the new phy matches the SAS address of
632          * other phys in the port OR this is the first phy in the port,
633          * then activate the phy and allow it to be used for operations
634          * in this port. */
635         if (
636                 (
637                         (phy_sas_address.high == port_sas_address.high)
638                         && (phy_sas_address.low  == port_sas_address.low)
639                 )
640                 || (this_port->active_phy_mask == 0)
641                 ) {
642                 scic_sds_port_activate_phy(this_port, the_phy, do_notify_user);
643
644                 if (this_port->parent.state_machine.current_state_id
645                     == SCI_BASE_PORT_STATE_RESETTING) {
646                         sci_base_state_machine_change_state(
647                                 &this_port->parent.state_machine, SCI_BASE_PORT_STATE_READY
648                                 );
649                 }
650         } else {
651                 scic_sds_port_invalid_link_up(this_port, the_phy);
652         }
653 }
654
655
656 enum sci_status scic_port_start(struct scic_sds_port *port)
657 {
658         return port->state_handlers->parent.start_handler(&port->parent);
659 }
660
661
662 enum sci_status scic_port_stop(struct scic_sds_port *port)
663 {
664         return port->state_handlers->parent.stop_handler(&port->parent);
665 }
666
667
668 enum sci_status scic_port_get_properties(
669         struct scic_sds_port *port,
670         struct scic_port_properties *prop)
671 {
672         if ((port == SCI_INVALID_HANDLE) ||
673             (port->logical_port_index == SCIC_SDS_DUMMY_PORT))
674                 return SCI_FAILURE_INVALID_PORT;
675
676         prop->index    = port->logical_port_index;
677         prop->phy_mask = scic_sds_port_get_phys(port);
678         scic_sds_port_get_sas_address(port, &prop->local.sas_address);
679         scic_sds_port_get_protocols(port, &prop->local.protocols);
680         scic_sds_port_get_attached_sas_address(port, &prop->remote.sas_address);
681         scic_sds_port_get_attached_protocols(port, &prop->remote.protocols);
682
683         return SCI_SUCCESS;
684 }
685
686
687 enum sci_status scic_port_hard_reset(
688         struct scic_sds_port *port,
689         u32 reset_timeout)
690 {
691         return port->state_handlers->parent.reset_handler(
692                        &port->parent, reset_timeout);
693 }
694
695 /**
696  *
697  * @this_port: The port for which the direct attached device id is to be
698  *    assigned.
699  *
700  * This method assigns the direct attached device ID for this port.
701  */
702 void scic_sds_port_set_direct_attached_device_id(
703         struct scic_sds_port *this_port,
704         u32 device_id)
705 {
706         u32 tl_control;
707
708         SCU_STPTLDARNI_WRITE(this_port, device_id);
709
710         /*
711          * The read should guarntee that the first write gets posted
712          * before the next write */
713         tl_control = SCU_TLCR_READ(this_port);
714         tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
715         SCU_TLCR_WRITE(this_port, tl_control);
716 }
717
718
719 /**
720  *
721  * @this_port: This is the port on which the phy should be enabled.
722  * @the_phy: This is the specific phy which to enable.
723  * @do_notify_user: This parameter specifies whether to inform the user (via
724  *    scic_cb_port_link_up()) as to the fact that a new phy as become ready.
725  *
726  * This method will activate the phy in the port. Activation includes: - adding
727  * the phy to the port - enabling the Protocol Engine in the silicon. -
728  * notifying the user that the link is up. none
729  */
730 void scic_sds_port_activate_phy(
731         struct scic_sds_port *this_port,
732         struct scic_sds_phy *the_phy,
733         bool do_notify_user)
734 {
735         struct scic_sds_controller *controller;
736         struct sci_sas_identify_address_frame_protocols protocols;
737
738         controller = scic_sds_port_get_controller(this_port);
739         scic_sds_phy_get_attached_phy_protocols(the_phy, &protocols);
740
741         /* If this is sata port then the phy has already been resumed */
742         if (!protocols.u.bits.stp_target) {
743                 scic_sds_phy_resume(the_phy);
744         }
745
746         this_port->active_phy_mask |= 1 << the_phy->phy_index;
747
748         scic_sds_controller_clear_invalid_phy(controller, the_phy);
749
750         if (do_notify_user == true)
751                 scic_cb_port_link_up(this_port->owning_controller, this_port, the_phy);
752 }
753
754 /**
755  *
756  * @this_port: This is the port on which the phy should be deactivated.
757  * @the_phy: This is the specific phy that is no longer active in the port.
758  * @do_notify_user: This parameter specifies whether to inform the user (via
759  *    scic_cb_port_link_down()) as to the fact that a new phy as become ready.
760  *
761  * This method will deactivate the supplied phy in the port. none
762  */
763 void scic_sds_port_deactivate_phy(
764         struct scic_sds_port *this_port,
765         struct scic_sds_phy *the_phy,
766         bool do_notify_user)
767 {
768         this_port->active_phy_mask &= ~(1 << the_phy->phy_index);
769
770         the_phy->max_negotiated_speed = SCI_SAS_NO_LINK_RATE;
771
772         /* Re-assign the phy back to the LP as if it were a narrow port */
773         SCU_PCSPExCR_WRITE(this_port, the_phy->phy_index, the_phy->phy_index);
774
775         if (do_notify_user == true)
776                 scic_cb_port_link_down(this_port->owning_controller, this_port, the_phy);
777 }
778
779 /**
780  *
781  * @this_port: This is the port on which the phy should be disabled.
782  * @the_phy: This is the specific phy which to disabled.
783  *
784  * This method will disable the phy and report that the phy is not valid for
785  * this port object. None
786  */
787 static void scic_sds_port_invalid_link_up(
788         struct scic_sds_port *this_port,
789         struct scic_sds_phy *the_phy)
790 {
791         struct scic_sds_controller *controller = scic_sds_port_get_controller(this_port);
792
793         /*
794          * Check to see if we have alreay reported this link as bad and if not go
795          * ahead and tell the SCI_USER that we have discovered an invalid link. */
796         if ((controller->invalid_phy_mask & (1 << the_phy->phy_index)) == 0) {
797                 scic_sds_controller_set_invalid_phy(controller, the_phy);
798
799                 scic_cb_port_invalid_link_up(controller, this_port, the_phy);
800         }
801 }
802
803 /**
804  * This method returns false if the port only has a single phy object assigned.
805  *     If there are no phys or more than one phy then the method will return
806  *    true.
807  * @this_port: The port for which the wide port condition is to be checked.
808  *
809  * bool true Is returned if this is a wide ported port. false Is returned if
810  * this is a narrow port.
811  */
812 static bool scic_sds_port_is_wide(struct scic_sds_port *this_port)
813 {
814         u32 index;
815         u32 phy_count = 0;
816
817         for (index = 0; index < SCI_MAX_PHYS; index++) {
818                 if (this_port->phy_table[index] != NULL) {
819                         phy_count++;
820                 }
821         }
822
823         return phy_count != 1;
824 }
825
826 /**
827  * This method is called by the PHY object when the link is detected. if the
828  *    port wants the PHY to continue on to the link up state then the port
829  *    layer must return true.  If the port object returns false the phy object
830  *    must halt its attempt to go link up.
831  * @this_port: The port associated with the phy object.
832  * @the_phy: The phy object that is trying to go link up.
833  *
834  * true if the phy object can continue to the link up condition. true Is
835  * returned if this phy can continue to the ready state. false Is returned if
836  * can not continue on to the ready state. This notification is in place for
837  * wide ports and direct attached phys.  Since there are no wide ported SATA
838  * devices this could become an invalid port configuration.
839  */
840 bool scic_sds_port_link_detected(
841         struct scic_sds_port *this_port,
842         struct scic_sds_phy *the_phy)
843 {
844         struct sci_sas_identify_address_frame_protocols protocols;
845
846         scic_sds_phy_get_attached_phy_protocols(the_phy, &protocols);
847
848         if (
849                 (this_port->logical_port_index != SCIC_SDS_DUMMY_PORT)
850                 && (protocols.u.bits.stp_target)
851                 && scic_sds_port_is_wide(this_port)
852                 ) {
853                 scic_sds_port_invalid_link_up(this_port, the_phy);
854
855                 return false;
856         }
857
858         return true;
859 }
860
861 /**
862  * This method is the entry point for the phy to inform the port that it is now
863  *    in a ready state
864  * @this_port:
865  *
866  *
867  */
868 void scic_sds_port_link_up(
869         struct scic_sds_port *this_port,
870         struct scic_sds_phy *the_phy)
871 {
872         the_phy->is_in_link_training = false;
873
874         this_port->state_handlers->link_up_handler(this_port, the_phy);
875 }
876
877 /**
878  * This method is the entry point for the phy to inform the port that it is no
879  *    longer in a ready state
880  * @this_port:
881  *
882  *
883  */
884 void scic_sds_port_link_down(
885         struct scic_sds_port *this_port,
886         struct scic_sds_phy *the_phy)
887 {
888         this_port->state_handlers->link_down_handler(this_port, the_phy);
889 }
890
891 /**
892  * This method is called to start an IO request on this port.
893  * @this_port:
894  * @the_device:
895  * @the_io_request:
896  *
897  * enum sci_status
898  */
899 enum sci_status scic_sds_port_start_io(
900         struct scic_sds_port *this_port,
901         struct scic_sds_remote_device *the_device,
902         struct scic_sds_request *the_io_request)
903 {
904         return this_port->state_handlers->start_io_handler(
905                        this_port, the_device, the_io_request);
906 }
907
908 /**
909  * This method is called to complete an IO request to the port.
910  * @this_port:
911  * @the_device:
912  * @the_io_request:
913  *
914  * enum sci_status
915  */
916 enum sci_status scic_sds_port_complete_io(
917         struct scic_sds_port *this_port,
918         struct scic_sds_remote_device *the_device,
919         struct scic_sds_request *the_io_request)
920 {
921         return this_port->state_handlers->complete_io_handler(
922                        this_port, the_device, the_io_request);
923 }
924
925 /**
926  * This method is provided to timeout requests for port operations. Mostly its
927  *    for the port reset operation.
928  *
929  *
930  */
931 static void scic_sds_port_timeout_handler(void *port)
932 {
933         struct scic_sds_port *this_port = port;
934         u32 current_state;
935
936         current_state = sci_base_state_machine_get_state(
937                 &this_port->parent.state_machine);
938
939         if (current_state == SCI_BASE_PORT_STATE_RESETTING) {
940                 /*
941                  * if the port is still in the resetting state then the timeout fired
942                  * before the reset completed. */
943                 sci_base_state_machine_change_state(
944                         &this_port->parent.state_machine,
945                         SCI_BASE_PORT_STATE_FAILED
946                         );
947         } else if (current_state == SCI_BASE_PORT_STATE_STOPPED) {
948                 /*
949                  * if the port is stopped then the start request failed
950                  * In this case stay in the stopped state. */
951                 dev_err(sciport_to_dev(this_port),
952                         "%s: SCIC Port 0x%p failed to stop before tiemout.\n",
953                         __func__,
954                         this_port);
955         } else if (current_state == SCI_BASE_PORT_STATE_STOPPING) {
956                 /* if the port is still stopping then the stop has not completed */
957                 scic_cb_port_stop_complete(
958                         scic_sds_port_get_controller(this_port),
959                         port,
960                         SCI_FAILURE_TIMEOUT
961                         );
962         } else {
963                 /*
964                  * The port is in the ready state and we have a timer reporting a timeout
965                  * this should not happen. */
966                 dev_err(sciport_to_dev(this_port),
967                         "%s: SCIC Port 0x%p is processing a timeout operation "
968                         "in state %d.\n",
969                         __func__,
970                         this_port,
971                         current_state);
972         }
973 }
974
975 /* --------------------------------------------------------------------------- */
976
977 #ifdef SCIC_DEBUG_ENABLED
978 void scic_sds_port_decrement_request_count(struct scic_sds_port *this_port)
979 {
980         if (this_port->started_request_count == 0)
981                 dev_warn(sciport_to_dev(this_port),
982                          __func__,
983                          "%s: SCIC Port object requested to decrement started "
984                          "io count past zero.\n");
985         else
986                 this_port->started_request_count--;
987 }
988 #endif
989
990 /**
991  * This function updates the hardwares VIIT entry for this port.
992  *
993  *
994  */
995 void scic_sds_port_update_viit_entry(struct scic_sds_port *this_port)
996 {
997         struct sci_sas_address sas_address;
998
999         scic_sds_port_get_sas_address(this_port, &sas_address);
1000
1001         scu_port_viit_register_write(
1002                 this_port, initiator_sas_address_hi, sas_address.high);
1003
1004         scu_port_viit_register_write(
1005                 this_port, initiator_sas_address_lo, sas_address.low);
1006
1007         /* This value get cleared just in case its not already cleared */
1008         scu_port_viit_register_write(
1009                 this_port, reserved, 0);
1010
1011         /* We are required to update the status register last */
1012         scu_port_viit_register_write(
1013                 this_port, status, (
1014                         SCU_VIIT_ENTRY_ID_VIIT
1015                         | SCU_VIIT_IPPT_INITIATOR
1016                         | ((1 << this_port->physical_port_index) << SCU_VIIT_ENTRY_LPVIE_SHIFT)
1017                         | SCU_VIIT_STATUS_ALL_VALID
1018                         )
1019                 );
1020 }
1021
1022 /**
1023  * This method returns the maximum allowed speed for data transfers on this
1024  *    port.  This maximum allowed speed evaluates to the maximum speed of the
1025  *    slowest phy in the port.
1026  * @this_port: This parameter specifies the port for which to retrieve the
1027  *    maximum allowed speed.
1028  *
1029  * This method returns the maximum negotiated speed of the slowest phy in the
1030  * port.
1031  */
1032 enum sci_sas_link_rate scic_sds_port_get_max_allowed_speed(
1033         struct scic_sds_port *this_port)
1034 {
1035         u16 index             = 0;
1036         enum sci_sas_link_rate max_allowed_speed = SCI_SAS_600_GB;
1037         struct scic_sds_phy *phy               = NULL;
1038
1039         /*
1040          * Loop through all of the phys in this port and find the phy with the
1041          * lowest maximum link rate. */
1042         for (index = 0; index < SCI_MAX_PHYS; index++) {
1043                 phy = this_port->phy_table[index];
1044                 if (
1045                         (phy != NULL)
1046                         && (scic_sds_port_active_phy(this_port, phy) == true)
1047                         && (phy->max_negotiated_speed < max_allowed_speed)
1048                         )
1049                         max_allowed_speed = phy->max_negotiated_speed;
1050         }
1051
1052         return max_allowed_speed;
1053 }
1054
1055
1056 /**
1057  * This method passes the event to core user.
1058  * @this_port: The port that a BCN happens.
1059  * @this_phy: The phy that receives BCN.
1060  *
1061  */
1062 void scic_sds_port_broadcast_change_received(
1063         struct scic_sds_port *this_port,
1064         struct scic_sds_phy *this_phy)
1065 {
1066         /* notify the user. */
1067         scic_cb_port_bc_change_primitive_received(
1068                 this_port->owning_controller, this_port, this_phy
1069                 );
1070 }
1071
1072
1073 /**
1074  * This API methhod enables the broadcast change notification from underneath
1075  *    hardware.
1076  * @this_port: The port that a BCN had been disabled from.
1077  *
1078  */
1079 void scic_port_enable_broadcast_change_notification(
1080         struct scic_sds_port *port)
1081 {
1082         struct scic_sds_phy *phy;
1083         u32 register_value;
1084         u8 index;
1085
1086         /* Loop through all of the phys to enable BCN. */
1087         for (index = 0; index < SCI_MAX_PHYS; index++) {
1088                 phy = port->phy_table[index];
1089                 if (phy != NULL) {
1090                         register_value = SCU_SAS_LLCTL_READ(phy);
1091
1092                         /* clear the bit by writing 1. */
1093                         SCU_SAS_LLCTL_WRITE(phy, register_value);
1094                 }
1095         }
1096 }
1097
1098 /*
1099  * ****************************************************************************
1100  * *  READY SUBSTATE HANDLERS
1101  * **************************************************************************** */
1102
1103 /**
1104  *
1105  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1106  *    object.
1107  *
1108  * This method is the general ready state stop handler for the struct scic_sds_port
1109  * object.  This function will transition the ready substate machine to its
1110  * final state. enum sci_status SCI_SUCCESS
1111  */
1112 static enum sci_status scic_sds_port_ready_substate_stop_handler(
1113         struct sci_base_port *port)
1114 {
1115         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1116
1117         sci_base_state_machine_change_state(
1118                 &this_port->parent.state_machine,
1119                 SCI_BASE_PORT_STATE_STOPPING
1120                 );
1121
1122         return SCI_SUCCESS;
1123 }
1124
1125 /**
1126  *
1127  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1128  *    object.
1129  * @device: This is the struct sci_base_remote_device object which is not used in this
1130  *    function.
1131  * @io_request: This is the struct sci_base_request object which is not used in this
1132  *    function.
1133  *
1134  * This method is the general ready substate complete io handler for the
1135  * struct scic_sds_port object.  This function decrments the outstanding request count
1136  * for this port object. enum sci_status SCI_SUCCESS
1137  */
1138 static enum sci_status scic_sds_port_ready_substate_complete_io_handler(
1139         struct scic_sds_port *port,
1140         struct scic_sds_remote_device *device,
1141         struct scic_sds_request *io_request)
1142 {
1143         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1144
1145         scic_sds_port_decrement_request_count(this_port);
1146
1147         return SCI_SUCCESS;
1148 }
1149
1150 static enum sci_status scic_sds_port_ready_substate_add_phy_handler(
1151         struct sci_base_port *port,
1152         struct sci_base_phy *phy)
1153 {
1154         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1155         struct scic_sds_phy *this_phy  = (struct scic_sds_phy *)phy;
1156         enum sci_status status;
1157
1158         status = scic_sds_port_set_phy(this_port, this_phy);
1159
1160         if (status == SCI_SUCCESS) {
1161                 scic_sds_port_general_link_up_handler(this_port, this_phy, true);
1162
1163                 this_port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
1164
1165                 sci_base_state_machine_change_state(
1166                         &this_port->ready_substate_machine,
1167                         SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1168                         );
1169         }
1170
1171         return status;
1172 }
1173
1174
1175 static enum sci_status scic_sds_port_ready_substate_remove_phy_handler(
1176         struct sci_base_port *port,
1177         struct sci_base_phy *phy)
1178 {
1179         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1180         struct scic_sds_phy *this_phy  = (struct scic_sds_phy *)phy;
1181         enum sci_status status;
1182
1183         status = scic_sds_port_clear_phy(this_port, this_phy);
1184
1185         if (status == SCI_SUCCESS) {
1186                 scic_sds_port_deactivate_phy(this_port, this_phy, true);
1187
1188                 this_port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
1189
1190                 sci_base_state_machine_change_state(
1191                         &this_port->ready_substate_machine,
1192                         SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1193                         );
1194         }
1195
1196         return status;
1197 }
1198
1199 /*
1200  * ****************************************************************************
1201  * *  READY SUBSTATE WAITING HANDLERS
1202  * **************************************************************************** */
1203
1204 /**
1205  *
1206  * @this_port: This is the struct scic_sds_port object that which has a phy that has
1207  *    gone link up.
1208  * @the_phy: This is the struct scic_sds_phy object that has gone link up.
1209  *
1210  * This method is the ready waiting substate link up handler for the
1211  * struct scic_sds_port object.  This methos will report the link up condition for
1212  * this port and will transition to the ready operational substate. none
1213  */
1214 static void scic_sds_port_ready_waiting_substate_link_up_handler(
1215         struct scic_sds_port *this_port,
1216         struct scic_sds_phy *the_phy)
1217 {
1218         /*
1219          * Since this is the first phy going link up for the port we can just enable
1220          * it and continue. */
1221         scic_sds_port_activate_phy(this_port, the_phy, true);
1222
1223         sci_base_state_machine_change_state(
1224                 &this_port->ready_substate_machine,
1225                 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1226                 );
1227 }
1228
1229 /**
1230  *
1231  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1232  *    object.
1233  * @device: This is the struct sci_base_remote_device object which is not used in this
1234  *    request.
1235  * @io_request: This is the struct sci_base_request object which is not used in this
1236  *    function.
1237  *
1238  * This method is the ready waiting substate start io handler for the
1239  * struct scic_sds_port object. The port object can not accept new requests so the
1240  * request is failed. enum sci_status SCI_FAILURE_INVALID_STATE
1241  */
1242 static enum sci_status scic_sds_port_ready_waiting_substate_start_io_handler(
1243         struct scic_sds_port *port,
1244         struct scic_sds_remote_device *device,
1245         struct scic_sds_request *io_request)
1246 {
1247         return SCI_FAILURE_INVALID_STATE;
1248 }
1249
1250 /*
1251  * ****************************************************************************
1252  * *  READY SUBSTATE OPERATIONAL HANDLERS
1253  * **************************************************************************** */
1254
1255 /**
1256  *
1257  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1258  *    object.
1259  * @timeout: This is the timeout for the reset request to complete.
1260  *
1261  * This method will casue the port to reset. enum sci_status SCI_SUCCESS
1262  */
1263 static enum sci_status scic_sds_port_ready_operational_substate_reset_handler(
1264         struct sci_base_port *port,
1265         u32 timeout)
1266 {
1267         enum sci_status status = SCI_FAILURE_INVALID_PHY;
1268         u32 phy_index;
1269         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1270         struct scic_sds_phy *selected_phy = SCI_INVALID_HANDLE;
1271
1272
1273         /* Select a phy on which we can send the hard reset request. */
1274         for (
1275                 phy_index = 0;
1276                 (phy_index < SCI_MAX_PHYS)
1277                 && (selected_phy == SCI_INVALID_HANDLE);
1278                 phy_index++
1279                 ) {
1280                 selected_phy = this_port->phy_table[phy_index];
1281
1282                 if (
1283                         (selected_phy != SCI_INVALID_HANDLE)
1284                         && !scic_sds_port_active_phy(this_port, selected_phy)
1285                         ) {
1286                         /* We found a phy but it is not ready select different phy */
1287                         selected_phy = SCI_INVALID_HANDLE;
1288                 }
1289         }
1290
1291         /* If we have a phy then go ahead and start the reset procedure */
1292         if (selected_phy != SCI_INVALID_HANDLE) {
1293                 status = scic_sds_phy_reset(selected_phy);
1294
1295                 if (status == SCI_SUCCESS) {
1296                         scic_cb_timer_start(
1297                                 scic_sds_port_get_controller(this_port),
1298                                 this_port->timer_handle,
1299                                 timeout
1300                                 );
1301
1302                         this_port->not_ready_reason = SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED;
1303
1304                         sci_base_state_machine_change_state(
1305                                 &this_port->parent.state_machine,
1306                                 SCI_BASE_PORT_STATE_RESETTING
1307                                 );
1308                 }
1309         }
1310
1311         return status;
1312 }
1313
1314 /**
1315  * scic_sds_port_ready_operational_substate_link_up_handler() -
1316  * @this_port: This is the struct scic_sds_port object that which has a phy that has
1317  *    gone link up.
1318  * @the_phy: This is the struct scic_sds_phy object that has gone link up.
1319  *
1320  * This method is the ready operational substate link up handler for the
1321  * struct scic_sds_port object. This function notifies the SCI User that the phy has
1322  * gone link up. none
1323  */
1324 static void scic_sds_port_ready_operational_substate_link_up_handler(
1325         struct scic_sds_port *this_port,
1326         struct scic_sds_phy *the_phy)
1327 {
1328         scic_sds_port_general_link_up_handler(this_port, the_phy, true);
1329 }
1330
1331 /**
1332  * scic_sds_port_ready_operational_substate_link_down_handler() -
1333  * @this_port: This is the struct scic_sds_port object that which has a phy that has
1334  *    gone link down.
1335  * @the_phy: This is the struct scic_sds_phy object that has gone link down.
1336  *
1337  * This method is the ready operational substate link down handler for the
1338  * struct scic_sds_port object. This function notifies the SCI User that the phy has
1339  * gone link down and if this is the last phy in the port the port will change
1340  * state to the ready waiting substate. none
1341  */
1342 static void scic_sds_port_ready_operational_substate_link_down_handler(
1343         struct scic_sds_port *this_port,
1344         struct scic_sds_phy *the_phy)
1345 {
1346         scic_sds_port_deactivate_phy(this_port, the_phy, true);
1347
1348         /*
1349          * If there are no active phys left in the port, then transition
1350          * the port to the WAITING state until such time as a phy goes
1351          * link up. */
1352         if (this_port->active_phy_mask == 0) {
1353                 sci_base_state_machine_change_state(
1354                         scic_sds_port_get_ready_substate_machine(this_port),
1355                         SCIC_SDS_PORT_READY_SUBSTATE_WAITING
1356                         );
1357         }
1358 }
1359
1360 /**
1361  *
1362  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1363  *    object.
1364  * @device: This is the struct sci_base_remote_device object which is not used in this
1365  *    function.
1366  * @io_request: This is the struct sci_base_request object which is not used in this
1367  *    function.
1368  *
1369  * This method is the ready operational substate start io handler for the
1370  * struct scic_sds_port object.  This function incremetns the outstanding request
1371  * count for this port object. enum sci_status SCI_SUCCESS
1372  */
1373 static enum sci_status scic_sds_port_ready_operational_substate_start_io_handler(
1374         struct scic_sds_port *port,
1375         struct scic_sds_remote_device *device,
1376         struct scic_sds_request *io_request)
1377 {
1378         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1379
1380         scic_sds_port_increment_request_count(this_port);
1381
1382         return SCI_SUCCESS;
1383 }
1384
1385 /*
1386  * ****************************************************************************
1387  * *  READY SUBSTATE OPERATIONAL HANDLERS
1388  * **************************************************************************** */
1389
1390 /**
1391  * scic_sds_port_ready_configuring_substate_add_phy_handler() -
1392  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1393  *    object.
1394  *
1395  * This is the default method for a port add phy request.  It will report a
1396  * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1397  */
1398 static enum sci_status scic_sds_port_ready_configuring_substate_add_phy_handler(
1399         struct sci_base_port *port,
1400         struct sci_base_phy *phy)
1401 {
1402         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1403         struct scic_sds_phy *this_phy  = (struct scic_sds_phy *)phy;
1404         enum sci_status status;
1405
1406         status = scic_sds_port_set_phy(this_port, this_phy);
1407
1408         if (status == SCI_SUCCESS) {
1409                 scic_sds_port_general_link_up_handler(this_port, this_phy, true);
1410
1411                 /*
1412                  * Re-enter the configuring state since this may be the last phy in
1413                  * the port. */
1414                 sci_base_state_machine_change_state(
1415                         &this_port->ready_substate_machine,
1416                         SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1417                         );
1418         }
1419
1420         return status;
1421 }
1422
1423 /**
1424  * scic_sds_port_ready_configuring_substate_remove_phy_handler() -
1425  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1426  *    object.
1427  *
1428  * This is the default method for a port remove phy request.  It will report a
1429  * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1430  */
1431 static enum sci_status scic_sds_port_ready_configuring_substate_remove_phy_handler(
1432         struct sci_base_port *port,
1433         struct sci_base_phy *phy)
1434 {
1435         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1436         struct scic_sds_phy *this_phy  = (struct scic_sds_phy *)phy;
1437         enum sci_status status;
1438
1439         status = scic_sds_port_clear_phy(this_port, this_phy);
1440
1441         if (status == SCI_SUCCESS) {
1442                 scic_sds_port_deactivate_phy(this_port, this_phy, true);
1443
1444                 /*
1445                  * Re-enter the configuring state since this may be the last phy in
1446                  * the port. */
1447                 sci_base_state_machine_change_state(
1448                         &this_port->ready_substate_machine,
1449                         SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1450                         );
1451         }
1452
1453         return status;
1454 }
1455
1456 /**
1457  * scic_sds_port_ready_configuring_substate_complete_io_handler() -
1458  * @port: This is the port that is being requested to complete the io request.
1459  * @device: This is the device on which the io is completing.
1460  *
1461  * This method will decrement the outstanding request count for this port. If
1462  * the request count goes to 0 then the port can be reprogrammed with its new
1463  * phy data.
1464  */
1465 static enum sci_status scic_sds_port_ready_configuring_substate_complete_io_handler(
1466         struct scic_sds_port *port,
1467         struct scic_sds_remote_device *device,
1468         struct scic_sds_request *io_request)
1469 {
1470         scic_sds_port_decrement_request_count(port);
1471
1472         if (port->started_request_count == 0) {
1473                 sci_base_state_machine_change_state(
1474                         &port->ready_substate_machine,
1475                         SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1476                         );
1477         }
1478
1479         return SCI_SUCCESS;
1480 }
1481
1482 /* --------------------------------------------------------------------------- */
1483
1484 struct scic_sds_port_state_handler
1485 scic_sds_port_ready_substate_handler_table[SCIC_SDS_PORT_READY_MAX_SUBSTATES] =
1486 {
1487         /* SCIC_SDS_PORT_READY_SUBSTATE_WAITING */
1488         {
1489                 {
1490                         scic_sds_port_default_start_handler,
1491                         scic_sds_port_ready_substate_stop_handler,
1492                         scic_sds_port_default_destruct_handler,
1493                         scic_sds_port_default_reset_handler,
1494                         scic_sds_port_ready_substate_add_phy_handler,
1495                         scic_sds_port_default_remove_phy_handler
1496                 },
1497                 scic_sds_port_default_frame_handler,
1498                 scic_sds_port_default_event_handler,
1499                 scic_sds_port_ready_waiting_substate_link_up_handler,
1500                 scic_sds_port_default_link_down_handler,
1501                 scic_sds_port_ready_waiting_substate_start_io_handler,
1502                 scic_sds_port_ready_substate_complete_io_handler,
1503         },
1504         /* SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL */
1505         {
1506                 {
1507                         scic_sds_port_default_start_handler,
1508                         scic_sds_port_ready_substate_stop_handler,
1509                         scic_sds_port_default_destruct_handler,
1510                         scic_sds_port_ready_operational_substate_reset_handler,
1511                         scic_sds_port_ready_substate_add_phy_handler,
1512                         scic_sds_port_ready_substate_remove_phy_handler
1513                 },
1514                 scic_sds_port_default_frame_handler,
1515                 scic_sds_port_default_event_handler,
1516                 scic_sds_port_ready_operational_substate_link_up_handler,
1517                 scic_sds_port_ready_operational_substate_link_down_handler,
1518                 scic_sds_port_ready_operational_substate_start_io_handler,
1519                 scic_sds_port_ready_substate_complete_io_handler
1520         },
1521         /* SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING */
1522         {
1523                 {
1524                         scic_sds_port_default_start_handler,
1525                         scic_sds_port_ready_substate_stop_handler,
1526                         scic_sds_port_default_destruct_handler,
1527                         scic_sds_port_default_reset_handler,
1528                         scic_sds_port_ready_configuring_substate_add_phy_handler,
1529                         scic_sds_port_ready_configuring_substate_remove_phy_handler
1530                 },
1531                 scic_sds_port_default_frame_handler,
1532                 scic_sds_port_default_event_handler,
1533                 scic_sds_port_default_link_up_handler,
1534                 scic_sds_port_default_link_down_handler,
1535                 scic_sds_port_default_start_io_handler,
1536                 scic_sds_port_ready_configuring_substate_complete_io_handler
1537         }
1538 };
1539
1540
1541 /**
1542  * scic_sds_port_set_ready_state_handlers() -
1543  *
1544  * This macro sets the port ready substate handlers.
1545  */
1546 #define scic_sds_port_set_ready_state_handlers(port, state_id) \
1547         scic_sds_port_set_state_handlers(\
1548                 port, &scic_sds_port_ready_substate_handler_table[(state_id)] \
1549                 )
1550
1551 /*
1552  * ******************************************************************************
1553  * *  PORT STATE PRIVATE METHODS
1554  * ****************************************************************************** */
1555
1556 /**
1557  *
1558  * @this_port: This is the struct scic_sds_port object to suspend.
1559  *
1560  * This method will susped the port task scheduler for this port object. none
1561  */
1562 static void scic_sds_port_suspend_port_task_scheduler(
1563         struct scic_sds_port *this_port)
1564 {
1565         u32 pts_control_value;
1566         u32 tl_control_value;
1567
1568         pts_control_value = scu_port_task_scheduler_read(this_port, control);
1569         tl_control_value = scu_transport_layer_read(this_port, control);
1570
1571         pts_control_value |= SCU_PTSxCR_GEN_BIT(SUSPEND);
1572         tl_control_value  |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
1573
1574         scu_port_task_scheduler_write(this_port, control, pts_control_value);
1575         scu_transport_layer_write(this_port, control, tl_control_value);
1576 }
1577
1578 /**
1579  *
1580  * @this_port: This is the struct scic_sds_port object to resume.
1581  *
1582  * This method will resume the port task scheduler for this port object. none
1583  */
1584 static void scic_sds_port_resume_port_task_scheduler(
1585         struct scic_sds_port *this_port)
1586 {
1587         u32 pts_control_value;
1588
1589         pts_control_value = scu_port_task_scheduler_read(this_port, control);
1590
1591         pts_control_value &= ~SCU_PTSxCR_GEN_BIT(SUSPEND);
1592
1593         scu_port_task_scheduler_write(this_port, control, pts_control_value);
1594 }
1595
1596 /*
1597  * ******************************************************************************
1598  * *  PORT READY SUBSTATE METHODS
1599  * ****************************************************************************** */
1600
1601 /**
1602  *
1603  * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
1604  *
1605  * This method will perform the actions required by the struct scic_sds_port on
1606  * entering the SCIC_SDS_PORT_READY_SUBSTATE_WAITING. This function checks the
1607  * port for any ready phys.  If there is at least one phy in a ready state then
1608  * the port transitions to the ready operational substate. none
1609  */
1610 static void scic_sds_port_ready_substate_waiting_enter(
1611         struct sci_base_object *object)
1612 {
1613         struct scic_sds_port *this_port = (struct scic_sds_port *)object;
1614
1615         scic_sds_port_set_ready_state_handlers(
1616                 this_port, SCIC_SDS_PORT_READY_SUBSTATE_WAITING
1617                 );
1618
1619         scic_sds_port_suspend_port_task_scheduler(this_port);
1620
1621         this_port->not_ready_reason = SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS;
1622
1623         if (this_port->active_phy_mask != 0) {
1624                 /* At least one of the phys on the port is ready */
1625                 sci_base_state_machine_change_state(
1626                         &this_port->ready_substate_machine,
1627                         SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1628                         );
1629         }
1630 }
1631
1632 /**
1633  *
1634  * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
1635  *
1636  * This method will perform the actions required by the struct scic_sds_port on
1637  * entering the SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL. This function sets
1638  * the state handlers for the port object, notifies the SCI User that the port
1639  * is ready, and resumes port operations. none
1640  */
1641 static void scic_sds_port_ready_substate_operational_enter(
1642         struct sci_base_object *object)
1643 {
1644         u32 index;
1645         struct scic_sds_port *this_port = (struct scic_sds_port *)object;
1646
1647         scic_sds_port_set_ready_state_handlers(
1648                 this_port, SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1649                 );
1650
1651         scic_cb_port_ready(
1652                 scic_sds_port_get_controller(this_port), this_port
1653                 );
1654
1655         for (index = 0; index < SCI_MAX_PHYS; index++) {
1656                 if (this_port->phy_table[index] != NULL) {
1657                         scic_sds_port_write_phy_assignment(
1658                                 this_port, this_port->phy_table[index]
1659                                 );
1660                 }
1661         }
1662
1663         scic_sds_port_update_viit_entry(this_port);
1664
1665         scic_sds_port_resume_port_task_scheduler(this_port);
1666 }
1667
1668 /**
1669  *
1670  * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
1671  *
1672  * This method will perform the actions required by the struct scic_sds_port on
1673  * exiting the SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL. This function reports
1674  * the port not ready and suspends the port task scheduler. none
1675  */
1676 static void scic_sds_port_ready_substate_operational_exit(
1677         struct sci_base_object *object)
1678 {
1679         struct scic_sds_port *this_port = (struct scic_sds_port *)object;
1680
1681         scic_cb_port_not_ready(
1682                 scic_sds_port_get_controller(this_port),
1683                 this_port,
1684                 this_port->not_ready_reason
1685                 );
1686 }
1687
1688 /*
1689  * ******************************************************************************
1690  * *  PORT READY CONFIGURING METHODS
1691  * ****************************************************************************** */
1692
1693 /**
1694  * scic_sds_port_ready_substate_configuring_enter() -
1695  * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
1696  *
1697  * This method will perform the actions required by the struct scic_sds_port on
1698  * exiting the SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL. This function reports
1699  * the port not ready and suspends the port task scheduler. none
1700  */
1701 static void scic_sds_port_ready_substate_configuring_enter(
1702         struct sci_base_object *object)
1703 {
1704         struct scic_sds_port *this_port = (struct scic_sds_port *)object;
1705
1706         scic_sds_port_set_ready_state_handlers(
1707                 this_port, SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1708                 );
1709
1710         if (this_port->active_phy_mask == 0) {
1711                 scic_cb_port_not_ready(
1712                         scic_sds_port_get_controller(this_port),
1713                         this_port,
1714                         SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS
1715                         );
1716
1717                 sci_base_state_machine_change_state(
1718                         &this_port->ready_substate_machine,
1719                         SCIC_SDS_PORT_READY_SUBSTATE_WAITING
1720                         );
1721         } else if (this_port->started_request_count == 0) {
1722                 sci_base_state_machine_change_state(
1723                         &this_port->ready_substate_machine,
1724                         SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1725                         );
1726         }
1727 }
1728
1729 static void scic_sds_port_ready_substate_configuring_exit(
1730         struct sci_base_object *object)
1731 {
1732         struct scic_sds_port *this_port = (struct scic_sds_port *)object;
1733
1734         scic_sds_port_suspend_port_task_scheduler(this_port);
1735 }
1736
1737 /* --------------------------------------------------------------------------- */
1738
1739 const struct sci_base_state scic_sds_port_ready_substate_table[] = {
1740         [SCIC_SDS_PORT_READY_SUBSTATE_WAITING] = {
1741                 .enter_state = scic_sds_port_ready_substate_waiting_enter,
1742         },
1743         [SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL] = {
1744                 .enter_state = scic_sds_port_ready_substate_operational_enter,
1745                 .exit_state  = scic_sds_port_ready_substate_operational_exit
1746         },
1747         [SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING] = {
1748                 .enter_state = scic_sds_port_ready_substate_configuring_enter,
1749                 .exit_state  = scic_sds_port_ready_substate_configuring_exit
1750         },
1751 };
1752
1753 /*
1754  * ***************************************************************************
1755  * *  DEFAULT HANDLERS
1756  * *************************************************************************** */
1757
1758 /**
1759  *
1760  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1761  *    object.
1762  *
1763  * This is the default method for port a start request.  It will report a
1764  * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1765  */
1766 enum sci_status scic_sds_port_default_start_handler(
1767         struct sci_base_port *port)
1768 {
1769         struct scic_sds_port *sci_port = (struct scic_sds_port *)port;
1770
1771         dev_warn(sciport_to_dev(sci_port),
1772                  "%s: SCIC Port 0x%p requested to start while in invalid "
1773                  "state %d\n",
1774                  __func__,
1775                  port,
1776                  sci_base_state_machine_get_state(
1777                          scic_sds_port_get_base_state_machine(
1778                                  (struct scic_sds_port *)port)));
1779
1780         return SCI_FAILURE_INVALID_STATE;
1781 }
1782
1783 /**
1784  *
1785  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1786  *    object.
1787  *
1788  * This is the default method for a port stop request.  It will report a
1789  * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1790  */
1791 static enum sci_status scic_sds_port_default_stop_handler(
1792         struct sci_base_port *port)
1793 {
1794         struct scic_sds_port *sci_port = (struct scic_sds_port *)port;
1795
1796         dev_warn(sciport_to_dev(sci_port),
1797                  "%s: SCIC Port 0x%p requested to stop while in invalid "
1798                  "state %d\n",
1799                  __func__,
1800                  port,
1801                  sci_base_state_machine_get_state(
1802                          scic_sds_port_get_base_state_machine(
1803                                  (struct scic_sds_port *)port)));
1804
1805         return SCI_FAILURE_INVALID_STATE;
1806 }
1807
1808 /**
1809  *
1810  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1811  *    object.
1812  *
1813  * This is the default method for a port destruct request.  It will report a
1814  * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1815  */
1816 enum sci_status scic_sds_port_default_destruct_handler(
1817         struct sci_base_port *port)
1818 {
1819         struct scic_sds_port *sci_port = (struct scic_sds_port *)port;
1820
1821         dev_warn(sciport_to_dev(sci_port),
1822                  "%s: SCIC Port 0x%p requested to destruct while in invalid "
1823                  "state %d\n",
1824                  __func__,
1825                  port,
1826                  sci_base_state_machine_get_state(
1827                          scic_sds_port_get_base_state_machine(
1828                                  (struct scic_sds_port *)port)));
1829
1830         return SCI_FAILURE_INVALID_STATE;
1831 }
1832
1833 /**
1834  *
1835  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1836  *    object.
1837  * @timeout: This is the timeout for the reset request to complete.
1838  *
1839  * This is the default method for a port reset request.  It will report a
1840  * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1841  */
1842 enum sci_status scic_sds_port_default_reset_handler(
1843         struct sci_base_port *port,
1844         u32 timeout)
1845 {
1846         struct scic_sds_port *sci_port = (struct scic_sds_port *)port;
1847
1848         dev_warn(sciport_to_dev(sci_port),
1849                  "%s: SCIC Port 0x%p requested to reset while in invalid "
1850                  "state %d\n",
1851                  __func__,
1852                  port,
1853                  sci_base_state_machine_get_state(
1854                          scic_sds_port_get_base_state_machine(
1855                                  (struct scic_sds_port *)port)));
1856
1857         return SCI_FAILURE_INVALID_STATE;
1858 }
1859
1860 /**
1861  *
1862  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1863  *    object.
1864  *
1865  * This is the default method for a port add phy request.  It will report a
1866  * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1867  */
1868 static enum sci_status scic_sds_port_default_add_phy_handler(
1869         struct sci_base_port *port,
1870         struct sci_base_phy *phy)
1871 {
1872         struct scic_sds_port *sci_port = (struct scic_sds_port *)port;
1873
1874         dev_warn(sciport_to_dev(sci_port),
1875                  "%s: SCIC Port 0x%p requested to add phy 0x%p while in "
1876                  "invalid state %d\n",
1877                  __func__,
1878                  port,
1879                  phy,
1880                  sci_base_state_machine_get_state(
1881                          scic_sds_port_get_base_state_machine(
1882                                  (struct scic_sds_port *)port)));
1883
1884         return SCI_FAILURE_INVALID_STATE;
1885 }
1886
1887 /**
1888  *
1889  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1890  *    object.
1891  *
1892  * This is the default method for a port remove phy request.  It will report a
1893  * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1894  */
1895 enum sci_status scic_sds_port_default_remove_phy_handler(
1896         struct sci_base_port *port,
1897         struct sci_base_phy *phy)
1898 {
1899         struct scic_sds_port *sci_port = (struct scic_sds_port *)port;
1900
1901         dev_warn(sciport_to_dev(sci_port),
1902                  "%s: SCIC Port 0x%p requested to remove phy 0x%p while in "
1903                  "invalid state %d\n",
1904                  __func__,
1905                  port,
1906                  phy,
1907                  sci_base_state_machine_get_state(
1908                          scic_sds_port_get_base_state_machine(
1909                                  (struct scic_sds_port *)port)));
1910
1911         return SCI_FAILURE_INVALID_STATE;
1912 }
1913
1914 /**
1915  *
1916  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1917  *    object.
1918  *
1919  * This is the default method for a port unsolicited frame request.  It will
1920  * report a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE Is it even
1921  * possible to receive an unsolicited frame directed to a port object?  It
1922  * seems possible if we implementing virtual functions but until then?
1923  */
1924 enum sci_status scic_sds_port_default_frame_handler(
1925         struct scic_sds_port *port,
1926         u32 frame_index)
1927 {
1928         dev_warn(sciport_to_dev(port),
1929                  "%s: SCIC Port 0x%p requested to process frame %d while in "
1930                  "invalid state %d\n",
1931                  __func__,
1932                  port,
1933                  frame_index,
1934                  sci_base_state_machine_get_state(
1935                          scic_sds_port_get_base_state_machine(port)));
1936
1937         scic_sds_controller_release_frame(
1938                 scic_sds_port_get_controller(port), frame_index
1939                 );
1940
1941         return SCI_FAILURE_INVALID_STATE;
1942 }
1943
1944 /**
1945  *
1946  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1947  *    object.
1948  *
1949  * This is the default method for a port event request.  It will report a
1950  * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1951  */
1952 enum sci_status scic_sds_port_default_event_handler(
1953         struct scic_sds_port *port,
1954         u32 event_code)
1955 {
1956         dev_warn(sciport_to_dev(port),
1957                  "%s: SCIC Port 0x%p requested to process event 0x%x while "
1958                  "in invalid state %d\n",
1959                  __func__,
1960                  port,
1961                  event_code,
1962                  sci_base_state_machine_get_state(
1963                          scic_sds_port_get_base_state_machine(
1964                                  (struct scic_sds_port *)port)));
1965
1966         return SCI_FAILURE_INVALID_STATE;
1967 }
1968
1969 /**
1970  *
1971  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1972  *    object.
1973  *
1974  * This is the default method for a port link up notification.  It will report
1975  * a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1976  */
1977 void scic_sds_port_default_link_up_handler(
1978         struct scic_sds_port *this_port,
1979         struct scic_sds_phy *phy)
1980 {
1981         dev_warn(sciport_to_dev(this_port),
1982                  "%s: SCIC Port 0x%p received link_up notification from phy "
1983                  "0x%p while in invalid state %d\n",
1984                  __func__,
1985                  this_port,
1986                  phy,
1987                  sci_base_state_machine_get_state(
1988                          scic_sds_port_get_base_state_machine(this_port)));
1989 }
1990
1991 /**
1992  *
1993  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1994  *    object.
1995  *
1996  * This is the default method for a port link down notification.  It will
1997  * report a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1998  */
1999 void scic_sds_port_default_link_down_handler(
2000         struct scic_sds_port *this_port,
2001         struct scic_sds_phy *phy)
2002 {
2003         dev_warn(sciport_to_dev(this_port),
2004                  "%s: SCIC Port 0x%p received link down notification from "
2005                  "phy 0x%p while in invalid state %d\n",
2006                  __func__,
2007                  this_port,
2008                  phy,
2009                  sci_base_state_machine_get_state(
2010                          scic_sds_port_get_base_state_machine(this_port)));
2011 }
2012
2013 /**
2014  *
2015  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2016  *    object.
2017  *
2018  * This is the default method for a port start io request.  It will report a
2019  * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2020  */
2021 enum sci_status scic_sds_port_default_start_io_handler(
2022         struct scic_sds_port *this_port,
2023         struct scic_sds_remote_device *device,
2024         struct scic_sds_request *io_request)
2025 {
2026         dev_warn(sciport_to_dev(this_port),
2027                  "%s: SCIC Port 0x%p requested to start io request 0x%p "
2028                  "while in invalid state %d\n",
2029                  __func__,
2030                  this_port,
2031                  io_request,
2032                  sci_base_state_machine_get_state(
2033                          scic_sds_port_get_base_state_machine(this_port)));
2034
2035         return SCI_FAILURE_INVALID_STATE;
2036 }
2037
2038 /**
2039  *
2040  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2041  *    object.
2042  *
2043  * This is the default method for a port complete io request.  It will report a
2044  * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2045  */
2046 static enum sci_status scic_sds_port_default_complete_io_handler(
2047         struct scic_sds_port *this_port,
2048         struct scic_sds_remote_device *device,
2049         struct scic_sds_request *io_request)
2050 {
2051         dev_warn(sciport_to_dev(this_port),
2052                  "%s: SCIC Port 0x%p requested to complete io request 0x%p "
2053                  "while in invalid state %d\n",
2054                  __func__,
2055                  this_port,
2056                  io_request,
2057                  sci_base_state_machine_get_state(
2058                          scic_sds_port_get_base_state_machine(this_port)));
2059
2060         return SCI_FAILURE_INVALID_STATE;
2061 }
2062
2063 /*
2064  * ****************************************************************************
2065  * * GENERAL STATE HANDLERS
2066  * **************************************************************************** */
2067
2068 /**
2069  *
2070  * @port: This is the struct scic_sds_port object on which the io request count will
2071  *    be decremented.
2072  * @device: This is the struct scic_sds_remote_device object to which the io request
2073  *    is being directed.  This parameter is not required to complete this
2074  *    operation.
2075  * @io_request: This is the request that is being completed on this port
2076  *    object.  This parameter is not required to complete this operation.
2077  *
2078  * This is a general complete io request handler for the struct scic_sds_port object.
2079  * enum sci_status SCI_SUCCESS
2080  */
2081 static enum sci_status scic_sds_port_general_complete_io_handler(
2082         struct scic_sds_port *port,
2083         struct scic_sds_remote_device *device,
2084         struct scic_sds_request *io_request)
2085 {
2086         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2087
2088         scic_sds_port_decrement_request_count(this_port);
2089
2090         return SCI_SUCCESS;
2091 }
2092
2093 /*
2094  * ****************************************************************************
2095  * * STOPPED STATE HANDLERS
2096  * **************************************************************************** */
2097
2098 /**
2099  *
2100  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2101  *    object.
2102  *
2103  * This method takes the struct scic_sds_port from a stopped state and attempts to
2104  * start it.  To start a port it must have no assiged devices and it must have
2105  * at least one phy assigned to it.  If those conditions are met then the port
2106  * can transition to the ready state. enum sci_status
2107  * SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION This struct scic_sds_port object could
2108  * not be started because the port configuration is not valid. SCI_SUCCESS the
2109  * start request is successful and the struct scic_sds_port object has transitioned to
2110  * the SCI_BASE_PORT_STATE_READY.
2111  */
2112 static enum sci_status scic_sds_port_stopped_state_start_handler(
2113         struct sci_base_port *port)
2114 {
2115         u32 phy_mask;
2116         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2117
2118         if (this_port->assigned_device_count > 0) {
2119                 /*
2120                  * / @todo This is a start failure operation because there are still
2121                  * /       devices assigned to this port.  There must be no devices
2122                  * /       assigned to a port on a start operation. */
2123                 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
2124         }
2125
2126         phy_mask = scic_sds_port_get_phys(this_port);
2127
2128         /*
2129          * There are one or more phys assigned to this port.  Make sure
2130          * the port's phy mask is in fact legal and supported by the
2131          * silicon. */
2132         if (scic_sds_port_is_phy_mask_valid(this_port, phy_mask) == true) {
2133                 sci_base_state_machine_change_state(
2134                         scic_sds_port_get_base_state_machine(this_port),
2135                         SCI_BASE_PORT_STATE_READY
2136                         );
2137
2138                 return SCI_SUCCESS;
2139         }
2140
2141         return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
2142 }
2143
2144 /**
2145  *
2146  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2147  *    object.
2148  *
2149  * This method takes the struct scic_sds_port that is in a stopped state and handles a
2150  * stop request.  This function takes no action. enum sci_status SCI_SUCCESS the
2151  * stop request is successful as the struct scic_sds_port object is already stopped.
2152  */
2153 static enum sci_status scic_sds_port_stopped_state_stop_handler(
2154         struct sci_base_port *port)
2155 {
2156         /* We are already stopped so there is nothing to do here */
2157         return SCI_SUCCESS;
2158 }
2159
2160 /**
2161  *
2162  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2163  *    object.
2164  *
2165  * This method takes the struct scic_sds_port that is in a stopped state and handles
2166  * the destruct request.  The stopped state is the only state in which the
2167  * struct scic_sds_port can be destroyed.  This function causes the port object to
2168  * transition to the SCI_BASE_PORT_STATE_FINAL. enum sci_status SCI_SUCCESS
2169  */
2170 static enum sci_status scic_sds_port_stopped_state_destruct_handler(
2171         struct sci_base_port *port)
2172 {
2173         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2174
2175         sci_base_state_machine_stop(&this_port->parent.state_machine);
2176
2177         return SCI_SUCCESS;
2178 }
2179
2180 /**
2181  *
2182  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2183  *    object.
2184  * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2185  *    object.
2186  *
2187  * This method takes the struct scic_sds_port that is in a stopped state and handles
2188  * the add phy request.  In MPC mode the only time a phy can be added to a port
2189  * is in the SCI_BASE_PORT_STATE_STOPPED. enum sci_status
2190  * SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION is returned when the phy can not
2191  * be added to the port. SCI_SUCCESS if the phy is added to the port.
2192  */
2193 static enum sci_status scic_sds_port_stopped_state_add_phy_handler(
2194         struct sci_base_port *port,
2195         struct sci_base_phy *phy)
2196 {
2197         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2198         struct scic_sds_phy *this_phy  = (struct scic_sds_phy *)phy;
2199         struct sci_sas_address port_sas_address;
2200
2201         /* Read the port assigned SAS Address if there is one */
2202         scic_sds_port_get_sas_address(this_port, &port_sas_address);
2203
2204         if (port_sas_address.high != 0 && port_sas_address.low != 0) {
2205                 struct sci_sas_address phy_sas_address;
2206
2207                 /*
2208                  * Make sure that the PHY SAS Address matches the SAS Address
2209                  * for this port. */
2210                 scic_sds_phy_get_sas_address(this_phy, &phy_sas_address);
2211
2212                 if (
2213                         (port_sas_address.high != phy_sas_address.high)
2214                         || (port_sas_address.low  != phy_sas_address.low)
2215                         ) {
2216                         return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
2217                 }
2218         }
2219
2220         return scic_sds_port_set_phy(this_port, this_phy);
2221 }
2222
2223
2224 /**
2225  *
2226  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2227  *    object.
2228  * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2229  *    object.
2230  *
2231  * This method takes the struct scic_sds_port that is in a stopped state and handles
2232  * the remove phy request.  In MPC mode the only time a phy can be removed from
2233  * a port is in the SCI_BASE_PORT_STATE_STOPPED. enum sci_status
2234  * SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION is returned when the phy can not
2235  * be added to the port. SCI_SUCCESS if the phy is added to the port.
2236  */
2237 static enum sci_status scic_sds_port_stopped_state_remove_phy_handler(
2238         struct sci_base_port *port,
2239         struct sci_base_phy *phy)
2240 {
2241         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2242         struct scic_sds_phy *this_phy  = (struct scic_sds_phy *)phy;
2243
2244         return scic_sds_port_clear_phy(this_port, this_phy);
2245 }
2246
2247 /*
2248  * ****************************************************************************
2249  * *  READY STATE HANDLERS
2250  * **************************************************************************** */
2251
2252 /*
2253  * ****************************************************************************
2254  * *  RESETTING STATE HANDLERS
2255  * **************************************************************************** */
2256
2257 /*
2258  * ****************************************************************************
2259  * *  STOPPING STATE HANDLERS
2260  * **************************************************************************** */
2261
2262 /**
2263  *
2264  * @port: This is the struct scic_sds_port object on which the io request count will
2265  *    be decremented.
2266  * @device: This is the struct scic_sds_remote_device object to which the io request
2267  *    is being directed.  This parameter is not required to complete this
2268  *    operation.
2269  * @io_request: This is the request that is being completed on this port
2270  *    object.  This parameter is not required to complete this operation.
2271  *
2272  * This method takes the struct scic_sds_port that is in a stopping state and handles
2273  * the complete io request. Should the request count reach 0 then the port
2274  * object will transition to the stopped state. enum sci_status SCI_SUCCESS
2275  */
2276 static enum sci_status scic_sds_port_stopping_state_complete_io_handler(
2277         struct scic_sds_port *port,
2278         struct scic_sds_remote_device *device,
2279         struct scic_sds_request *io_request)
2280 {
2281         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2282
2283         scic_sds_port_decrement_request_count(this_port);
2284
2285         if (this_port->started_request_count == 0) {
2286                 sci_base_state_machine_change_state(
2287                         scic_sds_port_get_base_state_machine(this_port),
2288                         SCI_BASE_PORT_STATE_STOPPED
2289                         );
2290         }
2291
2292         return SCI_SUCCESS;
2293 }
2294
2295 /*
2296  * ****************************************************************************
2297  * *  RESETTING STATE HANDLERS
2298  * **************************************************************************** */
2299
2300 /**
2301  *
2302  * @port: This is the port object which is being requested to stop.
2303  *
2304  * This method will stop a failed port.  This causes a transition to the
2305  * stopping state. enum sci_status SCI_SUCCESS
2306  */
2307 static enum sci_status scic_sds_port_reset_state_stop_handler(
2308         struct sci_base_port *port)
2309 {
2310         struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2311
2312         sci_base_state_machine_change_state(
2313                 &this_port->parent.state_machine,
2314                 SCI_BASE_PORT_STATE_STOPPING
2315                 );
2316
2317         return SCI_SUCCESS;
2318 }
2319
2320 /**
2321  *
2322  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2323  *    object.
2324  *
2325  * This method will transition a failed port to its ready state.  The port
2326  * failed because a hard reset request timed out but at some time later one or
2327  * more phys in the port became ready. enum sci_status SCI_SUCCESS
2328  */
2329 static void scic_sds_port_reset_state_link_up_handler(
2330         struct scic_sds_port *this_port,
2331         struct scic_sds_phy *phy)
2332 {
2333         /*
2334          * / @todo We should make sure that the phy that has gone link up is the same
2335          * /       one on which we sent the reset.  It is possible that the phy on
2336          * /       which we sent the reset is not the one that has gone link up and we
2337          * /       want to make sure that phy being reset comes back.  Consider the
2338          * /       case where a reset is sent but before the hardware processes the
2339          * /       reset it get a link up on the port because of a hot plug event.
2340          * /       because of the reset request this phy will go link down almost
2341          * /       immediately. */
2342
2343         /*
2344          * In the resetting state we don't notify the user regarding
2345          * link up and link down notifications. */
2346         scic_sds_port_general_link_up_handler(this_port, phy, false);
2347 }
2348
2349 /**
2350  *
2351  * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2352  *    object.
2353  *
2354  * This method process link down notifications that occur during a port reset
2355  * operation. Link downs can occur during the reset operation. enum sci_status
2356  * SCI_SUCCESS
2357  */
2358 static void scic_sds_port_reset_state_link_down_handler(
2359         struct scic_sds_port *this_port,
2360         struct scic_sds_phy *phy)
2361 {
2362         /*
2363          * In the resetting state we don't notify the user regarding
2364          * link up and link down notifications. */
2365         scic_sds_port_deactivate_phy(this_port, phy, false);
2366 }
2367
2368 /* --------------------------------------------------------------------------- */
2369
2370 struct scic_sds_port_state_handler
2371 scic_sds_port_state_handler_table[SCI_BASE_PORT_MAX_STATES] =
2372 {
2373         /* SCI_BASE_PORT_STATE_STOPPED */
2374         {
2375                 {
2376                         scic_sds_port_stopped_state_start_handler,
2377                         scic_sds_port_stopped_state_stop_handler,
2378                         scic_sds_port_stopped_state_destruct_handler,
2379                         scic_sds_port_default_reset_handler,
2380                         scic_sds_port_stopped_state_add_phy_handler,
2381                         scic_sds_port_stopped_state_remove_phy_handler
2382                 },
2383                 scic_sds_port_default_frame_handler,
2384                 scic_sds_port_default_event_handler,
2385                 scic_sds_port_default_link_up_handler,
2386                 scic_sds_port_default_link_down_handler,
2387                 scic_sds_port_default_start_io_handler,
2388                 scic_sds_port_default_complete_io_handler
2389         },
2390         /* SCI_BASE_PORT_STATE_STOPPING */
2391         {
2392                 {
2393                         scic_sds_port_default_start_handler,
2394                         scic_sds_port_default_stop_handler,
2395                         scic_sds_port_default_destruct_handler,
2396                         scic_sds_port_default_reset_handler,
2397                         scic_sds_port_default_add_phy_handler,
2398                         scic_sds_port_default_remove_phy_handler
2399                 },
2400                 scic_sds_port_default_frame_handler,
2401                 scic_sds_port_default_event_handler,
2402                 scic_sds_port_default_link_up_handler,
2403                 scic_sds_port_default_link_down_handler,
2404                 scic_sds_port_default_start_io_handler,
2405                 scic_sds_port_stopping_state_complete_io_handler
2406         },
2407         /* SCI_BASE_PORT_STATE_READY */
2408         {
2409                 {
2410                         scic_sds_port_default_start_handler,
2411                         scic_sds_port_default_stop_handler,
2412                         scic_sds_port_default_destruct_handler,
2413                         scic_sds_port_default_reset_handler,
2414                         scic_sds_port_default_add_phy_handler,
2415                         scic_sds_port_default_remove_phy_handler
2416                 },
2417                 scic_sds_port_default_frame_handler,
2418                 scic_sds_port_default_event_handler,
2419                 scic_sds_port_default_link_up_handler,
2420                 scic_sds_port_default_link_down_handler,
2421                 scic_sds_port_default_start_io_handler,
2422                 scic_sds_port_general_complete_io_handler
2423         },
2424         /* SCI_BASE_PORT_STATE_RESETTING */
2425         {
2426                 {
2427                         scic_sds_port_default_start_handler,
2428                         scic_sds_port_reset_state_stop_handler,
2429                         scic_sds_port_default_destruct_handler,
2430                         scic_sds_port_default_reset_handler,
2431                         scic_sds_port_default_add_phy_handler,
2432                         scic_sds_port_default_remove_phy_handler
2433                 },
2434                 scic_sds_port_default_frame_handler,
2435                 scic_sds_port_default_event_handler,
2436                 scic_sds_port_reset_state_link_up_handler,
2437                 scic_sds_port_reset_state_link_down_handler,
2438                 scic_sds_port_default_start_io_handler,
2439                 scic_sds_port_general_complete_io_handler
2440         },
2441         /* SCI_BASE_PORT_STATE_FAILED */
2442         {
2443                 {
2444                         scic_sds_port_default_start_handler,
2445                         scic_sds_port_default_stop_handler,
2446                         scic_sds_port_default_destruct_handler,
2447                         scic_sds_port_default_reset_handler,
2448                         scic_sds_port_default_add_phy_handler,
2449                         scic_sds_port_default_remove_phy_handler
2450                 },
2451                 scic_sds_port_default_frame_handler,
2452                 scic_sds_port_default_event_handler,
2453                 scic_sds_port_default_link_up_handler,
2454                 scic_sds_port_default_link_down_handler,
2455                 scic_sds_port_default_start_io_handler,
2456                 scic_sds_port_general_complete_io_handler
2457         }
2458 };
2459
2460 /*
2461  * ******************************************************************************
2462  * *  PORT STATE PRIVATE METHODS
2463  * ****************************************************************************** */
2464
2465 /**
2466  *
2467  * @this_port: This is the port object which to suspend.
2468  *
2469  * This method will enable the SCU Port Task Scheduler for this port object but
2470  * will leave the port task scheduler in a suspended state. none
2471  */
2472 static void scic_sds_port_enable_port_task_scheduler(
2473         struct scic_sds_port *this_port)
2474 {
2475         u32 pts_control_value;
2476
2477         pts_control_value = scu_port_task_scheduler_read(this_port, control);
2478
2479         pts_control_value |= SCU_PTSxCR_GEN_BIT(ENABLE) | SCU_PTSxCR_GEN_BIT(SUSPEND);
2480
2481         scu_port_task_scheduler_write(this_port, control, pts_control_value);
2482 }
2483
2484 /**
2485  *
2486  * @this_port: This is the port object which to resume.
2487  *
2488  * This method will disable the SCU port task scheduler for this port object.
2489  * none
2490  */
2491 static void scic_sds_port_disable_port_task_scheduler(
2492         struct scic_sds_port *this_port)
2493 {
2494         u32 pts_control_value;
2495
2496         pts_control_value = scu_port_task_scheduler_read(this_port, control);
2497
2498         pts_control_value &= ~(SCU_PTSxCR_GEN_BIT(ENABLE)
2499                                | SCU_PTSxCR_GEN_BIT(SUSPEND));
2500
2501         scu_port_task_scheduler_write(this_port, control, pts_control_value);
2502 }
2503
2504 /*
2505  * ******************************************************************************
2506  * *  PORT STATE METHODS
2507  * ****************************************************************************** */
2508
2509 /**
2510  *
2511  * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2512  *
2513  * This method will perform the actions required by the struct scic_sds_port on
2514  * entering the SCI_BASE_PORT_STATE_STOPPED. This function sets the stopped
2515  * state handlers for the struct scic_sds_port object and disables the port task
2516  * scheduler in the hardware. none
2517  */
2518 static void scic_sds_port_stopped_state_enter(
2519         struct sci_base_object *object)
2520 {
2521         struct scic_sds_port *this_port;
2522
2523         this_port = (struct scic_sds_port *)object;
2524
2525         scic_sds_port_set_base_state_handlers(
2526                 this_port, SCI_BASE_PORT_STATE_STOPPED
2527                 );
2528
2529         if (
2530                 SCI_BASE_PORT_STATE_STOPPING
2531                 == this_port->parent.state_machine.previous_state_id
2532                 ) {
2533                 /*
2534                  * If we enter this state becasuse of a request to stop
2535                  * the port then we want to disable the hardwares port
2536                  * task scheduler. */
2537                 scic_sds_port_disable_port_task_scheduler(this_port);
2538         }
2539 }
2540
2541 /**
2542  *
2543  * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2544  *
2545  * This method will perform the actions required by the struct scic_sds_port on
2546  * exiting the SCI_BASE_STATE_STOPPED. This function enables the SCU hardware
2547  * port task scheduler. none
2548  */
2549 static void scic_sds_port_stopped_state_exit(
2550         struct sci_base_object *object)
2551 {
2552         struct scic_sds_port *this_port;
2553
2554         this_port = (struct scic_sds_port *)object;
2555
2556         /* Enable and suspend the port task scheduler */
2557         scic_sds_port_enable_port_task_scheduler(this_port);
2558 }
2559
2560 /**
2561  *
2562  * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2563  *
2564  * This method will perform the actions required by the struct scic_sds_port on
2565  * entering the SCI_BASE_PORT_STATE_READY. This function sets the ready state
2566  * handlers for the struct scic_sds_port object, reports the port object as not ready
2567  * and starts the ready substate machine. none
2568  */
2569 static void scic_sds_port_ready_state_enter(
2570         struct sci_base_object *object)
2571 {
2572         struct scic_sds_port *this_port;
2573
2574         this_port = (struct scic_sds_port *)object;
2575
2576         /* Put the ready state handlers in place though they will not be there long */
2577         scic_sds_port_set_base_state_handlers(
2578                 this_port, SCI_BASE_PORT_STATE_READY
2579                 );
2580
2581         if (
2582                 SCI_BASE_PORT_STATE_RESETTING
2583                 == this_port->parent.state_machine.previous_state_id
2584                 ) {
2585                 scic_cb_port_hard_reset_complete(
2586                         scic_sds_port_get_controller(this_port),
2587                         this_port,
2588                         SCI_SUCCESS
2589                         );
2590         } else {
2591                 /* Notify the caller that the port is not yet ready */
2592                 scic_cb_port_not_ready(
2593                         scic_sds_port_get_controller(this_port),
2594                         this_port,
2595                         SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS
2596                         );
2597         }
2598
2599         /* Start the ready substate machine */
2600         sci_base_state_machine_start(
2601                 scic_sds_port_get_ready_substate_machine(this_port)
2602                 );
2603 }
2604
2605 /**
2606  *
2607  * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2608  *
2609  * This method will perform the actions required by the struct scic_sds_port on
2610  * exiting the SCI_BASE_STATE_READY. This function does nothing. none
2611  */
2612 static void scic_sds_port_ready_state_exit(
2613         struct sci_base_object *object)
2614 {
2615         struct scic_sds_port *this_port;
2616
2617         this_port = (struct scic_sds_port *)object;
2618
2619         sci_base_state_machine_stop(&this_port->ready_substate_machine);
2620 }
2621
2622 /**
2623  *
2624  * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2625  *
2626  * This method will perform the actions required by the struct scic_sds_port on
2627  * entering the SCI_BASE_PORT_STATE_RESETTING. This function sets the resetting
2628  * state handlers for the struct scic_sds_port object. none
2629  */
2630 static void scic_sds_port_resetting_state_enter(
2631         struct sci_base_object *object)
2632 {
2633         struct scic_sds_port *this_port;
2634
2635         this_port = (struct scic_sds_port *)object;
2636
2637         scic_sds_port_set_base_state_handlers(
2638                 this_port, SCI_BASE_PORT_STATE_RESETTING
2639                 );
2640
2641         scic_sds_port_set_direct_attached_device_id(
2642                 this_port,
2643                 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
2644                 );
2645 }
2646
2647 /**
2648  *
2649  * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2650  *
2651  * This method will perform the actions required by the struct scic_sds_port on
2652  * exiting the SCI_BASE_STATE_RESETTING. This function does nothing. none
2653  */
2654 static void scic_sds_port_resetting_state_exit(
2655         struct sci_base_object *object)
2656 {
2657         struct scic_sds_port *this_port;
2658
2659         this_port = (struct scic_sds_port *)object;
2660
2661         scic_cb_timer_stop(
2662                 scic_sds_port_get_controller(this_port),
2663                 this_port->timer_handle
2664                 );
2665 }
2666
2667 /**
2668  *
2669  * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2670  *
2671  * This method will perform the actions required by the struct scic_sds_port on
2672  * entering the SCI_BASE_PORT_STATE_STOPPING. This function sets the stopping
2673  * state handlers for the struct scic_sds_port object. none
2674  */
2675 static void scic_sds_port_stopping_state_enter(
2676         struct sci_base_object *object)
2677 {
2678         struct scic_sds_port *this_port;
2679
2680         this_port = (struct scic_sds_port *)object;
2681
2682         scic_sds_port_set_base_state_handlers(
2683                 this_port, SCI_BASE_PORT_STATE_STOPPING
2684                 );
2685 }
2686
2687 /**
2688  *
2689  * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2690  *
2691  * This method will perform the actions required by the struct scic_sds_port on
2692  * exiting the SCI_BASE_STATE_STOPPING. This function does nothing. none
2693  */
2694 static void scic_sds_port_stopping_state_exit(
2695         struct sci_base_object *object)
2696 {
2697         struct scic_sds_port *this_port;
2698
2699         this_port = (struct scic_sds_port *)object;
2700
2701         scic_cb_timer_stop(
2702                 scic_sds_port_get_controller(this_port),
2703                 this_port->timer_handle
2704                 );
2705 }
2706
2707 /**
2708  *
2709  * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2710  *
2711  * This method will perform the actions required by the struct scic_sds_port on
2712  * entering the SCI_BASE_PORT_STATE_STOPPING. This function sets the stopping
2713  * state handlers for the struct scic_sds_port object. none
2714  */
2715 static void scic_sds_port_failed_state_enter(
2716         struct sci_base_object *object)
2717 {
2718         struct scic_sds_port *this_port;
2719
2720         this_port = (struct scic_sds_port *)object;
2721
2722         scic_sds_port_set_base_state_handlers(
2723                 this_port,
2724                 SCI_BASE_PORT_STATE_FAILED
2725                 );
2726
2727         scic_cb_port_hard_reset_complete(
2728                 scic_sds_port_get_controller(this_port),
2729                 this_port,
2730                 SCI_FAILURE_TIMEOUT
2731                 );
2732 }
2733
2734 /* --------------------------------------------------------------------------- */
2735
2736 const struct sci_base_state scic_sds_port_state_table[] = {
2737         [SCI_BASE_PORT_STATE_STOPPED] = {
2738                 .enter_state = scic_sds_port_stopped_state_enter,
2739                 .exit_state  = scic_sds_port_stopped_state_exit
2740         },
2741         [SCI_BASE_PORT_STATE_STOPPING] = {
2742                 .enter_state = scic_sds_port_stopping_state_enter,
2743                 .exit_state  = scic_sds_port_stopping_state_exit
2744         },
2745         [SCI_BASE_PORT_STATE_READY] = {
2746                 .enter_state = scic_sds_port_ready_state_enter,
2747                 .exit_state  = scic_sds_port_ready_state_exit
2748         },
2749         [SCI_BASE_PORT_STATE_RESETTING] = {
2750                 .enter_state = scic_sds_port_resetting_state_enter,
2751                 .exit_state  = scic_sds_port_resetting_state_exit
2752         },
2753         [SCI_BASE_PORT_STATE_FAILED] = {
2754                 .enter_state = scic_sds_port_failed_state_enter,
2755         }
2756 };
2757