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