]>
Commit | Line | Data |
---|---|---|
6f231dda DW |
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 | ||
e531381e | 56 | #ifndef _ISCI_PORT_H_ |
6f231dda | 57 | #define _ISCI_PORT_H_ |
ce2b3261 DW |
58 | |
59 | #include <scsi/libsas.h> | |
60 | #include "isci.h" | |
e2f8db50 DW |
61 | #include "sas.h" |
62 | #include "phy.h" | |
63 | ||
64 | #define SCIC_SDS_DUMMY_PORT 0xFF | |
6f231dda | 65 | |
05b080fc MT |
66 | #define PF_NOTIFY (1 << 0) |
67 | #define PF_RESUME (1 << 1) | |
68 | ||
6f231dda DW |
69 | struct isci_phy; |
70 | struct isci_host; | |
6f231dda DW |
71 | |
72 | enum isci_status { | |
73 | isci_freed = 0x00, | |
74 | isci_starting = 0x01, | |
75 | isci_ready = 0x02, | |
76 | isci_ready_for_io = 0x03, | |
77 | isci_stopping = 0x04, | |
78 | isci_stopped = 0x05, | |
6f231dda DW |
79 | }; |
80 | ||
e2f8db50 | 81 | /** |
ffe191c9 | 82 | * struct isci_port - isci direct attached sas port object |
ffe191c9 DW |
83 | * @ready_exit: several states constitute 'ready'. When exiting ready we |
84 | * need to take extra port-teardown actions that are | |
85 | * skipped when exiting to another 'ready' state. | |
86 | * @logical_port_index: software port index | |
87 | * @physical_port_index: hardware port index | |
88 | * @active_phy_mask: identifies phy members | |
05b080fc MT |
89 | * @enabled_phy_mask: phy mask for the port |
90 | * that are already part of the port | |
ffe191c9 DW |
91 | * @reserved_tag: |
92 | * @reserved_rni: reserver for port task scheduler workaround | |
93 | * @started_request_count: reference count for outstanding commands | |
94 | * @not_ready_reason: set during state transitions and notified | |
95 | * @timer: timeout start/stop operations | |
6f231dda DW |
96 | */ |
97 | struct isci_port { | |
6f231dda | 98 | struct isci_host *isci_host; |
6f231dda | 99 | struct list_head remote_dev_list; |
92776991 DW |
100 | #define IPORT_RESET_PENDING 0 |
101 | unsigned long state; | |
6f231dda | 102 | enum sci_status hard_reset_status; |
ffe191c9 DW |
103 | struct sci_base_state_machine sm; |
104 | bool ready_exit; | |
105 | u8 logical_port_index; | |
106 | u8 physical_port_index; | |
107 | u8 active_phy_mask; | |
05b080fc | 108 | u8 enabled_phy_mask; |
8e35a139 | 109 | u8 last_active_phy; |
ffe191c9 DW |
110 | u16 reserved_rni; |
111 | u16 reserved_tag; | |
112 | u32 started_request_count; | |
113 | u32 assigned_device_count; | |
6f48844e | 114 | u32 hang_detect_users; |
ffe191c9 DW |
115 | u32 not_ready_reason; |
116 | struct isci_phy *phy_table[SCI_MAX_PHYS]; | |
d9dcb4ba | 117 | struct isci_host *owning_controller; |
ffe191c9 DW |
118 | struct sci_timer timer; |
119 | struct scu_port_task_scheduler_registers __iomem *port_task_scheduler_registers; | |
120 | /* XXX rework: only one register, no need to replicate per-port */ | |
121 | u32 __iomem *port_pe_configuration_register; | |
122 | struct scu_viit_entry __iomem *viit_registers; | |
6f231dda DW |
123 | }; |
124 | ||
89a7301f | 125 | enum sci_port_not_ready_reason_code { |
e2f8db50 DW |
126 | SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS, |
127 | SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED, | |
128 | SCIC_PORT_NOT_READY_INVALID_PORT_CONFIGURATION, | |
129 | SCIC_PORT_NOT_READY_RECONFIGURING, | |
130 | ||
131 | SCIC_PORT_NOT_READY_REASON_CODE_MAX | |
132 | }; | |
133 | ||
89a7301f | 134 | struct sci_port_end_point_properties { |
e2f8db50 | 135 | struct sci_sas_address sas_address; |
89a7301f | 136 | struct sci_phy_proto protocols; |
e2f8db50 DW |
137 | }; |
138 | ||
89a7301f | 139 | struct sci_port_properties { |
e2f8db50 | 140 | u32 index; |
89a7301f DW |
141 | struct sci_port_end_point_properties local; |
142 | struct sci_port_end_point_properties remote; | |
e2f8db50 DW |
143 | u32 phy_mask; |
144 | }; | |
145 | ||
e2f8db50 | 146 | /** |
d7a0ccdd DW |
147 | * enum sci_port_states - port state machine states |
148 | * @SCI_PORT_STOPPED: port has successfully been stopped. In this state | |
149 | * no new IO operations are permitted. This state is | |
150 | * entered from the STOPPING state. | |
151 | * @SCI_PORT_STOPPING: port is in the process of stopping. In this | |
152 | * state no new IO operations are permitted, but | |
153 | * existing IO operations are allowed to complete. | |
154 | * This state is entered from the READY state. | |
155 | * @SCI_PORT_READY: port is now ready. Thus, the user is able to | |
156 | * perform IO operations on this port. This state is | |
157 | * entered from the STARTING state. | |
158 | * @SCI_PORT_SUB_WAITING: port is started and ready but has no active | |
159 | * phys. | |
160 | * @SCI_PORT_SUB_OPERATIONAL: port is started and ready and there is at | |
161 | * least one phy operational. | |
162 | * @SCI_PORT_SUB_CONFIGURING: port is started and there was an | |
163 | * add/remove phy event. This state is only | |
164 | * used in Automatic Port Configuration Mode | |
165 | * (APC) | |
166 | * @SCI_PORT_RESETTING: port is in the process of performing a hard | |
167 | * reset. Thus, the user is unable to perform IO | |
168 | * operations on this port. This state is entered | |
169 | * from the READY state. | |
170 | * @SCI_PORT_FAILED: port has failed a reset request. This state is | |
171 | * entered when a port reset request times out. This | |
172 | * state is entered from the RESETTING state. | |
e2f8db50 | 173 | */ |
d7a0ccdd DW |
174 | #define PORT_STATES {\ |
175 | C(PORT_STOPPED),\ | |
176 | C(PORT_STOPPING),\ | |
177 | C(PORT_READY),\ | |
178 | C(PORT_SUB_WAITING),\ | |
179 | C(PORT_SUB_OPERATIONAL),\ | |
180 | C(PORT_SUB_CONFIGURING),\ | |
181 | C(PORT_RESETTING),\ | |
182 | C(PORT_FAILED),\ | |
183 | } | |
184 | #undef C | |
185 | #define C(a) SCI_##a | |
186 | enum sci_port_states PORT_STATES; | |
187 | #undef C | |
e2f8db50 | 188 | |
89a7301f | 189 | static inline void sci_port_decrement_request_count(struct isci_port *iport) |
e2f8db50 | 190 | { |
ffe191c9 | 191 | if (WARN_ONCE(iport->started_request_count == 0, |
e2f8db50 DW |
192 | "%s: tried to decrement started_request_count past 0!?", |
193 | __func__)) | |
194 | /* pass */; | |
195 | else | |
ffe191c9 | 196 | iport->started_request_count--; |
e2f8db50 DW |
197 | } |
198 | ||
89a7301f | 199 | #define sci_port_active_phy(port, phy) \ |
e2f8db50 DW |
200 | (((port)->active_phy_mask & (1 << (phy)->phy_index)) != 0) |
201 | ||
89a7301f | 202 | void sci_port_construct( |
ffe191c9 | 203 | struct isci_port *iport, |
e2f8db50 | 204 | u8 port_index, |
d9dcb4ba | 205 | struct isci_host *ihost); |
e2f8db50 | 206 | |
89a7301f DW |
207 | enum sci_status sci_port_start(struct isci_port *iport); |
208 | enum sci_status sci_port_stop(struct isci_port *iport); | |
d76f71d9 | 209 | |
89a7301f | 210 | enum sci_status sci_port_add_phy( |
ffe191c9 | 211 | struct isci_port *iport, |
85280955 | 212 | struct isci_phy *iphy); |
e2f8db50 | 213 | |
89a7301f | 214 | enum sci_status sci_port_remove_phy( |
ffe191c9 | 215 | struct isci_port *iport, |
85280955 | 216 | struct isci_phy *iphy); |
e2f8db50 | 217 | |
89a7301f | 218 | void sci_port_setup_transports( |
ffe191c9 | 219 | struct isci_port *iport, |
e2f8db50 DW |
220 | u32 device_id); |
221 | ||
61aaff49 | 222 | void isci_port_bcn_enable(struct isci_host *, struct isci_port *); |
e2f8db50 | 223 | |
89a7301f | 224 | void sci_port_deactivate_phy( |
ffe191c9 | 225 | struct isci_port *iport, |
85280955 | 226 | struct isci_phy *iphy, |
e2f8db50 DW |
227 | bool do_notify_user); |
228 | ||
89a7301f | 229 | bool sci_port_link_detected( |
ffe191c9 | 230 | struct isci_port *iport, |
85280955 | 231 | struct isci_phy *iphy); |
e2f8db50 | 232 | |
7e629841 BN |
233 | enum sci_status sci_port_get_properties( |
234 | struct isci_port *iport, | |
235 | struct sci_port_properties *prop); | |
236 | ||
89a7301f | 237 | enum sci_status sci_port_link_up(struct isci_port *iport, |
85280955 | 238 | struct isci_phy *iphy); |
89a7301f | 239 | enum sci_status sci_port_link_down(struct isci_port *iport, |
85280955 | 240 | struct isci_phy *iphy); |
e2f8db50 | 241 | |
5076a1a9 | 242 | struct isci_request; |
78a6f06e | 243 | struct isci_remote_device; |
89a7301f | 244 | enum sci_status sci_port_start_io( |
ffe191c9 | 245 | struct isci_port *iport, |
78a6f06e | 246 | struct isci_remote_device *idev, |
5076a1a9 | 247 | struct isci_request *ireq); |
e2f8db50 | 248 | |
89a7301f | 249 | enum sci_status sci_port_complete_io( |
ffe191c9 | 250 | struct isci_port *iport, |
78a6f06e | 251 | struct isci_remote_device *idev, |
5076a1a9 | 252 | struct isci_request *ireq); |
e2f8db50 | 253 | |
89a7301f | 254 | enum sas_linkrate sci_port_get_max_allowed_speed( |
ffe191c9 | 255 | struct isci_port *iport); |
e2f8db50 | 256 | |
89a7301f | 257 | void sci_port_broadcast_change_received( |
ffe191c9 | 258 | struct isci_port *iport, |
85280955 | 259 | struct isci_phy *iphy); |
e2f8db50 | 260 | |
89a7301f | 261 | bool sci_port_is_valid_phy_assignment( |
ffe191c9 | 262 | struct isci_port *iport, |
e2f8db50 DW |
263 | u32 phy_index); |
264 | ||
89a7301f | 265 | void sci_port_get_sas_address( |
ffe191c9 | 266 | struct isci_port *iport, |
e2f8db50 DW |
267 | struct sci_sas_address *sas_address); |
268 | ||
89a7301f | 269 | void sci_port_get_attached_sas_address( |
ffe191c9 | 270 | struct isci_port *iport, |
e2f8db50 DW |
271 | struct sci_sas_address *sas_address); |
272 | ||
6f48844e JS |
273 | void sci_port_set_hang_detection_timeout( |
274 | struct isci_port *isci_port, | |
275 | u32 timeout); | |
276 | ||
e2f8db50 DW |
277 | void isci_port_formed(struct asd_sas_phy *); |
278 | void isci_port_deformed(struct asd_sas_phy *); | |
6f231dda | 279 | |
4393aa4e DW |
280 | int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport, |
281 | struct isci_phy *iphy); | |
687833a0 | 282 | int isci_ata_check_ready(struct domain_device *dev); |
6f231dda | 283 | #endif /* !defined(_ISCI_PORT_H_) */ |