1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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#define PF_NOTIFY (1 << 0)
67#define PF_RESUME (1 << 1)
68
69struct isci_phy;
70struct isci_host;
71
72enum 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,
79};
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97struct isci_port {
98 struct isci_host *isci_host;
99 struct list_head remote_dev_list;
100 #define IPORT_RESET_PENDING 0
101 unsigned long state;
102 enum sci_status hard_reset_status;
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;
108 u8 enabled_phy_mask;
109 u8 last_active_phy;
110 u16 reserved_rni;
111 u16 reserved_tag;
112 u32 started_request_count;
113 u32 assigned_device_count;
114 u32 hang_detect_users;
115 u32 not_ready_reason;
116 struct isci_phy *phy_table[SCI_MAX_PHYS];
117 struct isci_host *owning_controller;
118 struct sci_timer timer;
119 struct scu_port_task_scheduler_registers __iomem *port_task_scheduler_registers;
120
121 u32 __iomem *port_pe_configuration_register;
122 struct scu_viit_entry __iomem *viit_registers;
123};
124
125enum sci_port_not_ready_reason_code {
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
134struct sci_port_end_point_properties {
135 struct sci_sas_address sas_address;
136 struct sci_phy_proto protocols;
137};
138
139struct sci_port_properties {
140 u32 index;
141 struct sci_port_end_point_properties local;
142 struct sci_port_end_point_properties remote;
143 u32 phy_mask;
144};
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
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
186enum sci_port_states PORT_STATES;
187#undef C
188
189static inline void sci_port_decrement_request_count(struct isci_port *iport)
190{
191 if (WARN_ONCE(iport->started_request_count == 0,
192 "%s: tried to decrement started_request_count past 0!?",
193 __func__))
194 ;
195 else
196 iport->started_request_count--;
197}
198
199#define sci_port_active_phy(port, phy) \
200 (((port)->active_phy_mask & (1 << (phy)->phy_index)) != 0)
201
202void sci_port_construct(
203 struct isci_port *iport,
204 u8 port_index,
205 struct isci_host *ihost);
206
207enum sci_status sci_port_start(struct isci_port *iport);
208enum sci_status sci_port_stop(struct isci_port *iport);
209
210enum sci_status sci_port_add_phy(
211 struct isci_port *iport,
212 struct isci_phy *iphy);
213
214enum sci_status sci_port_remove_phy(
215 struct isci_port *iport,
216 struct isci_phy *iphy);
217
218void sci_port_setup_transports(
219 struct isci_port *iport,
220 u32 device_id);
221
222void isci_port_bcn_enable(struct isci_host *, struct isci_port *);
223
224void sci_port_deactivate_phy(
225 struct isci_port *iport,
226 struct isci_phy *iphy,
227 bool do_notify_user);
228
229bool sci_port_link_detected(
230 struct isci_port *iport,
231 struct isci_phy *iphy);
232
233enum sci_status sci_port_get_properties(
234 struct isci_port *iport,
235 struct sci_port_properties *prop);
236
237enum sci_status sci_port_link_up(struct isci_port *iport,
238 struct isci_phy *iphy);
239enum sci_status sci_port_link_down(struct isci_port *iport,
240 struct isci_phy *iphy);
241
242struct isci_request;
243struct isci_remote_device;
244enum sci_status sci_port_start_io(
245 struct isci_port *iport,
246 struct isci_remote_device *idev,
247 struct isci_request *ireq);
248
249enum sci_status sci_port_complete_io(
250 struct isci_port *iport,
251 struct isci_remote_device *idev,
252 struct isci_request *ireq);
253
254enum sas_linkrate sci_port_get_max_allowed_speed(
255 struct isci_port *iport);
256
257void sci_port_broadcast_change_received(
258 struct isci_port *iport,
259 struct isci_phy *iphy);
260
261bool sci_port_is_valid_phy_assignment(
262 struct isci_port *iport,
263 u32 phy_index);
264
265void sci_port_get_sas_address(
266 struct isci_port *iport,
267 struct sci_sas_address *sas_address);
268
269void sci_port_get_attached_sas_address(
270 struct isci_port *iport,
271 struct sci_sas_address *sas_address);
272
273void sci_port_set_hang_detection_timeout(
274 struct isci_port *isci_port,
275 u32 timeout);
276
277void isci_port_formed(struct asd_sas_phy *);
278void isci_port_deformed(struct asd_sas_phy *);
279
280int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport,
281 struct isci_phy *iphy);
282int isci_ata_check_ready(struct domain_device *dev);
283#endif
284