diff options
Diffstat (limited to 'drivers/scsi/isci/port.h')
-rw-r--r-- | drivers/scsi/isci/port.h | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/drivers/scsi/isci/port.h b/drivers/scsi/isci/port.h new file mode 100644 index 000000000000..b50ecd4e8f9c --- /dev/null +++ b/drivers/scsi/isci/port.h | |||
@@ -0,0 +1,306 @@ | |||
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 _ISCI_PORT_H_ | ||
57 | #define _ISCI_PORT_H_ | ||
58 | |||
59 | #include <scsi/libsas.h> | ||
60 | #include "isci.h" | ||
61 | #include "sas.h" | ||
62 | #include "phy.h" | ||
63 | |||
64 | #define SCIC_SDS_DUMMY_PORT 0xFF | ||
65 | |||
66 | struct isci_phy; | ||
67 | struct isci_host; | ||
68 | |||
69 | enum isci_status { | ||
70 | isci_freed = 0x00, | ||
71 | isci_starting = 0x01, | ||
72 | isci_ready = 0x02, | ||
73 | isci_ready_for_io = 0x03, | ||
74 | isci_stopping = 0x04, | ||
75 | isci_stopped = 0x05, | ||
76 | }; | ||
77 | |||
78 | /** | ||
79 | * struct isci_port - isci direct attached sas port object | ||
80 | * @event: counts bcns and port stop events (for bcn filtering) | ||
81 | * @ready_exit: several states constitute 'ready'. When exiting ready we | ||
82 | * need to take extra port-teardown actions that are | ||
83 | * skipped when exiting to another 'ready' state. | ||
84 | * @logical_port_index: software port index | ||
85 | * @physical_port_index: hardware port index | ||
86 | * @active_phy_mask: identifies phy members | ||
87 | * @reserved_tag: | ||
88 | * @reserved_rni: reserver for port task scheduler workaround | ||
89 | * @started_request_count: reference count for outstanding commands | ||
90 | * @not_ready_reason: set during state transitions and notified | ||
91 | * @timer: timeout start/stop operations | ||
92 | */ | ||
93 | struct isci_port { | ||
94 | enum isci_status status; | ||
95 | #define IPORT_BCN_BLOCKED 0 | ||
96 | #define IPORT_BCN_PENDING 1 | ||
97 | unsigned long flags; | ||
98 | atomic_t event; | ||
99 | struct isci_host *isci_host; | ||
100 | struct asd_sas_port sas_port; | ||
101 | struct list_head remote_dev_list; | ||
102 | spinlock_t state_lock; | ||
103 | struct list_head domain_dev_list; | ||
104 | struct completion start_complete; | ||
105 | struct completion hard_reset_complete; | ||
106 | enum sci_status hard_reset_status; | ||
107 | struct sci_base_state_machine sm; | ||
108 | bool ready_exit; | ||
109 | u8 logical_port_index; | ||
110 | u8 physical_port_index; | ||
111 | u8 active_phy_mask; | ||
112 | u16 reserved_rni; | ||
113 | u16 reserved_tag; | ||
114 | u32 started_request_count; | ||
115 | u32 assigned_device_count; | ||
116 | u32 not_ready_reason; | ||
117 | struct isci_phy *phy_table[SCI_MAX_PHYS]; | ||
118 | struct isci_host *owning_controller; | ||
119 | struct sci_timer timer; | ||
120 | struct scu_port_task_scheduler_registers __iomem *port_task_scheduler_registers; | ||
121 | /* XXX rework: only one register, no need to replicate per-port */ | ||
122 | u32 __iomem *port_pe_configuration_register; | ||
123 | struct scu_viit_entry __iomem *viit_registers; | ||
124 | }; | ||
125 | |||
126 | enum sci_port_not_ready_reason_code { | ||
127 | SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS, | ||
128 | SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED, | ||
129 | SCIC_PORT_NOT_READY_INVALID_PORT_CONFIGURATION, | ||
130 | SCIC_PORT_NOT_READY_RECONFIGURING, | ||
131 | |||
132 | SCIC_PORT_NOT_READY_REASON_CODE_MAX | ||
133 | }; | ||
134 | |||
135 | struct sci_port_end_point_properties { | ||
136 | struct sci_sas_address sas_address; | ||
137 | struct sci_phy_proto protocols; | ||
138 | }; | ||
139 | |||
140 | struct sci_port_properties { | ||
141 | u32 index; | ||
142 | struct sci_port_end_point_properties local; | ||
143 | struct sci_port_end_point_properties remote; | ||
144 | u32 phy_mask; | ||
145 | }; | ||
146 | |||
147 | /** | ||
148 | * enum sci_port_states - This enumeration depicts all the states for the | ||
149 | * common port state machine. | ||
150 | * | ||
151 | * | ||
152 | */ | ||
153 | enum sci_port_states { | ||
154 | /** | ||
155 | * This state indicates that the port has successfully been stopped. | ||
156 | * In this state no new IO operations are permitted. | ||
157 | * This state is entered from the STOPPING state. | ||
158 | */ | ||
159 | SCI_PORT_STOPPED, | ||
160 | |||
161 | /** | ||
162 | * This state indicates that the port is in the process of stopping. | ||
163 | * In this state no new IO operations are permitted, but existing IO | ||
164 | * operations are allowed to complete. | ||
165 | * This state is entered from the READY state. | ||
166 | */ | ||
167 | SCI_PORT_STOPPING, | ||
168 | |||
169 | /** | ||
170 | * This state indicates the port is now ready. Thus, the user is | ||
171 | * able to perform IO operations on this port. | ||
172 | * This state is entered from the STARTING state. | ||
173 | */ | ||
174 | SCI_PORT_READY, | ||
175 | |||
176 | /** | ||
177 | * The substate where the port is started and ready but has no | ||
178 | * active phys. | ||
179 | */ | ||
180 | SCI_PORT_SUB_WAITING, | ||
181 | |||
182 | /** | ||
183 | * The substate where the port is started and ready and there is | ||
184 | * at least one phy operational. | ||
185 | */ | ||
186 | SCI_PORT_SUB_OPERATIONAL, | ||
187 | |||
188 | /** | ||
189 | * The substate where the port is started and there was an | ||
190 | * add/remove phy event. This state is only used in Automatic | ||
191 | * Port Configuration Mode (APC) | ||
192 | */ | ||
193 | SCI_PORT_SUB_CONFIGURING, | ||
194 | |||
195 | /** | ||
196 | * This state indicates the port is in the process of performing a hard | ||
197 | * reset. Thus, the user is unable to perform IO operations on this | ||
198 | * port. | ||
199 | * This state is entered from the READY state. | ||
200 | */ | ||
201 | SCI_PORT_RESETTING, | ||
202 | |||
203 | /** | ||
204 | * This state indicates the port has failed a reset request. This state | ||
205 | * is entered when a port reset request times out. | ||
206 | * This state is entered from the RESETTING state. | ||
207 | */ | ||
208 | SCI_PORT_FAILED, | ||
209 | |||
210 | |||
211 | }; | ||
212 | |||
213 | static inline void sci_port_decrement_request_count(struct isci_port *iport) | ||
214 | { | ||
215 | if (WARN_ONCE(iport->started_request_count == 0, | ||
216 | "%s: tried to decrement started_request_count past 0!?", | ||
217 | __func__)) | ||
218 | /* pass */; | ||
219 | else | ||
220 | iport->started_request_count--; | ||
221 | } | ||
222 | |||
223 | #define sci_port_active_phy(port, phy) \ | ||
224 | (((port)->active_phy_mask & (1 << (phy)->phy_index)) != 0) | ||
225 | |||
226 | void sci_port_construct( | ||
227 | struct isci_port *iport, | ||
228 | u8 port_index, | ||
229 | struct isci_host *ihost); | ||
230 | |||
231 | enum sci_status sci_port_start(struct isci_port *iport); | ||
232 | enum sci_status sci_port_stop(struct isci_port *iport); | ||
233 | |||
234 | enum sci_status sci_port_add_phy( | ||
235 | struct isci_port *iport, | ||
236 | struct isci_phy *iphy); | ||
237 | |||
238 | enum sci_status sci_port_remove_phy( | ||
239 | struct isci_port *iport, | ||
240 | struct isci_phy *iphy); | ||
241 | |||
242 | void sci_port_setup_transports( | ||
243 | struct isci_port *iport, | ||
244 | u32 device_id); | ||
245 | |||
246 | void isci_port_bcn_enable(struct isci_host *, struct isci_port *); | ||
247 | |||
248 | void sci_port_deactivate_phy( | ||
249 | struct isci_port *iport, | ||
250 | struct isci_phy *iphy, | ||
251 | bool do_notify_user); | ||
252 | |||
253 | bool sci_port_link_detected( | ||
254 | struct isci_port *iport, | ||
255 | struct isci_phy *iphy); | ||
256 | |||
257 | enum sci_status sci_port_link_up(struct isci_port *iport, | ||
258 | struct isci_phy *iphy); | ||
259 | enum sci_status sci_port_link_down(struct isci_port *iport, | ||
260 | struct isci_phy *iphy); | ||
261 | |||
262 | struct isci_request; | ||
263 | struct isci_remote_device; | ||
264 | enum sci_status sci_port_start_io( | ||
265 | struct isci_port *iport, | ||
266 | struct isci_remote_device *idev, | ||
267 | struct isci_request *ireq); | ||
268 | |||
269 | enum sci_status sci_port_complete_io( | ||
270 | struct isci_port *iport, | ||
271 | struct isci_remote_device *idev, | ||
272 | struct isci_request *ireq); | ||
273 | |||
274 | enum sas_linkrate sci_port_get_max_allowed_speed( | ||
275 | struct isci_port *iport); | ||
276 | |||
277 | void sci_port_broadcast_change_received( | ||
278 | struct isci_port *iport, | ||
279 | struct isci_phy *iphy); | ||
280 | |||
281 | bool sci_port_is_valid_phy_assignment( | ||
282 | struct isci_port *iport, | ||
283 | u32 phy_index); | ||
284 | |||
285 | void sci_port_get_sas_address( | ||
286 | struct isci_port *iport, | ||
287 | struct sci_sas_address *sas_address); | ||
288 | |||
289 | void sci_port_get_attached_sas_address( | ||
290 | struct isci_port *iport, | ||
291 | struct sci_sas_address *sas_address); | ||
292 | |||
293 | enum isci_status isci_port_get_state( | ||
294 | struct isci_port *isci_port); | ||
295 | |||
296 | void isci_port_formed(struct asd_sas_phy *); | ||
297 | void isci_port_deformed(struct asd_sas_phy *); | ||
298 | |||
299 | void isci_port_init( | ||
300 | struct isci_port *port, | ||
301 | struct isci_host *host, | ||
302 | int index); | ||
303 | |||
304 | int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport, | ||
305 | struct isci_phy *iphy); | ||
306 | #endif /* !defined(_ISCI_PORT_H_) */ | ||