Commit 77c309f3cdf9e217032dfe330f5881d352bb0436

Authored by Dan Williams
Committed by James Bottomley
1 parent 899fcf40f3

[SCSI] libsas: fixup target_port_protocols for expanders that don't report sata

If discovery returns 0 for target_port_protocols but shows an attached
sata device, just report SAS_PROTOCOL_SATA in the identify data so
userspace can reliably search for sata devices in the domain.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

Showing 1 changed file with 2 additions and 0 deletions Inline Diff

drivers/scsi/libsas/sas_expander.c
1 /* 1 /*
2 * Serial Attached SCSI (SAS) Expander discovery and configuration 2 * Serial Attached SCSI (SAS) Expander discovery and configuration
3 * 3 *
4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved. 4 * Copyright (C) 2005 Adaptec, Inc. All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com> 5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 * 6 *
7 * This file is licensed under GPLv2. 7 * This file is licensed under GPLv2.
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as 10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the 11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version. 12 * License, or (at your option) any later version.
13 * 13 *
14 * This program is distributed in the hope that it will be useful, but 14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details. 17 * General Public License for more details.
18 * 18 *
19 * You should have received a copy of the GNU General Public License 19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software 20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 * 22 *
23 */ 23 */
24 24
25 #include <linux/scatterlist.h> 25 #include <linux/scatterlist.h>
26 #include <linux/blkdev.h> 26 #include <linux/blkdev.h>
27 #include <linux/slab.h> 27 #include <linux/slab.h>
28 28
29 #include "sas_internal.h" 29 #include "sas_internal.h"
30 30
31 #include <scsi/sas_ata.h> 31 #include <scsi/sas_ata.h>
32 #include <scsi/scsi_transport.h> 32 #include <scsi/scsi_transport.h>
33 #include <scsi/scsi_transport_sas.h> 33 #include <scsi/scsi_transport_sas.h>
34 #include "../scsi_sas_internal.h" 34 #include "../scsi_sas_internal.h"
35 35
36 static int sas_discover_expander(struct domain_device *dev); 36 static int sas_discover_expander(struct domain_device *dev);
37 static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr); 37 static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr);
38 static int sas_configure_phy(struct domain_device *dev, int phy_id, 38 static int sas_configure_phy(struct domain_device *dev, int phy_id,
39 u8 *sas_addr, int include); 39 u8 *sas_addr, int include);
40 static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr); 40 static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr);
41 41
42 /* ---------- SMP task management ---------- */ 42 /* ---------- SMP task management ---------- */
43 43
44 static void smp_task_timedout(unsigned long _task) 44 static void smp_task_timedout(unsigned long _task)
45 { 45 {
46 struct sas_task *task = (void *) _task; 46 struct sas_task *task = (void *) _task;
47 unsigned long flags; 47 unsigned long flags;
48 48
49 spin_lock_irqsave(&task->task_state_lock, flags); 49 spin_lock_irqsave(&task->task_state_lock, flags);
50 if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) 50 if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
51 task->task_state_flags |= SAS_TASK_STATE_ABORTED; 51 task->task_state_flags |= SAS_TASK_STATE_ABORTED;
52 spin_unlock_irqrestore(&task->task_state_lock, flags); 52 spin_unlock_irqrestore(&task->task_state_lock, flags);
53 53
54 complete(&task->completion); 54 complete(&task->completion);
55 } 55 }
56 56
57 static void smp_task_done(struct sas_task *task) 57 static void smp_task_done(struct sas_task *task)
58 { 58 {
59 if (!del_timer(&task->timer)) 59 if (!del_timer(&task->timer))
60 return; 60 return;
61 complete(&task->completion); 61 complete(&task->completion);
62 } 62 }
63 63
64 /* Give it some long enough timeout. In seconds. */ 64 /* Give it some long enough timeout. In seconds. */
65 #define SMP_TIMEOUT 10 65 #define SMP_TIMEOUT 10
66 66
67 static int smp_execute_task(struct domain_device *dev, void *req, int req_size, 67 static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
68 void *resp, int resp_size) 68 void *resp, int resp_size)
69 { 69 {
70 int res, retry; 70 int res, retry;
71 struct sas_task *task = NULL; 71 struct sas_task *task = NULL;
72 struct sas_internal *i = 72 struct sas_internal *i =
73 to_sas_internal(dev->port->ha->core.shost->transportt); 73 to_sas_internal(dev->port->ha->core.shost->transportt);
74 74
75 mutex_lock(&dev->ex_dev.cmd_mutex); 75 mutex_lock(&dev->ex_dev.cmd_mutex);
76 for (retry = 0; retry < 3; retry++) { 76 for (retry = 0; retry < 3; retry++) {
77 if (test_bit(SAS_DEV_GONE, &dev->state)) { 77 if (test_bit(SAS_DEV_GONE, &dev->state)) {
78 res = -ECOMM; 78 res = -ECOMM;
79 break; 79 break;
80 } 80 }
81 81
82 task = sas_alloc_task(GFP_KERNEL); 82 task = sas_alloc_task(GFP_KERNEL);
83 if (!task) { 83 if (!task) {
84 res = -ENOMEM; 84 res = -ENOMEM;
85 break; 85 break;
86 } 86 }
87 task->dev = dev; 87 task->dev = dev;
88 task->task_proto = dev->tproto; 88 task->task_proto = dev->tproto;
89 sg_init_one(&task->smp_task.smp_req, req, req_size); 89 sg_init_one(&task->smp_task.smp_req, req, req_size);
90 sg_init_one(&task->smp_task.smp_resp, resp, resp_size); 90 sg_init_one(&task->smp_task.smp_resp, resp, resp_size);
91 91
92 task->task_done = smp_task_done; 92 task->task_done = smp_task_done;
93 93
94 task->timer.data = (unsigned long) task; 94 task->timer.data = (unsigned long) task;
95 task->timer.function = smp_task_timedout; 95 task->timer.function = smp_task_timedout;
96 task->timer.expires = jiffies + SMP_TIMEOUT*HZ; 96 task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
97 add_timer(&task->timer); 97 add_timer(&task->timer);
98 98
99 res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL); 99 res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
100 100
101 if (res) { 101 if (res) {
102 del_timer(&task->timer); 102 del_timer(&task->timer);
103 SAS_DPRINTK("executing SMP task failed:%d\n", res); 103 SAS_DPRINTK("executing SMP task failed:%d\n", res);
104 break; 104 break;
105 } 105 }
106 106
107 wait_for_completion(&task->completion); 107 wait_for_completion(&task->completion);
108 res = -ECOMM; 108 res = -ECOMM;
109 if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { 109 if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
110 SAS_DPRINTK("smp task timed out or aborted\n"); 110 SAS_DPRINTK("smp task timed out or aborted\n");
111 i->dft->lldd_abort_task(task); 111 i->dft->lldd_abort_task(task);
112 if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { 112 if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
113 SAS_DPRINTK("SMP task aborted and not done\n"); 113 SAS_DPRINTK("SMP task aborted and not done\n");
114 break; 114 break;
115 } 115 }
116 } 116 }
117 if (task->task_status.resp == SAS_TASK_COMPLETE && 117 if (task->task_status.resp == SAS_TASK_COMPLETE &&
118 task->task_status.stat == SAM_STAT_GOOD) { 118 task->task_status.stat == SAM_STAT_GOOD) {
119 res = 0; 119 res = 0;
120 break; 120 break;
121 } 121 }
122 if (task->task_status.resp == SAS_TASK_COMPLETE && 122 if (task->task_status.resp == SAS_TASK_COMPLETE &&
123 task->task_status.stat == SAS_DATA_UNDERRUN) { 123 task->task_status.stat == SAS_DATA_UNDERRUN) {
124 /* no error, but return the number of bytes of 124 /* no error, but return the number of bytes of
125 * underrun */ 125 * underrun */
126 res = task->task_status.residual; 126 res = task->task_status.residual;
127 break; 127 break;
128 } 128 }
129 if (task->task_status.resp == SAS_TASK_COMPLETE && 129 if (task->task_status.resp == SAS_TASK_COMPLETE &&
130 task->task_status.stat == SAS_DATA_OVERRUN) { 130 task->task_status.stat == SAS_DATA_OVERRUN) {
131 res = -EMSGSIZE; 131 res = -EMSGSIZE;
132 break; 132 break;
133 } 133 }
134 if (task->task_status.resp == SAS_TASK_UNDELIVERED && 134 if (task->task_status.resp == SAS_TASK_UNDELIVERED &&
135 task->task_status.stat == SAS_DEVICE_UNKNOWN) 135 task->task_status.stat == SAS_DEVICE_UNKNOWN)
136 break; 136 break;
137 else { 137 else {
138 SAS_DPRINTK("%s: task to dev %016llx response: 0x%x " 138 SAS_DPRINTK("%s: task to dev %016llx response: 0x%x "
139 "status 0x%x\n", __func__, 139 "status 0x%x\n", __func__,
140 SAS_ADDR(dev->sas_addr), 140 SAS_ADDR(dev->sas_addr),
141 task->task_status.resp, 141 task->task_status.resp,
142 task->task_status.stat); 142 task->task_status.stat);
143 sas_free_task(task); 143 sas_free_task(task);
144 task = NULL; 144 task = NULL;
145 } 145 }
146 } 146 }
147 mutex_unlock(&dev->ex_dev.cmd_mutex); 147 mutex_unlock(&dev->ex_dev.cmd_mutex);
148 148
149 BUG_ON(retry == 3 && task != NULL); 149 BUG_ON(retry == 3 && task != NULL);
150 sas_free_task(task); 150 sas_free_task(task);
151 return res; 151 return res;
152 } 152 }
153 153
154 /* ---------- Allocations ---------- */ 154 /* ---------- Allocations ---------- */
155 155
156 static inline void *alloc_smp_req(int size) 156 static inline void *alloc_smp_req(int size)
157 { 157 {
158 u8 *p = kzalloc(size, GFP_KERNEL); 158 u8 *p = kzalloc(size, GFP_KERNEL);
159 if (p) 159 if (p)
160 p[0] = SMP_REQUEST; 160 p[0] = SMP_REQUEST;
161 return p; 161 return p;
162 } 162 }
163 163
164 static inline void *alloc_smp_resp(int size) 164 static inline void *alloc_smp_resp(int size)
165 { 165 {
166 return kzalloc(size, GFP_KERNEL); 166 return kzalloc(size, GFP_KERNEL);
167 } 167 }
168 168
169 static char sas_route_char(struct domain_device *dev, struct ex_phy *phy) 169 static char sas_route_char(struct domain_device *dev, struct ex_phy *phy)
170 { 170 {
171 switch (phy->routing_attr) { 171 switch (phy->routing_attr) {
172 case TABLE_ROUTING: 172 case TABLE_ROUTING:
173 if (dev->ex_dev.t2t_supp) 173 if (dev->ex_dev.t2t_supp)
174 return 'U'; 174 return 'U';
175 else 175 else
176 return 'T'; 176 return 'T';
177 case DIRECT_ROUTING: 177 case DIRECT_ROUTING:
178 return 'D'; 178 return 'D';
179 case SUBTRACTIVE_ROUTING: 179 case SUBTRACTIVE_ROUTING:
180 return 'S'; 180 return 'S';
181 default: 181 default:
182 return '?'; 182 return '?';
183 } 183 }
184 } 184 }
185 185
186 static enum sas_dev_type to_dev_type(struct discover_resp *dr) 186 static enum sas_dev_type to_dev_type(struct discover_resp *dr)
187 { 187 {
188 /* This is detecting a failure to transmit initial dev to host 188 /* This is detecting a failure to transmit initial dev to host
189 * FIS as described in section J.5 of sas-2 r16 189 * FIS as described in section J.5 of sas-2 r16
190 */ 190 */
191 if (dr->attached_dev_type == NO_DEVICE && dr->attached_sata_dev && 191 if (dr->attached_dev_type == NO_DEVICE && dr->attached_sata_dev &&
192 dr->linkrate >= SAS_LINK_RATE_1_5_GBPS) 192 dr->linkrate >= SAS_LINK_RATE_1_5_GBPS)
193 return SATA_PENDING; 193 return SATA_PENDING;
194 else 194 else
195 return dr->attached_dev_type; 195 return dr->attached_dev_type;
196 } 196 }
197 197
198 static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) 198 static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
199 { 199 {
200 enum sas_dev_type dev_type; 200 enum sas_dev_type dev_type;
201 enum sas_linkrate linkrate; 201 enum sas_linkrate linkrate;
202 u8 sas_addr[SAS_ADDR_SIZE]; 202 u8 sas_addr[SAS_ADDR_SIZE];
203 struct smp_resp *resp = rsp; 203 struct smp_resp *resp = rsp;
204 struct discover_resp *dr = &resp->disc; 204 struct discover_resp *dr = &resp->disc;
205 struct expander_device *ex = &dev->ex_dev; 205 struct expander_device *ex = &dev->ex_dev;
206 struct ex_phy *phy = &ex->ex_phy[phy_id]; 206 struct ex_phy *phy = &ex->ex_phy[phy_id];
207 struct sas_rphy *rphy = dev->rphy; 207 struct sas_rphy *rphy = dev->rphy;
208 bool new_phy = !phy->phy; 208 bool new_phy = !phy->phy;
209 char *type; 209 char *type;
210 210
211 if (new_phy) { 211 if (new_phy) {
212 phy->phy = sas_phy_alloc(&rphy->dev, phy_id); 212 phy->phy = sas_phy_alloc(&rphy->dev, phy_id);
213 213
214 /* FIXME: error_handling */ 214 /* FIXME: error_handling */
215 BUG_ON(!phy->phy); 215 BUG_ON(!phy->phy);
216 } 216 }
217 217
218 switch (resp->result) { 218 switch (resp->result) {
219 case SMP_RESP_PHY_VACANT: 219 case SMP_RESP_PHY_VACANT:
220 phy->phy_state = PHY_VACANT; 220 phy->phy_state = PHY_VACANT;
221 break; 221 break;
222 default: 222 default:
223 phy->phy_state = PHY_NOT_PRESENT; 223 phy->phy_state = PHY_NOT_PRESENT;
224 break; 224 break;
225 case SMP_RESP_FUNC_ACC: 225 case SMP_RESP_FUNC_ACC:
226 phy->phy_state = PHY_EMPTY; /* do not know yet */ 226 phy->phy_state = PHY_EMPTY; /* do not know yet */
227 break; 227 break;
228 } 228 }
229 229
230 /* check if anything important changed to squelch debug */ 230 /* check if anything important changed to squelch debug */
231 dev_type = phy->attached_dev_type; 231 dev_type = phy->attached_dev_type;
232 linkrate = phy->linkrate; 232 linkrate = phy->linkrate;
233 memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); 233 memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
234 234
235 phy->attached_dev_type = to_dev_type(dr); 235 phy->attached_dev_type = to_dev_type(dr);
236 phy->phy_id = phy_id; 236 phy->phy_id = phy_id;
237 phy->linkrate = dr->linkrate; 237 phy->linkrate = dr->linkrate;
238 phy->attached_sata_host = dr->attached_sata_host; 238 phy->attached_sata_host = dr->attached_sata_host;
239 phy->attached_sata_dev = dr->attached_sata_dev; 239 phy->attached_sata_dev = dr->attached_sata_dev;
240 phy->attached_sata_ps = dr->attached_sata_ps; 240 phy->attached_sata_ps = dr->attached_sata_ps;
241 phy->attached_iproto = dr->iproto << 1; 241 phy->attached_iproto = dr->iproto << 1;
242 phy->attached_tproto = dr->tproto << 1; 242 phy->attached_tproto = dr->tproto << 1;
243 memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE); 243 memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE);
244 phy->attached_phy_id = dr->attached_phy_id; 244 phy->attached_phy_id = dr->attached_phy_id;
245 phy->phy_change_count = dr->change_count; 245 phy->phy_change_count = dr->change_count;
246 phy->routing_attr = dr->routing_attr; 246 phy->routing_attr = dr->routing_attr;
247 phy->virtual = dr->virtual; 247 phy->virtual = dr->virtual;
248 phy->last_da_index = -1; 248 phy->last_da_index = -1;
249 249
250 phy->phy->identify.sas_address = SAS_ADDR(phy->attached_sas_addr); 250 phy->phy->identify.sas_address = SAS_ADDR(phy->attached_sas_addr);
251 phy->phy->identify.device_type = dr->attached_dev_type; 251 phy->phy->identify.device_type = dr->attached_dev_type;
252 phy->phy->identify.initiator_port_protocols = phy->attached_iproto; 252 phy->phy->identify.initiator_port_protocols = phy->attached_iproto;
253 phy->phy->identify.target_port_protocols = phy->attached_tproto; 253 phy->phy->identify.target_port_protocols = phy->attached_tproto;
254 if (!phy->attached_tproto && dr->attached_sata_dev)
255 phy->phy->identify.target_port_protocols = SAS_PROTOCOL_SATA;
254 phy->phy->identify.phy_identifier = phy_id; 256 phy->phy->identify.phy_identifier = phy_id;
255 phy->phy->minimum_linkrate_hw = dr->hmin_linkrate; 257 phy->phy->minimum_linkrate_hw = dr->hmin_linkrate;
256 phy->phy->maximum_linkrate_hw = dr->hmax_linkrate; 258 phy->phy->maximum_linkrate_hw = dr->hmax_linkrate;
257 phy->phy->minimum_linkrate = dr->pmin_linkrate; 259 phy->phy->minimum_linkrate = dr->pmin_linkrate;
258 phy->phy->maximum_linkrate = dr->pmax_linkrate; 260 phy->phy->maximum_linkrate = dr->pmax_linkrate;
259 phy->phy->negotiated_linkrate = phy->linkrate; 261 phy->phy->negotiated_linkrate = phy->linkrate;
260 262
261 if (new_phy) 263 if (new_phy)
262 if (sas_phy_add(phy->phy)) { 264 if (sas_phy_add(phy->phy)) {
263 sas_phy_free(phy->phy); 265 sas_phy_free(phy->phy);
264 return; 266 return;
265 } 267 }
266 268
267 switch (phy->attached_dev_type) { 269 switch (phy->attached_dev_type) {
268 case SATA_PENDING: 270 case SATA_PENDING:
269 type = "stp pending"; 271 type = "stp pending";
270 break; 272 break;
271 case NO_DEVICE: 273 case NO_DEVICE:
272 type = "no device"; 274 type = "no device";
273 break; 275 break;
274 case SAS_END_DEV: 276 case SAS_END_DEV:
275 if (phy->attached_iproto) { 277 if (phy->attached_iproto) {
276 if (phy->attached_tproto) 278 if (phy->attached_tproto)
277 type = "host+target"; 279 type = "host+target";
278 else 280 else
279 type = "host"; 281 type = "host";
280 } else { 282 } else {
281 if (dr->attached_sata_dev) 283 if (dr->attached_sata_dev)
282 type = "stp"; 284 type = "stp";
283 else 285 else
284 type = "ssp"; 286 type = "ssp";
285 } 287 }
286 break; 288 break;
287 case EDGE_DEV: 289 case EDGE_DEV:
288 case FANOUT_DEV: 290 case FANOUT_DEV:
289 type = "smp"; 291 type = "smp";
290 break; 292 break;
291 default: 293 default:
292 type = "unknown"; 294 type = "unknown";
293 } 295 }
294 296
295 /* this routine is polled by libata error recovery so filter 297 /* this routine is polled by libata error recovery so filter
296 * unimportant messages 298 * unimportant messages
297 */ 299 */
298 if (new_phy || phy->attached_dev_type != dev_type || 300 if (new_phy || phy->attached_dev_type != dev_type ||
299 phy->linkrate != linkrate || 301 phy->linkrate != linkrate ||
300 SAS_ADDR(phy->attached_sas_addr) != SAS_ADDR(sas_addr)) 302 SAS_ADDR(phy->attached_sas_addr) != SAS_ADDR(sas_addr))
301 /* pass */; 303 /* pass */;
302 else 304 else
303 return; 305 return;
304 306
305 SAS_DPRINTK("ex %016llx phy%02d:%c:%X attached: %016llx (%s)\n", 307 SAS_DPRINTK("ex %016llx phy%02d:%c:%X attached: %016llx (%s)\n",
306 SAS_ADDR(dev->sas_addr), phy->phy_id, 308 SAS_ADDR(dev->sas_addr), phy->phy_id,
307 sas_route_char(dev, phy), phy->linkrate, 309 sas_route_char(dev, phy), phy->linkrate,
308 SAS_ADDR(phy->attached_sas_addr), type); 310 SAS_ADDR(phy->attached_sas_addr), type);
309 } 311 }
310 312
311 /* check if we have an existing attached ata device on this expander phy */ 313 /* check if we have an existing attached ata device on this expander phy */
312 struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id) 314 struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id)
313 { 315 {
314 struct ex_phy *ex_phy = &ex_dev->ex_dev.ex_phy[phy_id]; 316 struct ex_phy *ex_phy = &ex_dev->ex_dev.ex_phy[phy_id];
315 struct domain_device *dev; 317 struct domain_device *dev;
316 struct sas_rphy *rphy; 318 struct sas_rphy *rphy;
317 319
318 if (!ex_phy->port) 320 if (!ex_phy->port)
319 return NULL; 321 return NULL;
320 322
321 rphy = ex_phy->port->rphy; 323 rphy = ex_phy->port->rphy;
322 if (!rphy) 324 if (!rphy)
323 return NULL; 325 return NULL;
324 326
325 dev = sas_find_dev_by_rphy(rphy); 327 dev = sas_find_dev_by_rphy(rphy);
326 328
327 if (dev && dev_is_sata(dev)) 329 if (dev && dev_is_sata(dev))
328 return dev; 330 return dev;
329 331
330 return NULL; 332 return NULL;
331 } 333 }
332 334
333 #define DISCOVER_REQ_SIZE 16 335 #define DISCOVER_REQ_SIZE 16
334 #define DISCOVER_RESP_SIZE 56 336 #define DISCOVER_RESP_SIZE 56
335 337
336 static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req, 338 static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req,
337 u8 *disc_resp, int single) 339 u8 *disc_resp, int single)
338 { 340 {
339 struct discover_resp *dr; 341 struct discover_resp *dr;
340 int res; 342 int res;
341 343
342 disc_req[9] = single; 344 disc_req[9] = single;
343 345
344 res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE, 346 res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
345 disc_resp, DISCOVER_RESP_SIZE); 347 disc_resp, DISCOVER_RESP_SIZE);
346 if (res) 348 if (res)
347 return res; 349 return res;
348 dr = &((struct smp_resp *)disc_resp)->disc; 350 dr = &((struct smp_resp *)disc_resp)->disc;
349 if (memcmp(dev->sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE) == 0) { 351 if (memcmp(dev->sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE) == 0) {
350 sas_printk("Found loopback topology, just ignore it!\n"); 352 sas_printk("Found loopback topology, just ignore it!\n");
351 return 0; 353 return 0;
352 } 354 }
353 sas_set_ex_phy(dev, single, disc_resp); 355 sas_set_ex_phy(dev, single, disc_resp);
354 return 0; 356 return 0;
355 } 357 }
356 358
357 int sas_ex_phy_discover(struct domain_device *dev, int single) 359 int sas_ex_phy_discover(struct domain_device *dev, int single)
358 { 360 {
359 struct expander_device *ex = &dev->ex_dev; 361 struct expander_device *ex = &dev->ex_dev;
360 int res = 0; 362 int res = 0;
361 u8 *disc_req; 363 u8 *disc_req;
362 u8 *disc_resp; 364 u8 *disc_resp;
363 365
364 disc_req = alloc_smp_req(DISCOVER_REQ_SIZE); 366 disc_req = alloc_smp_req(DISCOVER_REQ_SIZE);
365 if (!disc_req) 367 if (!disc_req)
366 return -ENOMEM; 368 return -ENOMEM;
367 369
368 disc_resp = alloc_smp_req(DISCOVER_RESP_SIZE); 370 disc_resp = alloc_smp_req(DISCOVER_RESP_SIZE);
369 if (!disc_resp) { 371 if (!disc_resp) {
370 kfree(disc_req); 372 kfree(disc_req);
371 return -ENOMEM; 373 return -ENOMEM;
372 } 374 }
373 375
374 disc_req[1] = SMP_DISCOVER; 376 disc_req[1] = SMP_DISCOVER;
375 377
376 if (0 <= single && single < ex->num_phys) { 378 if (0 <= single && single < ex->num_phys) {
377 res = sas_ex_phy_discover_helper(dev, disc_req, disc_resp, single); 379 res = sas_ex_phy_discover_helper(dev, disc_req, disc_resp, single);
378 } else { 380 } else {
379 int i; 381 int i;
380 382
381 for (i = 0; i < ex->num_phys; i++) { 383 for (i = 0; i < ex->num_phys; i++) {
382 res = sas_ex_phy_discover_helper(dev, disc_req, 384 res = sas_ex_phy_discover_helper(dev, disc_req,
383 disc_resp, i); 385 disc_resp, i);
384 if (res) 386 if (res)
385 goto out_err; 387 goto out_err;
386 } 388 }
387 } 389 }
388 out_err: 390 out_err:
389 kfree(disc_resp); 391 kfree(disc_resp);
390 kfree(disc_req); 392 kfree(disc_req);
391 return res; 393 return res;
392 } 394 }
393 395
394 static int sas_expander_discover(struct domain_device *dev) 396 static int sas_expander_discover(struct domain_device *dev)
395 { 397 {
396 struct expander_device *ex = &dev->ex_dev; 398 struct expander_device *ex = &dev->ex_dev;
397 int res = -ENOMEM; 399 int res = -ENOMEM;
398 400
399 ex->ex_phy = kzalloc(sizeof(*ex->ex_phy)*ex->num_phys, GFP_KERNEL); 401 ex->ex_phy = kzalloc(sizeof(*ex->ex_phy)*ex->num_phys, GFP_KERNEL);
400 if (!ex->ex_phy) 402 if (!ex->ex_phy)
401 return -ENOMEM; 403 return -ENOMEM;
402 404
403 res = sas_ex_phy_discover(dev, -1); 405 res = sas_ex_phy_discover(dev, -1);
404 if (res) 406 if (res)
405 goto out_err; 407 goto out_err;
406 408
407 return 0; 409 return 0;
408 out_err: 410 out_err:
409 kfree(ex->ex_phy); 411 kfree(ex->ex_phy);
410 ex->ex_phy = NULL; 412 ex->ex_phy = NULL;
411 return res; 413 return res;
412 } 414 }
413 415
414 #define MAX_EXPANDER_PHYS 128 416 #define MAX_EXPANDER_PHYS 128
415 417
416 static void ex_assign_report_general(struct domain_device *dev, 418 static void ex_assign_report_general(struct domain_device *dev,
417 struct smp_resp *resp) 419 struct smp_resp *resp)
418 { 420 {
419 struct report_general_resp *rg = &resp->rg; 421 struct report_general_resp *rg = &resp->rg;
420 422
421 dev->ex_dev.ex_change_count = be16_to_cpu(rg->change_count); 423 dev->ex_dev.ex_change_count = be16_to_cpu(rg->change_count);
422 dev->ex_dev.max_route_indexes = be16_to_cpu(rg->route_indexes); 424 dev->ex_dev.max_route_indexes = be16_to_cpu(rg->route_indexes);
423 dev->ex_dev.num_phys = min(rg->num_phys, (u8)MAX_EXPANDER_PHYS); 425 dev->ex_dev.num_phys = min(rg->num_phys, (u8)MAX_EXPANDER_PHYS);
424 dev->ex_dev.t2t_supp = rg->t2t_supp; 426 dev->ex_dev.t2t_supp = rg->t2t_supp;
425 dev->ex_dev.conf_route_table = rg->conf_route_table; 427 dev->ex_dev.conf_route_table = rg->conf_route_table;
426 dev->ex_dev.configuring = rg->configuring; 428 dev->ex_dev.configuring = rg->configuring;
427 memcpy(dev->ex_dev.enclosure_logical_id, rg->enclosure_logical_id, 8); 429 memcpy(dev->ex_dev.enclosure_logical_id, rg->enclosure_logical_id, 8);
428 } 430 }
429 431
430 #define RG_REQ_SIZE 8 432 #define RG_REQ_SIZE 8
431 #define RG_RESP_SIZE 32 433 #define RG_RESP_SIZE 32
432 434
433 static int sas_ex_general(struct domain_device *dev) 435 static int sas_ex_general(struct domain_device *dev)
434 { 436 {
435 u8 *rg_req; 437 u8 *rg_req;
436 struct smp_resp *rg_resp; 438 struct smp_resp *rg_resp;
437 int res; 439 int res;
438 int i; 440 int i;
439 441
440 rg_req = alloc_smp_req(RG_REQ_SIZE); 442 rg_req = alloc_smp_req(RG_REQ_SIZE);
441 if (!rg_req) 443 if (!rg_req)
442 return -ENOMEM; 444 return -ENOMEM;
443 445
444 rg_resp = alloc_smp_resp(RG_RESP_SIZE); 446 rg_resp = alloc_smp_resp(RG_RESP_SIZE);
445 if (!rg_resp) { 447 if (!rg_resp) {
446 kfree(rg_req); 448 kfree(rg_req);
447 return -ENOMEM; 449 return -ENOMEM;
448 } 450 }
449 451
450 rg_req[1] = SMP_REPORT_GENERAL; 452 rg_req[1] = SMP_REPORT_GENERAL;
451 453
452 for (i = 0; i < 5; i++) { 454 for (i = 0; i < 5; i++) {
453 res = smp_execute_task(dev, rg_req, RG_REQ_SIZE, rg_resp, 455 res = smp_execute_task(dev, rg_req, RG_REQ_SIZE, rg_resp,
454 RG_RESP_SIZE); 456 RG_RESP_SIZE);
455 457
456 if (res) { 458 if (res) {
457 SAS_DPRINTK("RG to ex %016llx failed:0x%x\n", 459 SAS_DPRINTK("RG to ex %016llx failed:0x%x\n",
458 SAS_ADDR(dev->sas_addr), res); 460 SAS_ADDR(dev->sas_addr), res);
459 goto out; 461 goto out;
460 } else if (rg_resp->result != SMP_RESP_FUNC_ACC) { 462 } else if (rg_resp->result != SMP_RESP_FUNC_ACC) {
461 SAS_DPRINTK("RG:ex %016llx returned SMP result:0x%x\n", 463 SAS_DPRINTK("RG:ex %016llx returned SMP result:0x%x\n",
462 SAS_ADDR(dev->sas_addr), rg_resp->result); 464 SAS_ADDR(dev->sas_addr), rg_resp->result);
463 res = rg_resp->result; 465 res = rg_resp->result;
464 goto out; 466 goto out;
465 } 467 }
466 468
467 ex_assign_report_general(dev, rg_resp); 469 ex_assign_report_general(dev, rg_resp);
468 470
469 if (dev->ex_dev.configuring) { 471 if (dev->ex_dev.configuring) {
470 SAS_DPRINTK("RG: ex %llx self-configuring...\n", 472 SAS_DPRINTK("RG: ex %llx self-configuring...\n",
471 SAS_ADDR(dev->sas_addr)); 473 SAS_ADDR(dev->sas_addr));
472 schedule_timeout_interruptible(5*HZ); 474 schedule_timeout_interruptible(5*HZ);
473 } else 475 } else
474 break; 476 break;
475 } 477 }
476 out: 478 out:
477 kfree(rg_req); 479 kfree(rg_req);
478 kfree(rg_resp); 480 kfree(rg_resp);
479 return res; 481 return res;
480 } 482 }
481 483
482 static void ex_assign_manuf_info(struct domain_device *dev, void 484 static void ex_assign_manuf_info(struct domain_device *dev, void
483 *_mi_resp) 485 *_mi_resp)
484 { 486 {
485 u8 *mi_resp = _mi_resp; 487 u8 *mi_resp = _mi_resp;
486 struct sas_rphy *rphy = dev->rphy; 488 struct sas_rphy *rphy = dev->rphy;
487 struct sas_expander_device *edev = rphy_to_expander_device(rphy); 489 struct sas_expander_device *edev = rphy_to_expander_device(rphy);
488 490
489 memcpy(edev->vendor_id, mi_resp + 12, SAS_EXPANDER_VENDOR_ID_LEN); 491 memcpy(edev->vendor_id, mi_resp + 12, SAS_EXPANDER_VENDOR_ID_LEN);
490 memcpy(edev->product_id, mi_resp + 20, SAS_EXPANDER_PRODUCT_ID_LEN); 492 memcpy(edev->product_id, mi_resp + 20, SAS_EXPANDER_PRODUCT_ID_LEN);
491 memcpy(edev->product_rev, mi_resp + 36, 493 memcpy(edev->product_rev, mi_resp + 36,
492 SAS_EXPANDER_PRODUCT_REV_LEN); 494 SAS_EXPANDER_PRODUCT_REV_LEN);
493 495
494 if (mi_resp[8] & 1) { 496 if (mi_resp[8] & 1) {
495 memcpy(edev->component_vendor_id, mi_resp + 40, 497 memcpy(edev->component_vendor_id, mi_resp + 40,
496 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); 498 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
497 edev->component_id = mi_resp[48] << 8 | mi_resp[49]; 499 edev->component_id = mi_resp[48] << 8 | mi_resp[49];
498 edev->component_revision_id = mi_resp[50]; 500 edev->component_revision_id = mi_resp[50];
499 } 501 }
500 } 502 }
501 503
502 #define MI_REQ_SIZE 8 504 #define MI_REQ_SIZE 8
503 #define MI_RESP_SIZE 64 505 #define MI_RESP_SIZE 64
504 506
505 static int sas_ex_manuf_info(struct domain_device *dev) 507 static int sas_ex_manuf_info(struct domain_device *dev)
506 { 508 {
507 u8 *mi_req; 509 u8 *mi_req;
508 u8 *mi_resp; 510 u8 *mi_resp;
509 int res; 511 int res;
510 512
511 mi_req = alloc_smp_req(MI_REQ_SIZE); 513 mi_req = alloc_smp_req(MI_REQ_SIZE);
512 if (!mi_req) 514 if (!mi_req)
513 return -ENOMEM; 515 return -ENOMEM;
514 516
515 mi_resp = alloc_smp_resp(MI_RESP_SIZE); 517 mi_resp = alloc_smp_resp(MI_RESP_SIZE);
516 if (!mi_resp) { 518 if (!mi_resp) {
517 kfree(mi_req); 519 kfree(mi_req);
518 return -ENOMEM; 520 return -ENOMEM;
519 } 521 }
520 522
521 mi_req[1] = SMP_REPORT_MANUF_INFO; 523 mi_req[1] = SMP_REPORT_MANUF_INFO;
522 524
523 res = smp_execute_task(dev, mi_req, MI_REQ_SIZE, mi_resp,MI_RESP_SIZE); 525 res = smp_execute_task(dev, mi_req, MI_REQ_SIZE, mi_resp,MI_RESP_SIZE);
524 if (res) { 526 if (res) {
525 SAS_DPRINTK("MI: ex %016llx failed:0x%x\n", 527 SAS_DPRINTK("MI: ex %016llx failed:0x%x\n",
526 SAS_ADDR(dev->sas_addr), res); 528 SAS_ADDR(dev->sas_addr), res);
527 goto out; 529 goto out;
528 } else if (mi_resp[2] != SMP_RESP_FUNC_ACC) { 530 } else if (mi_resp[2] != SMP_RESP_FUNC_ACC) {
529 SAS_DPRINTK("MI ex %016llx returned SMP result:0x%x\n", 531 SAS_DPRINTK("MI ex %016llx returned SMP result:0x%x\n",
530 SAS_ADDR(dev->sas_addr), mi_resp[2]); 532 SAS_ADDR(dev->sas_addr), mi_resp[2]);
531 goto out; 533 goto out;
532 } 534 }
533 535
534 ex_assign_manuf_info(dev, mi_resp); 536 ex_assign_manuf_info(dev, mi_resp);
535 out: 537 out:
536 kfree(mi_req); 538 kfree(mi_req);
537 kfree(mi_resp); 539 kfree(mi_resp);
538 return res; 540 return res;
539 } 541 }
540 542
541 #define PC_REQ_SIZE 44 543 #define PC_REQ_SIZE 44
542 #define PC_RESP_SIZE 8 544 #define PC_RESP_SIZE 8
543 545
544 int sas_smp_phy_control(struct domain_device *dev, int phy_id, 546 int sas_smp_phy_control(struct domain_device *dev, int phy_id,
545 enum phy_func phy_func, 547 enum phy_func phy_func,
546 struct sas_phy_linkrates *rates) 548 struct sas_phy_linkrates *rates)
547 { 549 {
548 u8 *pc_req; 550 u8 *pc_req;
549 u8 *pc_resp; 551 u8 *pc_resp;
550 int res; 552 int res;
551 553
552 pc_req = alloc_smp_req(PC_REQ_SIZE); 554 pc_req = alloc_smp_req(PC_REQ_SIZE);
553 if (!pc_req) 555 if (!pc_req)
554 return -ENOMEM; 556 return -ENOMEM;
555 557
556 pc_resp = alloc_smp_resp(PC_RESP_SIZE); 558 pc_resp = alloc_smp_resp(PC_RESP_SIZE);
557 if (!pc_resp) { 559 if (!pc_resp) {
558 kfree(pc_req); 560 kfree(pc_req);
559 return -ENOMEM; 561 return -ENOMEM;
560 } 562 }
561 563
562 pc_req[1] = SMP_PHY_CONTROL; 564 pc_req[1] = SMP_PHY_CONTROL;
563 pc_req[9] = phy_id; 565 pc_req[9] = phy_id;
564 pc_req[10]= phy_func; 566 pc_req[10]= phy_func;
565 if (rates) { 567 if (rates) {
566 pc_req[32] = rates->minimum_linkrate << 4; 568 pc_req[32] = rates->minimum_linkrate << 4;
567 pc_req[33] = rates->maximum_linkrate << 4; 569 pc_req[33] = rates->maximum_linkrate << 4;
568 } 570 }
569 571
570 res = smp_execute_task(dev, pc_req, PC_REQ_SIZE, pc_resp,PC_RESP_SIZE); 572 res = smp_execute_task(dev, pc_req, PC_REQ_SIZE, pc_resp,PC_RESP_SIZE);
571 573
572 kfree(pc_resp); 574 kfree(pc_resp);
573 kfree(pc_req); 575 kfree(pc_req);
574 return res; 576 return res;
575 } 577 }
576 578
577 static void sas_ex_disable_phy(struct domain_device *dev, int phy_id) 579 static void sas_ex_disable_phy(struct domain_device *dev, int phy_id)
578 { 580 {
579 struct expander_device *ex = &dev->ex_dev; 581 struct expander_device *ex = &dev->ex_dev;
580 struct ex_phy *phy = &ex->ex_phy[phy_id]; 582 struct ex_phy *phy = &ex->ex_phy[phy_id];
581 583
582 sas_smp_phy_control(dev, phy_id, PHY_FUNC_DISABLE, NULL); 584 sas_smp_phy_control(dev, phy_id, PHY_FUNC_DISABLE, NULL);
583 phy->linkrate = SAS_PHY_DISABLED; 585 phy->linkrate = SAS_PHY_DISABLED;
584 } 586 }
585 587
586 static void sas_ex_disable_port(struct domain_device *dev, u8 *sas_addr) 588 static void sas_ex_disable_port(struct domain_device *dev, u8 *sas_addr)
587 { 589 {
588 struct expander_device *ex = &dev->ex_dev; 590 struct expander_device *ex = &dev->ex_dev;
589 int i; 591 int i;
590 592
591 for (i = 0; i < ex->num_phys; i++) { 593 for (i = 0; i < ex->num_phys; i++) {
592 struct ex_phy *phy = &ex->ex_phy[i]; 594 struct ex_phy *phy = &ex->ex_phy[i];
593 595
594 if (phy->phy_state == PHY_VACANT || 596 if (phy->phy_state == PHY_VACANT ||
595 phy->phy_state == PHY_NOT_PRESENT) 597 phy->phy_state == PHY_NOT_PRESENT)
596 continue; 598 continue;
597 599
598 if (SAS_ADDR(phy->attached_sas_addr) == SAS_ADDR(sas_addr)) 600 if (SAS_ADDR(phy->attached_sas_addr) == SAS_ADDR(sas_addr))
599 sas_ex_disable_phy(dev, i); 601 sas_ex_disable_phy(dev, i);
600 } 602 }
601 } 603 }
602 604
603 static int sas_dev_present_in_domain(struct asd_sas_port *port, 605 static int sas_dev_present_in_domain(struct asd_sas_port *port,
604 u8 *sas_addr) 606 u8 *sas_addr)
605 { 607 {
606 struct domain_device *dev; 608 struct domain_device *dev;
607 609
608 if (SAS_ADDR(port->sas_addr) == SAS_ADDR(sas_addr)) 610 if (SAS_ADDR(port->sas_addr) == SAS_ADDR(sas_addr))
609 return 1; 611 return 1;
610 list_for_each_entry(dev, &port->dev_list, dev_list_node) { 612 list_for_each_entry(dev, &port->dev_list, dev_list_node) {
611 if (SAS_ADDR(dev->sas_addr) == SAS_ADDR(sas_addr)) 613 if (SAS_ADDR(dev->sas_addr) == SAS_ADDR(sas_addr))
612 return 1; 614 return 1;
613 } 615 }
614 return 0; 616 return 0;
615 } 617 }
616 618
617 #define RPEL_REQ_SIZE 16 619 #define RPEL_REQ_SIZE 16
618 #define RPEL_RESP_SIZE 32 620 #define RPEL_RESP_SIZE 32
619 int sas_smp_get_phy_events(struct sas_phy *phy) 621 int sas_smp_get_phy_events(struct sas_phy *phy)
620 { 622 {
621 int res; 623 int res;
622 u8 *req; 624 u8 *req;
623 u8 *resp; 625 u8 *resp;
624 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent); 626 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
625 struct domain_device *dev = sas_find_dev_by_rphy(rphy); 627 struct domain_device *dev = sas_find_dev_by_rphy(rphy);
626 628
627 req = alloc_smp_req(RPEL_REQ_SIZE); 629 req = alloc_smp_req(RPEL_REQ_SIZE);
628 if (!req) 630 if (!req)
629 return -ENOMEM; 631 return -ENOMEM;
630 632
631 resp = alloc_smp_resp(RPEL_RESP_SIZE); 633 resp = alloc_smp_resp(RPEL_RESP_SIZE);
632 if (!resp) { 634 if (!resp) {
633 kfree(req); 635 kfree(req);
634 return -ENOMEM; 636 return -ENOMEM;
635 } 637 }
636 638
637 req[1] = SMP_REPORT_PHY_ERR_LOG; 639 req[1] = SMP_REPORT_PHY_ERR_LOG;
638 req[9] = phy->number; 640 req[9] = phy->number;
639 641
640 res = smp_execute_task(dev, req, RPEL_REQ_SIZE, 642 res = smp_execute_task(dev, req, RPEL_REQ_SIZE,
641 resp, RPEL_RESP_SIZE); 643 resp, RPEL_RESP_SIZE);
642 644
643 if (!res) 645 if (!res)
644 goto out; 646 goto out;
645 647
646 phy->invalid_dword_count = scsi_to_u32(&resp[12]); 648 phy->invalid_dword_count = scsi_to_u32(&resp[12]);
647 phy->running_disparity_error_count = scsi_to_u32(&resp[16]); 649 phy->running_disparity_error_count = scsi_to_u32(&resp[16]);
648 phy->loss_of_dword_sync_count = scsi_to_u32(&resp[20]); 650 phy->loss_of_dword_sync_count = scsi_to_u32(&resp[20]);
649 phy->phy_reset_problem_count = scsi_to_u32(&resp[24]); 651 phy->phy_reset_problem_count = scsi_to_u32(&resp[24]);
650 652
651 out: 653 out:
652 kfree(resp); 654 kfree(resp);
653 return res; 655 return res;
654 656
655 } 657 }
656 658
657 #ifdef CONFIG_SCSI_SAS_ATA 659 #ifdef CONFIG_SCSI_SAS_ATA
658 660
659 #define RPS_REQ_SIZE 16 661 #define RPS_REQ_SIZE 16
660 #define RPS_RESP_SIZE 60 662 #define RPS_RESP_SIZE 60
661 663
662 int sas_get_report_phy_sata(struct domain_device *dev, int phy_id, 664 int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
663 struct smp_resp *rps_resp) 665 struct smp_resp *rps_resp)
664 { 666 {
665 int res; 667 int res;
666 u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE); 668 u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE);
667 u8 *resp = (u8 *)rps_resp; 669 u8 *resp = (u8 *)rps_resp;
668 670
669 if (!rps_req) 671 if (!rps_req)
670 return -ENOMEM; 672 return -ENOMEM;
671 673
672 rps_req[1] = SMP_REPORT_PHY_SATA; 674 rps_req[1] = SMP_REPORT_PHY_SATA;
673 rps_req[9] = phy_id; 675 rps_req[9] = phy_id;
674 676
675 res = smp_execute_task(dev, rps_req, RPS_REQ_SIZE, 677 res = smp_execute_task(dev, rps_req, RPS_REQ_SIZE,
676 rps_resp, RPS_RESP_SIZE); 678 rps_resp, RPS_RESP_SIZE);
677 679
678 /* 0x34 is the FIS type for the D2H fis. There's a potential 680 /* 0x34 is the FIS type for the D2H fis. There's a potential
679 * standards cockup here. sas-2 explicitly specifies the FIS 681 * standards cockup here. sas-2 explicitly specifies the FIS
680 * should be encoded so that FIS type is in resp[24]. 682 * should be encoded so that FIS type is in resp[24].
681 * However, some expanders endian reverse this. Undo the 683 * However, some expanders endian reverse this. Undo the
682 * reversal here */ 684 * reversal here */
683 if (!res && resp[27] == 0x34 && resp[24] != 0x34) { 685 if (!res && resp[27] == 0x34 && resp[24] != 0x34) {
684 int i; 686 int i;
685 687
686 for (i = 0; i < 5; i++) { 688 for (i = 0; i < 5; i++) {
687 int j = 24 + (i*4); 689 int j = 24 + (i*4);
688 u8 a, b; 690 u8 a, b;
689 a = resp[j + 0]; 691 a = resp[j + 0];
690 b = resp[j + 1]; 692 b = resp[j + 1];
691 resp[j + 0] = resp[j + 3]; 693 resp[j + 0] = resp[j + 3];
692 resp[j + 1] = resp[j + 2]; 694 resp[j + 1] = resp[j + 2];
693 resp[j + 2] = b; 695 resp[j + 2] = b;
694 resp[j + 3] = a; 696 resp[j + 3] = a;
695 } 697 }
696 } 698 }
697 699
698 kfree(rps_req); 700 kfree(rps_req);
699 return res; 701 return res;
700 } 702 }
701 #endif 703 #endif
702 704
703 static void sas_ex_get_linkrate(struct domain_device *parent, 705 static void sas_ex_get_linkrate(struct domain_device *parent,
704 struct domain_device *child, 706 struct domain_device *child,
705 struct ex_phy *parent_phy) 707 struct ex_phy *parent_phy)
706 { 708 {
707 struct expander_device *parent_ex = &parent->ex_dev; 709 struct expander_device *parent_ex = &parent->ex_dev;
708 struct sas_port *port; 710 struct sas_port *port;
709 int i; 711 int i;
710 712
711 child->pathways = 0; 713 child->pathways = 0;
712 714
713 port = parent_phy->port; 715 port = parent_phy->port;
714 716
715 for (i = 0; i < parent_ex->num_phys; i++) { 717 for (i = 0; i < parent_ex->num_phys; i++) {
716 struct ex_phy *phy = &parent_ex->ex_phy[i]; 718 struct ex_phy *phy = &parent_ex->ex_phy[i];
717 719
718 if (phy->phy_state == PHY_VACANT || 720 if (phy->phy_state == PHY_VACANT ||
719 phy->phy_state == PHY_NOT_PRESENT) 721 phy->phy_state == PHY_NOT_PRESENT)
720 continue; 722 continue;
721 723
722 if (SAS_ADDR(phy->attached_sas_addr) == 724 if (SAS_ADDR(phy->attached_sas_addr) ==
723 SAS_ADDR(child->sas_addr)) { 725 SAS_ADDR(child->sas_addr)) {
724 726
725 child->min_linkrate = min(parent->min_linkrate, 727 child->min_linkrate = min(parent->min_linkrate,
726 phy->linkrate); 728 phy->linkrate);
727 child->max_linkrate = max(parent->max_linkrate, 729 child->max_linkrate = max(parent->max_linkrate,
728 phy->linkrate); 730 phy->linkrate);
729 child->pathways++; 731 child->pathways++;
730 sas_port_add_phy(port, phy->phy); 732 sas_port_add_phy(port, phy->phy);
731 } 733 }
732 } 734 }
733 child->linkrate = min(parent_phy->linkrate, child->max_linkrate); 735 child->linkrate = min(parent_phy->linkrate, child->max_linkrate);
734 child->pathways = min(child->pathways, parent->pathways); 736 child->pathways = min(child->pathways, parent->pathways);
735 } 737 }
736 738
737 static struct domain_device *sas_ex_discover_end_dev( 739 static struct domain_device *sas_ex_discover_end_dev(
738 struct domain_device *parent, int phy_id) 740 struct domain_device *parent, int phy_id)
739 { 741 {
740 struct expander_device *parent_ex = &parent->ex_dev; 742 struct expander_device *parent_ex = &parent->ex_dev;
741 struct ex_phy *phy = &parent_ex->ex_phy[phy_id]; 743 struct ex_phy *phy = &parent_ex->ex_phy[phy_id];
742 struct domain_device *child = NULL; 744 struct domain_device *child = NULL;
743 struct sas_rphy *rphy; 745 struct sas_rphy *rphy;
744 int res; 746 int res;
745 747
746 if (phy->attached_sata_host || phy->attached_sata_ps) 748 if (phy->attached_sata_host || phy->attached_sata_ps)
747 return NULL; 749 return NULL;
748 750
749 child = sas_alloc_device(); 751 child = sas_alloc_device();
750 if (!child) 752 if (!child)
751 return NULL; 753 return NULL;
752 754
753 kref_get(&parent->kref); 755 kref_get(&parent->kref);
754 child->parent = parent; 756 child->parent = parent;
755 child->port = parent->port; 757 child->port = parent->port;
756 child->iproto = phy->attached_iproto; 758 child->iproto = phy->attached_iproto;
757 memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); 759 memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
758 sas_hash_addr(child->hashed_sas_addr, child->sas_addr); 760 sas_hash_addr(child->hashed_sas_addr, child->sas_addr);
759 if (!phy->port) { 761 if (!phy->port) {
760 phy->port = sas_port_alloc(&parent->rphy->dev, phy_id); 762 phy->port = sas_port_alloc(&parent->rphy->dev, phy_id);
761 if (unlikely(!phy->port)) 763 if (unlikely(!phy->port))
762 goto out_err; 764 goto out_err;
763 if (unlikely(sas_port_add(phy->port) != 0)) { 765 if (unlikely(sas_port_add(phy->port) != 0)) {
764 sas_port_free(phy->port); 766 sas_port_free(phy->port);
765 goto out_err; 767 goto out_err;
766 } 768 }
767 } 769 }
768 sas_ex_get_linkrate(parent, child, phy); 770 sas_ex_get_linkrate(parent, child, phy);
769 sas_device_set_phy(child, phy->port); 771 sas_device_set_phy(child, phy->port);
770 772
771 #ifdef CONFIG_SCSI_SAS_ATA 773 #ifdef CONFIG_SCSI_SAS_ATA
772 if ((phy->attached_tproto & SAS_PROTOCOL_STP) || phy->attached_sata_dev) { 774 if ((phy->attached_tproto & SAS_PROTOCOL_STP) || phy->attached_sata_dev) {
773 res = sas_get_ata_info(child, phy); 775 res = sas_get_ata_info(child, phy);
774 if (res) 776 if (res)
775 goto out_free; 777 goto out_free;
776 778
777 rphy = sas_end_device_alloc(phy->port); 779 rphy = sas_end_device_alloc(phy->port);
778 if (unlikely(!rphy)) 780 if (unlikely(!rphy))
779 goto out_free; 781 goto out_free;
780 782
781 sas_init_dev(child); 783 sas_init_dev(child);
782 784
783 child->rphy = rphy; 785 child->rphy = rphy;
784 786
785 list_add_tail(&child->disco_list_node, &parent->port->disco_list); 787 list_add_tail(&child->disco_list_node, &parent->port->disco_list);
786 788
787 res = sas_discover_sata(child); 789 res = sas_discover_sata(child);
788 if (res) { 790 if (res) {
789 SAS_DPRINTK("sas_discover_sata() for device %16llx at " 791 SAS_DPRINTK("sas_discover_sata() for device %16llx at "
790 "%016llx:0x%x returned 0x%x\n", 792 "%016llx:0x%x returned 0x%x\n",
791 SAS_ADDR(child->sas_addr), 793 SAS_ADDR(child->sas_addr),
792 SAS_ADDR(parent->sas_addr), phy_id, res); 794 SAS_ADDR(parent->sas_addr), phy_id, res);
793 goto out_list_del; 795 goto out_list_del;
794 } 796 }
795 } else 797 } else
796 #endif 798 #endif
797 if (phy->attached_tproto & SAS_PROTOCOL_SSP) { 799 if (phy->attached_tproto & SAS_PROTOCOL_SSP) {
798 child->dev_type = SAS_END_DEV; 800 child->dev_type = SAS_END_DEV;
799 rphy = sas_end_device_alloc(phy->port); 801 rphy = sas_end_device_alloc(phy->port);
800 /* FIXME: error handling */ 802 /* FIXME: error handling */
801 if (unlikely(!rphy)) 803 if (unlikely(!rphy))
802 goto out_free; 804 goto out_free;
803 child->tproto = phy->attached_tproto; 805 child->tproto = phy->attached_tproto;
804 sas_init_dev(child); 806 sas_init_dev(child);
805 807
806 child->rphy = rphy; 808 child->rphy = rphy;
807 sas_fill_in_rphy(child, rphy); 809 sas_fill_in_rphy(child, rphy);
808 810
809 list_add_tail(&child->disco_list_node, &parent->port->disco_list); 811 list_add_tail(&child->disco_list_node, &parent->port->disco_list);
810 812
811 res = sas_discover_end_dev(child); 813 res = sas_discover_end_dev(child);
812 if (res) { 814 if (res) {
813 SAS_DPRINTK("sas_discover_end_dev() for device %16llx " 815 SAS_DPRINTK("sas_discover_end_dev() for device %16llx "
814 "at %016llx:0x%x returned 0x%x\n", 816 "at %016llx:0x%x returned 0x%x\n",
815 SAS_ADDR(child->sas_addr), 817 SAS_ADDR(child->sas_addr),
816 SAS_ADDR(parent->sas_addr), phy_id, res); 818 SAS_ADDR(parent->sas_addr), phy_id, res);
817 goto out_list_del; 819 goto out_list_del;
818 } 820 }
819 } else { 821 } else {
820 SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n", 822 SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n",
821 phy->attached_tproto, SAS_ADDR(parent->sas_addr), 823 phy->attached_tproto, SAS_ADDR(parent->sas_addr),
822 phy_id); 824 phy_id);
823 goto out_free; 825 goto out_free;
824 } 826 }
825 827
826 list_add_tail(&child->siblings, &parent_ex->children); 828 list_add_tail(&child->siblings, &parent_ex->children);
827 return child; 829 return child;
828 830
829 out_list_del: 831 out_list_del:
830 sas_rphy_free(child->rphy); 832 sas_rphy_free(child->rphy);
831 child->rphy = NULL; 833 child->rphy = NULL;
832 834
833 list_del(&child->disco_list_node); 835 list_del(&child->disco_list_node);
834 spin_lock_irq(&parent->port->dev_list_lock); 836 spin_lock_irq(&parent->port->dev_list_lock);
835 list_del(&child->dev_list_node); 837 list_del(&child->dev_list_node);
836 spin_unlock_irq(&parent->port->dev_list_lock); 838 spin_unlock_irq(&parent->port->dev_list_lock);
837 out_free: 839 out_free:
838 sas_port_delete(phy->port); 840 sas_port_delete(phy->port);
839 out_err: 841 out_err:
840 phy->port = NULL; 842 phy->port = NULL;
841 sas_put_device(child); 843 sas_put_device(child);
842 return NULL; 844 return NULL;
843 } 845 }
844 846
845 /* See if this phy is part of a wide port */ 847 /* See if this phy is part of a wide port */
846 static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id) 848 static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
847 { 849 {
848 struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id]; 850 struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
849 int i; 851 int i;
850 852
851 for (i = 0; i < parent->ex_dev.num_phys; i++) { 853 for (i = 0; i < parent->ex_dev.num_phys; i++) {
852 struct ex_phy *ephy = &parent->ex_dev.ex_phy[i]; 854 struct ex_phy *ephy = &parent->ex_dev.ex_phy[i];
853 855
854 if (ephy == phy) 856 if (ephy == phy)
855 continue; 857 continue;
856 858
857 if (!memcmp(phy->attached_sas_addr, ephy->attached_sas_addr, 859 if (!memcmp(phy->attached_sas_addr, ephy->attached_sas_addr,
858 SAS_ADDR_SIZE) && ephy->port) { 860 SAS_ADDR_SIZE) && ephy->port) {
859 sas_port_add_phy(ephy->port, phy->phy); 861 sas_port_add_phy(ephy->port, phy->phy);
860 phy->port = ephy->port; 862 phy->port = ephy->port;
861 phy->phy_state = PHY_DEVICE_DISCOVERED; 863 phy->phy_state = PHY_DEVICE_DISCOVERED;
862 return 0; 864 return 0;
863 } 865 }
864 } 866 }
865 867
866 return -ENODEV; 868 return -ENODEV;
867 } 869 }
868 870
869 static struct domain_device *sas_ex_discover_expander( 871 static struct domain_device *sas_ex_discover_expander(
870 struct domain_device *parent, int phy_id) 872 struct domain_device *parent, int phy_id)
871 { 873 {
872 struct sas_expander_device *parent_ex = rphy_to_expander_device(parent->rphy); 874 struct sas_expander_device *parent_ex = rphy_to_expander_device(parent->rphy);
873 struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id]; 875 struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
874 struct domain_device *child = NULL; 876 struct domain_device *child = NULL;
875 struct sas_rphy *rphy; 877 struct sas_rphy *rphy;
876 struct sas_expander_device *edev; 878 struct sas_expander_device *edev;
877 struct asd_sas_port *port; 879 struct asd_sas_port *port;
878 int res; 880 int res;
879 881
880 if (phy->routing_attr == DIRECT_ROUTING) { 882 if (phy->routing_attr == DIRECT_ROUTING) {
881 SAS_DPRINTK("ex %016llx:0x%x:D <--> ex %016llx:0x%x is not " 883 SAS_DPRINTK("ex %016llx:0x%x:D <--> ex %016llx:0x%x is not "
882 "allowed\n", 884 "allowed\n",
883 SAS_ADDR(parent->sas_addr), phy_id, 885 SAS_ADDR(parent->sas_addr), phy_id,
884 SAS_ADDR(phy->attached_sas_addr), 886 SAS_ADDR(phy->attached_sas_addr),
885 phy->attached_phy_id); 887 phy->attached_phy_id);
886 return NULL; 888 return NULL;
887 } 889 }
888 child = sas_alloc_device(); 890 child = sas_alloc_device();
889 if (!child) 891 if (!child)
890 return NULL; 892 return NULL;
891 893
892 phy->port = sas_port_alloc(&parent->rphy->dev, phy_id); 894 phy->port = sas_port_alloc(&parent->rphy->dev, phy_id);
893 /* FIXME: better error handling */ 895 /* FIXME: better error handling */
894 BUG_ON(sas_port_add(phy->port) != 0); 896 BUG_ON(sas_port_add(phy->port) != 0);
895 897
896 898
897 switch (phy->attached_dev_type) { 899 switch (phy->attached_dev_type) {
898 case EDGE_DEV: 900 case EDGE_DEV:
899 rphy = sas_expander_alloc(phy->port, 901 rphy = sas_expander_alloc(phy->port,
900 SAS_EDGE_EXPANDER_DEVICE); 902 SAS_EDGE_EXPANDER_DEVICE);
901 break; 903 break;
902 case FANOUT_DEV: 904 case FANOUT_DEV:
903 rphy = sas_expander_alloc(phy->port, 905 rphy = sas_expander_alloc(phy->port,
904 SAS_FANOUT_EXPANDER_DEVICE); 906 SAS_FANOUT_EXPANDER_DEVICE);
905 break; 907 break;
906 default: 908 default:
907 rphy = NULL; /* shut gcc up */ 909 rphy = NULL; /* shut gcc up */
908 BUG(); 910 BUG();
909 } 911 }
910 port = parent->port; 912 port = parent->port;
911 child->rphy = rphy; 913 child->rphy = rphy;
912 edev = rphy_to_expander_device(rphy); 914 edev = rphy_to_expander_device(rphy);
913 child->dev_type = phy->attached_dev_type; 915 child->dev_type = phy->attached_dev_type;
914 kref_get(&parent->kref); 916 kref_get(&parent->kref);
915 child->parent = parent; 917 child->parent = parent;
916 child->port = port; 918 child->port = port;
917 child->iproto = phy->attached_iproto; 919 child->iproto = phy->attached_iproto;
918 child->tproto = phy->attached_tproto; 920 child->tproto = phy->attached_tproto;
919 memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); 921 memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
920 sas_hash_addr(child->hashed_sas_addr, child->sas_addr); 922 sas_hash_addr(child->hashed_sas_addr, child->sas_addr);
921 sas_ex_get_linkrate(parent, child, phy); 923 sas_ex_get_linkrate(parent, child, phy);
922 edev->level = parent_ex->level + 1; 924 edev->level = parent_ex->level + 1;
923 parent->port->disc.max_level = max(parent->port->disc.max_level, 925 parent->port->disc.max_level = max(parent->port->disc.max_level,
924 edev->level); 926 edev->level);
925 sas_init_dev(child); 927 sas_init_dev(child);
926 sas_fill_in_rphy(child, rphy); 928 sas_fill_in_rphy(child, rphy);
927 sas_rphy_add(rphy); 929 sas_rphy_add(rphy);
928 930
929 spin_lock_irq(&parent->port->dev_list_lock); 931 spin_lock_irq(&parent->port->dev_list_lock);
930 list_add_tail(&child->dev_list_node, &parent->port->dev_list); 932 list_add_tail(&child->dev_list_node, &parent->port->dev_list);
931 spin_unlock_irq(&parent->port->dev_list_lock); 933 spin_unlock_irq(&parent->port->dev_list_lock);
932 934
933 res = sas_discover_expander(child); 935 res = sas_discover_expander(child);
934 if (res) { 936 if (res) {
935 spin_lock_irq(&parent->port->dev_list_lock); 937 spin_lock_irq(&parent->port->dev_list_lock);
936 list_del(&child->dev_list_node); 938 list_del(&child->dev_list_node);
937 spin_unlock_irq(&parent->port->dev_list_lock); 939 spin_unlock_irq(&parent->port->dev_list_lock);
938 sas_put_device(child); 940 sas_put_device(child);
939 return NULL; 941 return NULL;
940 } 942 }
941 list_add_tail(&child->siblings, &parent->ex_dev.children); 943 list_add_tail(&child->siblings, &parent->ex_dev.children);
942 return child; 944 return child;
943 } 945 }
944 946
945 static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) 947 static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
946 { 948 {
947 struct expander_device *ex = &dev->ex_dev; 949 struct expander_device *ex = &dev->ex_dev;
948 struct ex_phy *ex_phy = &ex->ex_phy[phy_id]; 950 struct ex_phy *ex_phy = &ex->ex_phy[phy_id];
949 struct domain_device *child = NULL; 951 struct domain_device *child = NULL;
950 int res = 0; 952 int res = 0;
951 953
952 /* Phy state */ 954 /* Phy state */
953 if (ex_phy->linkrate == SAS_SATA_SPINUP_HOLD) { 955 if (ex_phy->linkrate == SAS_SATA_SPINUP_HOLD) {
954 if (!sas_smp_phy_control(dev, phy_id, PHY_FUNC_LINK_RESET, NULL)) 956 if (!sas_smp_phy_control(dev, phy_id, PHY_FUNC_LINK_RESET, NULL))
955 res = sas_ex_phy_discover(dev, phy_id); 957 res = sas_ex_phy_discover(dev, phy_id);
956 if (res) 958 if (res)
957 return res; 959 return res;
958 } 960 }
959 961
960 /* Parent and domain coherency */ 962 /* Parent and domain coherency */
961 if (!dev->parent && (SAS_ADDR(ex_phy->attached_sas_addr) == 963 if (!dev->parent && (SAS_ADDR(ex_phy->attached_sas_addr) ==
962 SAS_ADDR(dev->port->sas_addr))) { 964 SAS_ADDR(dev->port->sas_addr))) {
963 sas_add_parent_port(dev, phy_id); 965 sas_add_parent_port(dev, phy_id);
964 return 0; 966 return 0;
965 } 967 }
966 if (dev->parent && (SAS_ADDR(ex_phy->attached_sas_addr) == 968 if (dev->parent && (SAS_ADDR(ex_phy->attached_sas_addr) ==
967 SAS_ADDR(dev->parent->sas_addr))) { 969 SAS_ADDR(dev->parent->sas_addr))) {
968 sas_add_parent_port(dev, phy_id); 970 sas_add_parent_port(dev, phy_id);
969 if (ex_phy->routing_attr == TABLE_ROUTING) 971 if (ex_phy->routing_attr == TABLE_ROUTING)
970 sas_configure_phy(dev, phy_id, dev->port->sas_addr, 1); 972 sas_configure_phy(dev, phy_id, dev->port->sas_addr, 1);
971 return 0; 973 return 0;
972 } 974 }
973 975
974 if (sas_dev_present_in_domain(dev->port, ex_phy->attached_sas_addr)) 976 if (sas_dev_present_in_domain(dev->port, ex_phy->attached_sas_addr))
975 sas_ex_disable_port(dev, ex_phy->attached_sas_addr); 977 sas_ex_disable_port(dev, ex_phy->attached_sas_addr);
976 978
977 if (ex_phy->attached_dev_type == NO_DEVICE) { 979 if (ex_phy->attached_dev_type == NO_DEVICE) {
978 if (ex_phy->routing_attr == DIRECT_ROUTING) { 980 if (ex_phy->routing_attr == DIRECT_ROUTING) {
979 memset(ex_phy->attached_sas_addr, 0, SAS_ADDR_SIZE); 981 memset(ex_phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
980 sas_configure_routing(dev, ex_phy->attached_sas_addr); 982 sas_configure_routing(dev, ex_phy->attached_sas_addr);
981 } 983 }
982 return 0; 984 return 0;
983 } else if (ex_phy->linkrate == SAS_LINK_RATE_UNKNOWN) 985 } else if (ex_phy->linkrate == SAS_LINK_RATE_UNKNOWN)
984 return 0; 986 return 0;
985 987
986 if (ex_phy->attached_dev_type != SAS_END_DEV && 988 if (ex_phy->attached_dev_type != SAS_END_DEV &&
987 ex_phy->attached_dev_type != FANOUT_DEV && 989 ex_phy->attached_dev_type != FANOUT_DEV &&
988 ex_phy->attached_dev_type != EDGE_DEV && 990 ex_phy->attached_dev_type != EDGE_DEV &&
989 ex_phy->attached_dev_type != SATA_PENDING) { 991 ex_phy->attached_dev_type != SATA_PENDING) {
990 SAS_DPRINTK("unknown device type(0x%x) attached to ex %016llx " 992 SAS_DPRINTK("unknown device type(0x%x) attached to ex %016llx "
991 "phy 0x%x\n", ex_phy->attached_dev_type, 993 "phy 0x%x\n", ex_phy->attached_dev_type,
992 SAS_ADDR(dev->sas_addr), 994 SAS_ADDR(dev->sas_addr),
993 phy_id); 995 phy_id);
994 return 0; 996 return 0;
995 } 997 }
996 998
997 res = sas_configure_routing(dev, ex_phy->attached_sas_addr); 999 res = sas_configure_routing(dev, ex_phy->attached_sas_addr);
998 if (res) { 1000 if (res) {
999 SAS_DPRINTK("configure routing for dev %016llx " 1001 SAS_DPRINTK("configure routing for dev %016llx "
1000 "reported 0x%x. Forgotten\n", 1002 "reported 0x%x. Forgotten\n",
1001 SAS_ADDR(ex_phy->attached_sas_addr), res); 1003 SAS_ADDR(ex_phy->attached_sas_addr), res);
1002 sas_disable_routing(dev, ex_phy->attached_sas_addr); 1004 sas_disable_routing(dev, ex_phy->attached_sas_addr);
1003 return res; 1005 return res;
1004 } 1006 }
1005 1007
1006 res = sas_ex_join_wide_port(dev, phy_id); 1008 res = sas_ex_join_wide_port(dev, phy_id);
1007 if (!res) { 1009 if (!res) {
1008 SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", 1010 SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
1009 phy_id, SAS_ADDR(ex_phy->attached_sas_addr)); 1011 phy_id, SAS_ADDR(ex_phy->attached_sas_addr));
1010 return res; 1012 return res;
1011 } 1013 }
1012 1014
1013 switch (ex_phy->attached_dev_type) { 1015 switch (ex_phy->attached_dev_type) {
1014 case SAS_END_DEV: 1016 case SAS_END_DEV:
1015 case SATA_PENDING: 1017 case SATA_PENDING:
1016 child = sas_ex_discover_end_dev(dev, phy_id); 1018 child = sas_ex_discover_end_dev(dev, phy_id);
1017 break; 1019 break;
1018 case FANOUT_DEV: 1020 case FANOUT_DEV:
1019 if (SAS_ADDR(dev->port->disc.fanout_sas_addr)) { 1021 if (SAS_ADDR(dev->port->disc.fanout_sas_addr)) {
1020 SAS_DPRINTK("second fanout expander %016llx phy 0x%x " 1022 SAS_DPRINTK("second fanout expander %016llx phy 0x%x "
1021 "attached to ex %016llx phy 0x%x\n", 1023 "attached to ex %016llx phy 0x%x\n",
1022 SAS_ADDR(ex_phy->attached_sas_addr), 1024 SAS_ADDR(ex_phy->attached_sas_addr),
1023 ex_phy->attached_phy_id, 1025 ex_phy->attached_phy_id,
1024 SAS_ADDR(dev->sas_addr), 1026 SAS_ADDR(dev->sas_addr),
1025 phy_id); 1027 phy_id);
1026 sas_ex_disable_phy(dev, phy_id); 1028 sas_ex_disable_phy(dev, phy_id);
1027 break; 1029 break;
1028 } else 1030 } else
1029 memcpy(dev->port->disc.fanout_sas_addr, 1031 memcpy(dev->port->disc.fanout_sas_addr,
1030 ex_phy->attached_sas_addr, SAS_ADDR_SIZE); 1032 ex_phy->attached_sas_addr, SAS_ADDR_SIZE);
1031 /* fallthrough */ 1033 /* fallthrough */
1032 case EDGE_DEV: 1034 case EDGE_DEV:
1033 child = sas_ex_discover_expander(dev, phy_id); 1035 child = sas_ex_discover_expander(dev, phy_id);
1034 break; 1036 break;
1035 default: 1037 default:
1036 break; 1038 break;
1037 } 1039 }
1038 1040
1039 if (child) { 1041 if (child) {
1040 int i; 1042 int i;
1041 1043
1042 for (i = 0; i < ex->num_phys; i++) { 1044 for (i = 0; i < ex->num_phys; i++) {
1043 if (ex->ex_phy[i].phy_state == PHY_VACANT || 1045 if (ex->ex_phy[i].phy_state == PHY_VACANT ||
1044 ex->ex_phy[i].phy_state == PHY_NOT_PRESENT) 1046 ex->ex_phy[i].phy_state == PHY_NOT_PRESENT)
1045 continue; 1047 continue;
1046 /* 1048 /*
1047 * Due to races, the phy might not get added to the 1049 * Due to races, the phy might not get added to the
1048 * wide port, so we add the phy to the wide port here. 1050 * wide port, so we add the phy to the wide port here.
1049 */ 1051 */
1050 if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) == 1052 if (SAS_ADDR(ex->ex_phy[i].attached_sas_addr) ==
1051 SAS_ADDR(child->sas_addr)) { 1053 SAS_ADDR(child->sas_addr)) {
1052 ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED; 1054 ex->ex_phy[i].phy_state= PHY_DEVICE_DISCOVERED;
1053 res = sas_ex_join_wide_port(dev, i); 1055 res = sas_ex_join_wide_port(dev, i);
1054 if (!res) 1056 if (!res)
1055 SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n", 1057 SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
1056 i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr)); 1058 i, SAS_ADDR(ex->ex_phy[i].attached_sas_addr));
1057 1059
1058 } 1060 }
1059 } 1061 }
1060 } 1062 }
1061 1063
1062 return res; 1064 return res;
1063 } 1065 }
1064 1066
1065 static int sas_find_sub_addr(struct domain_device *dev, u8 *sub_addr) 1067 static int sas_find_sub_addr(struct domain_device *dev, u8 *sub_addr)
1066 { 1068 {
1067 struct expander_device *ex = &dev->ex_dev; 1069 struct expander_device *ex = &dev->ex_dev;
1068 int i; 1070 int i;
1069 1071
1070 for (i = 0; i < ex->num_phys; i++) { 1072 for (i = 0; i < ex->num_phys; i++) {
1071 struct ex_phy *phy = &ex->ex_phy[i]; 1073 struct ex_phy *phy = &ex->ex_phy[i];
1072 1074
1073 if (phy->phy_state == PHY_VACANT || 1075 if (phy->phy_state == PHY_VACANT ||
1074 phy->phy_state == PHY_NOT_PRESENT) 1076 phy->phy_state == PHY_NOT_PRESENT)
1075 continue; 1077 continue;
1076 1078
1077 if ((phy->attached_dev_type == EDGE_DEV || 1079 if ((phy->attached_dev_type == EDGE_DEV ||
1078 phy->attached_dev_type == FANOUT_DEV) && 1080 phy->attached_dev_type == FANOUT_DEV) &&
1079 phy->routing_attr == SUBTRACTIVE_ROUTING) { 1081 phy->routing_attr == SUBTRACTIVE_ROUTING) {
1080 1082
1081 memcpy(sub_addr, phy->attached_sas_addr,SAS_ADDR_SIZE); 1083 memcpy(sub_addr, phy->attached_sas_addr,SAS_ADDR_SIZE);
1082 1084
1083 return 1; 1085 return 1;
1084 } 1086 }
1085 } 1087 }
1086 return 0; 1088 return 0;
1087 } 1089 }
1088 1090
1089 static int sas_check_level_subtractive_boundary(struct domain_device *dev) 1091 static int sas_check_level_subtractive_boundary(struct domain_device *dev)
1090 { 1092 {
1091 struct expander_device *ex = &dev->ex_dev; 1093 struct expander_device *ex = &dev->ex_dev;
1092 struct domain_device *child; 1094 struct domain_device *child;
1093 u8 sub_addr[8] = {0, }; 1095 u8 sub_addr[8] = {0, };
1094 1096
1095 list_for_each_entry(child, &ex->children, siblings) { 1097 list_for_each_entry(child, &ex->children, siblings) {
1096 if (child->dev_type != EDGE_DEV && 1098 if (child->dev_type != EDGE_DEV &&
1097 child->dev_type != FANOUT_DEV) 1099 child->dev_type != FANOUT_DEV)
1098 continue; 1100 continue;
1099 if (sub_addr[0] == 0) { 1101 if (sub_addr[0] == 0) {
1100 sas_find_sub_addr(child, sub_addr); 1102 sas_find_sub_addr(child, sub_addr);
1101 continue; 1103 continue;
1102 } else { 1104 } else {
1103 u8 s2[8]; 1105 u8 s2[8];
1104 1106
1105 if (sas_find_sub_addr(child, s2) && 1107 if (sas_find_sub_addr(child, s2) &&
1106 (SAS_ADDR(sub_addr) != SAS_ADDR(s2))) { 1108 (SAS_ADDR(sub_addr) != SAS_ADDR(s2))) {
1107 1109
1108 SAS_DPRINTK("ex %016llx->%016llx-?->%016llx " 1110 SAS_DPRINTK("ex %016llx->%016llx-?->%016llx "
1109 "diverges from subtractive " 1111 "diverges from subtractive "
1110 "boundary %016llx\n", 1112 "boundary %016llx\n",
1111 SAS_ADDR(dev->sas_addr), 1113 SAS_ADDR(dev->sas_addr),
1112 SAS_ADDR(child->sas_addr), 1114 SAS_ADDR(child->sas_addr),
1113 SAS_ADDR(s2), 1115 SAS_ADDR(s2),
1114 SAS_ADDR(sub_addr)); 1116 SAS_ADDR(sub_addr));
1115 1117
1116 sas_ex_disable_port(child, s2); 1118 sas_ex_disable_port(child, s2);
1117 } 1119 }
1118 } 1120 }
1119 } 1121 }
1120 return 0; 1122 return 0;
1121 } 1123 }
1122 /** 1124 /**
1123 * sas_ex_discover_devices -- discover devices attached to this expander 1125 * sas_ex_discover_devices -- discover devices attached to this expander
1124 * dev: pointer to the expander domain device 1126 * dev: pointer to the expander domain device
1125 * single: if you want to do a single phy, else set to -1; 1127 * single: if you want to do a single phy, else set to -1;
1126 * 1128 *
1127 * Configure this expander for use with its devices and register the 1129 * Configure this expander for use with its devices and register the
1128 * devices of this expander. 1130 * devices of this expander.
1129 */ 1131 */
1130 static int sas_ex_discover_devices(struct domain_device *dev, int single) 1132 static int sas_ex_discover_devices(struct domain_device *dev, int single)
1131 { 1133 {
1132 struct expander_device *ex = &dev->ex_dev; 1134 struct expander_device *ex = &dev->ex_dev;
1133 int i = 0, end = ex->num_phys; 1135 int i = 0, end = ex->num_phys;
1134 int res = 0; 1136 int res = 0;
1135 1137
1136 if (0 <= single && single < end) { 1138 if (0 <= single && single < end) {
1137 i = single; 1139 i = single;
1138 end = i+1; 1140 end = i+1;
1139 } 1141 }
1140 1142
1141 for ( ; i < end; i++) { 1143 for ( ; i < end; i++) {
1142 struct ex_phy *ex_phy = &ex->ex_phy[i]; 1144 struct ex_phy *ex_phy = &ex->ex_phy[i];
1143 1145
1144 if (ex_phy->phy_state == PHY_VACANT || 1146 if (ex_phy->phy_state == PHY_VACANT ||
1145 ex_phy->phy_state == PHY_NOT_PRESENT || 1147 ex_phy->phy_state == PHY_NOT_PRESENT ||
1146 ex_phy->phy_state == PHY_DEVICE_DISCOVERED) 1148 ex_phy->phy_state == PHY_DEVICE_DISCOVERED)
1147 continue; 1149 continue;
1148 1150
1149 switch (ex_phy->linkrate) { 1151 switch (ex_phy->linkrate) {
1150 case SAS_PHY_DISABLED: 1152 case SAS_PHY_DISABLED:
1151 case SAS_PHY_RESET_PROBLEM: 1153 case SAS_PHY_RESET_PROBLEM:
1152 case SAS_SATA_PORT_SELECTOR: 1154 case SAS_SATA_PORT_SELECTOR:
1153 continue; 1155 continue;
1154 default: 1156 default:
1155 res = sas_ex_discover_dev(dev, i); 1157 res = sas_ex_discover_dev(dev, i);
1156 if (res) 1158 if (res)
1157 break; 1159 break;
1158 continue; 1160 continue;
1159 } 1161 }
1160 } 1162 }
1161 1163
1162 if (!res) 1164 if (!res)
1163 sas_check_level_subtractive_boundary(dev); 1165 sas_check_level_subtractive_boundary(dev);
1164 1166
1165 return res; 1167 return res;
1166 } 1168 }
1167 1169
1168 static int sas_check_ex_subtractive_boundary(struct domain_device *dev) 1170 static int sas_check_ex_subtractive_boundary(struct domain_device *dev)
1169 { 1171 {
1170 struct expander_device *ex = &dev->ex_dev; 1172 struct expander_device *ex = &dev->ex_dev;
1171 int i; 1173 int i;
1172 u8 *sub_sas_addr = NULL; 1174 u8 *sub_sas_addr = NULL;
1173 1175
1174 if (dev->dev_type != EDGE_DEV) 1176 if (dev->dev_type != EDGE_DEV)
1175 return 0; 1177 return 0;
1176 1178
1177 for (i = 0; i < ex->num_phys; i++) { 1179 for (i = 0; i < ex->num_phys; i++) {
1178 struct ex_phy *phy = &ex->ex_phy[i]; 1180 struct ex_phy *phy = &ex->ex_phy[i];
1179 1181
1180 if (phy->phy_state == PHY_VACANT || 1182 if (phy->phy_state == PHY_VACANT ||
1181 phy->phy_state == PHY_NOT_PRESENT) 1183 phy->phy_state == PHY_NOT_PRESENT)
1182 continue; 1184 continue;
1183 1185
1184 if ((phy->attached_dev_type == FANOUT_DEV || 1186 if ((phy->attached_dev_type == FANOUT_DEV ||
1185 phy->attached_dev_type == EDGE_DEV) && 1187 phy->attached_dev_type == EDGE_DEV) &&
1186 phy->routing_attr == SUBTRACTIVE_ROUTING) { 1188 phy->routing_attr == SUBTRACTIVE_ROUTING) {
1187 1189
1188 if (!sub_sas_addr) 1190 if (!sub_sas_addr)
1189 sub_sas_addr = &phy->attached_sas_addr[0]; 1191 sub_sas_addr = &phy->attached_sas_addr[0];
1190 else if (SAS_ADDR(sub_sas_addr) != 1192 else if (SAS_ADDR(sub_sas_addr) !=
1191 SAS_ADDR(phy->attached_sas_addr)) { 1193 SAS_ADDR(phy->attached_sas_addr)) {
1192 1194
1193 SAS_DPRINTK("ex %016llx phy 0x%x " 1195 SAS_DPRINTK("ex %016llx phy 0x%x "
1194 "diverges(%016llx) on subtractive " 1196 "diverges(%016llx) on subtractive "
1195 "boundary(%016llx). Disabled\n", 1197 "boundary(%016llx). Disabled\n",
1196 SAS_ADDR(dev->sas_addr), i, 1198 SAS_ADDR(dev->sas_addr), i,
1197 SAS_ADDR(phy->attached_sas_addr), 1199 SAS_ADDR(phy->attached_sas_addr),
1198 SAS_ADDR(sub_sas_addr)); 1200 SAS_ADDR(sub_sas_addr));
1199 sas_ex_disable_phy(dev, i); 1201 sas_ex_disable_phy(dev, i);
1200 } 1202 }
1201 } 1203 }
1202 } 1204 }
1203 return 0; 1205 return 0;
1204 } 1206 }
1205 1207
1206 static void sas_print_parent_topology_bug(struct domain_device *child, 1208 static void sas_print_parent_topology_bug(struct domain_device *child,
1207 struct ex_phy *parent_phy, 1209 struct ex_phy *parent_phy,
1208 struct ex_phy *child_phy) 1210 struct ex_phy *child_phy)
1209 { 1211 {
1210 static const char *ex_type[] = { 1212 static const char *ex_type[] = {
1211 [EDGE_DEV] = "edge", 1213 [EDGE_DEV] = "edge",
1212 [FANOUT_DEV] = "fanout", 1214 [FANOUT_DEV] = "fanout",
1213 }; 1215 };
1214 struct domain_device *parent = child->parent; 1216 struct domain_device *parent = child->parent;
1215 1217
1216 sas_printk("%s ex %016llx phy 0x%x <--> %s ex %016llx " 1218 sas_printk("%s ex %016llx phy 0x%x <--> %s ex %016llx "
1217 "phy 0x%x has %c:%c routing link!\n", 1219 "phy 0x%x has %c:%c routing link!\n",
1218 1220
1219 ex_type[parent->dev_type], 1221 ex_type[parent->dev_type],
1220 SAS_ADDR(parent->sas_addr), 1222 SAS_ADDR(parent->sas_addr),
1221 parent_phy->phy_id, 1223 parent_phy->phy_id,
1222 1224
1223 ex_type[child->dev_type], 1225 ex_type[child->dev_type],
1224 SAS_ADDR(child->sas_addr), 1226 SAS_ADDR(child->sas_addr),
1225 child_phy->phy_id, 1227 child_phy->phy_id,
1226 1228
1227 sas_route_char(parent, parent_phy), 1229 sas_route_char(parent, parent_phy),
1228 sas_route_char(child, child_phy)); 1230 sas_route_char(child, child_phy));
1229 } 1231 }
1230 1232
1231 static int sas_check_eeds(struct domain_device *child, 1233 static int sas_check_eeds(struct domain_device *child,
1232 struct ex_phy *parent_phy, 1234 struct ex_phy *parent_phy,
1233 struct ex_phy *child_phy) 1235 struct ex_phy *child_phy)
1234 { 1236 {
1235 int res = 0; 1237 int res = 0;
1236 struct domain_device *parent = child->parent; 1238 struct domain_device *parent = child->parent;
1237 1239
1238 if (SAS_ADDR(parent->port->disc.fanout_sas_addr) != 0) { 1240 if (SAS_ADDR(parent->port->disc.fanout_sas_addr) != 0) {
1239 res = -ENODEV; 1241 res = -ENODEV;
1240 SAS_DPRINTK("edge ex %016llx phy S:0x%x <--> edge ex %016llx " 1242 SAS_DPRINTK("edge ex %016llx phy S:0x%x <--> edge ex %016llx "
1241 "phy S:0x%x, while there is a fanout ex %016llx\n", 1243 "phy S:0x%x, while there is a fanout ex %016llx\n",
1242 SAS_ADDR(parent->sas_addr), 1244 SAS_ADDR(parent->sas_addr),
1243 parent_phy->phy_id, 1245 parent_phy->phy_id,
1244 SAS_ADDR(child->sas_addr), 1246 SAS_ADDR(child->sas_addr),
1245 child_phy->phy_id, 1247 child_phy->phy_id,
1246 SAS_ADDR(parent->port->disc.fanout_sas_addr)); 1248 SAS_ADDR(parent->port->disc.fanout_sas_addr));
1247 } else if (SAS_ADDR(parent->port->disc.eeds_a) == 0) { 1249 } else if (SAS_ADDR(parent->port->disc.eeds_a) == 0) {
1248 memcpy(parent->port->disc.eeds_a, parent->sas_addr, 1250 memcpy(parent->port->disc.eeds_a, parent->sas_addr,
1249 SAS_ADDR_SIZE); 1251 SAS_ADDR_SIZE);
1250 memcpy(parent->port->disc.eeds_b, child->sas_addr, 1252 memcpy(parent->port->disc.eeds_b, child->sas_addr,
1251 SAS_ADDR_SIZE); 1253 SAS_ADDR_SIZE);
1252 } else if (((SAS_ADDR(parent->port->disc.eeds_a) == 1254 } else if (((SAS_ADDR(parent->port->disc.eeds_a) ==
1253 SAS_ADDR(parent->sas_addr)) || 1255 SAS_ADDR(parent->sas_addr)) ||
1254 (SAS_ADDR(parent->port->disc.eeds_a) == 1256 (SAS_ADDR(parent->port->disc.eeds_a) ==
1255 SAS_ADDR(child->sas_addr))) 1257 SAS_ADDR(child->sas_addr)))
1256 && 1258 &&
1257 ((SAS_ADDR(parent->port->disc.eeds_b) == 1259 ((SAS_ADDR(parent->port->disc.eeds_b) ==
1258 SAS_ADDR(parent->sas_addr)) || 1260 SAS_ADDR(parent->sas_addr)) ||
1259 (SAS_ADDR(parent->port->disc.eeds_b) == 1261 (SAS_ADDR(parent->port->disc.eeds_b) ==
1260 SAS_ADDR(child->sas_addr)))) 1262 SAS_ADDR(child->sas_addr))))
1261 ; 1263 ;
1262 else { 1264 else {
1263 res = -ENODEV; 1265 res = -ENODEV;
1264 SAS_DPRINTK("edge ex %016llx phy 0x%x <--> edge ex %016llx " 1266 SAS_DPRINTK("edge ex %016llx phy 0x%x <--> edge ex %016llx "
1265 "phy 0x%x link forms a third EEDS!\n", 1267 "phy 0x%x link forms a third EEDS!\n",
1266 SAS_ADDR(parent->sas_addr), 1268 SAS_ADDR(parent->sas_addr),
1267 parent_phy->phy_id, 1269 parent_phy->phy_id,
1268 SAS_ADDR(child->sas_addr), 1270 SAS_ADDR(child->sas_addr),
1269 child_phy->phy_id); 1271 child_phy->phy_id);
1270 } 1272 }
1271 1273
1272 return res; 1274 return res;
1273 } 1275 }
1274 1276
1275 /* Here we spill over 80 columns. It is intentional. 1277 /* Here we spill over 80 columns. It is intentional.
1276 */ 1278 */
1277 static int sas_check_parent_topology(struct domain_device *child) 1279 static int sas_check_parent_topology(struct domain_device *child)
1278 { 1280 {
1279 struct expander_device *child_ex = &child->ex_dev; 1281 struct expander_device *child_ex = &child->ex_dev;
1280 struct expander_device *parent_ex; 1282 struct expander_device *parent_ex;
1281 int i; 1283 int i;
1282 int res = 0; 1284 int res = 0;
1283 1285
1284 if (!child->parent) 1286 if (!child->parent)
1285 return 0; 1287 return 0;
1286 1288
1287 if (child->parent->dev_type != EDGE_DEV && 1289 if (child->parent->dev_type != EDGE_DEV &&
1288 child->parent->dev_type != FANOUT_DEV) 1290 child->parent->dev_type != FANOUT_DEV)
1289 return 0; 1291 return 0;
1290 1292
1291 parent_ex = &child->parent->ex_dev; 1293 parent_ex = &child->parent->ex_dev;
1292 1294
1293 for (i = 0; i < parent_ex->num_phys; i++) { 1295 for (i = 0; i < parent_ex->num_phys; i++) {
1294 struct ex_phy *parent_phy = &parent_ex->ex_phy[i]; 1296 struct ex_phy *parent_phy = &parent_ex->ex_phy[i];
1295 struct ex_phy *child_phy; 1297 struct ex_phy *child_phy;
1296 1298
1297 if (parent_phy->phy_state == PHY_VACANT || 1299 if (parent_phy->phy_state == PHY_VACANT ||
1298 parent_phy->phy_state == PHY_NOT_PRESENT) 1300 parent_phy->phy_state == PHY_NOT_PRESENT)
1299 continue; 1301 continue;
1300 1302
1301 if (SAS_ADDR(parent_phy->attached_sas_addr) != SAS_ADDR(child->sas_addr)) 1303 if (SAS_ADDR(parent_phy->attached_sas_addr) != SAS_ADDR(child->sas_addr))
1302 continue; 1304 continue;
1303 1305
1304 child_phy = &child_ex->ex_phy[parent_phy->attached_phy_id]; 1306 child_phy = &child_ex->ex_phy[parent_phy->attached_phy_id];
1305 1307
1306 switch (child->parent->dev_type) { 1308 switch (child->parent->dev_type) {
1307 case EDGE_DEV: 1309 case EDGE_DEV:
1308 if (child->dev_type == FANOUT_DEV) { 1310 if (child->dev_type == FANOUT_DEV) {
1309 if (parent_phy->routing_attr != SUBTRACTIVE_ROUTING || 1311 if (parent_phy->routing_attr != SUBTRACTIVE_ROUTING ||
1310 child_phy->routing_attr != TABLE_ROUTING) { 1312 child_phy->routing_attr != TABLE_ROUTING) {
1311 sas_print_parent_topology_bug(child, parent_phy, child_phy); 1313 sas_print_parent_topology_bug(child, parent_phy, child_phy);
1312 res = -ENODEV; 1314 res = -ENODEV;
1313 } 1315 }
1314 } else if (parent_phy->routing_attr == SUBTRACTIVE_ROUTING) { 1316 } else if (parent_phy->routing_attr == SUBTRACTIVE_ROUTING) {
1315 if (child_phy->routing_attr == SUBTRACTIVE_ROUTING) { 1317 if (child_phy->routing_attr == SUBTRACTIVE_ROUTING) {
1316 res = sas_check_eeds(child, parent_phy, child_phy); 1318 res = sas_check_eeds(child, parent_phy, child_phy);
1317 } else if (child_phy->routing_attr != TABLE_ROUTING) { 1319 } else if (child_phy->routing_attr != TABLE_ROUTING) {
1318 sas_print_parent_topology_bug(child, parent_phy, child_phy); 1320 sas_print_parent_topology_bug(child, parent_phy, child_phy);
1319 res = -ENODEV; 1321 res = -ENODEV;
1320 } 1322 }
1321 } else if (parent_phy->routing_attr == TABLE_ROUTING) { 1323 } else if (parent_phy->routing_attr == TABLE_ROUTING) {
1322 if (child_phy->routing_attr == SUBTRACTIVE_ROUTING || 1324 if (child_phy->routing_attr == SUBTRACTIVE_ROUTING ||
1323 (child_phy->routing_attr == TABLE_ROUTING && 1325 (child_phy->routing_attr == TABLE_ROUTING &&
1324 child_ex->t2t_supp && parent_ex->t2t_supp)) { 1326 child_ex->t2t_supp && parent_ex->t2t_supp)) {
1325 /* All good */; 1327 /* All good */;
1326 } else { 1328 } else {
1327 sas_print_parent_topology_bug(child, parent_phy, child_phy); 1329 sas_print_parent_topology_bug(child, parent_phy, child_phy);
1328 res = -ENODEV; 1330 res = -ENODEV;
1329 } 1331 }
1330 } 1332 }
1331 break; 1333 break;
1332 case FANOUT_DEV: 1334 case FANOUT_DEV:
1333 if (parent_phy->routing_attr != TABLE_ROUTING || 1335 if (parent_phy->routing_attr != TABLE_ROUTING ||
1334 child_phy->routing_attr != SUBTRACTIVE_ROUTING) { 1336 child_phy->routing_attr != SUBTRACTIVE_ROUTING) {
1335 sas_print_parent_topology_bug(child, parent_phy, child_phy); 1337 sas_print_parent_topology_bug(child, parent_phy, child_phy);
1336 res = -ENODEV; 1338 res = -ENODEV;
1337 } 1339 }
1338 break; 1340 break;
1339 default: 1341 default:
1340 break; 1342 break;
1341 } 1343 }
1342 } 1344 }
1343 1345
1344 return res; 1346 return res;
1345 } 1347 }
1346 1348
1347 #define RRI_REQ_SIZE 16 1349 #define RRI_REQ_SIZE 16
1348 #define RRI_RESP_SIZE 44 1350 #define RRI_RESP_SIZE 44
1349 1351
1350 static int sas_configure_present(struct domain_device *dev, int phy_id, 1352 static int sas_configure_present(struct domain_device *dev, int phy_id,
1351 u8 *sas_addr, int *index, int *present) 1353 u8 *sas_addr, int *index, int *present)
1352 { 1354 {
1353 int i, res = 0; 1355 int i, res = 0;
1354 struct expander_device *ex = &dev->ex_dev; 1356 struct expander_device *ex = &dev->ex_dev;
1355 struct ex_phy *phy = &ex->ex_phy[phy_id]; 1357 struct ex_phy *phy = &ex->ex_phy[phy_id];
1356 u8 *rri_req; 1358 u8 *rri_req;
1357 u8 *rri_resp; 1359 u8 *rri_resp;
1358 1360
1359 *present = 0; 1361 *present = 0;
1360 *index = 0; 1362 *index = 0;
1361 1363
1362 rri_req = alloc_smp_req(RRI_REQ_SIZE); 1364 rri_req = alloc_smp_req(RRI_REQ_SIZE);
1363 if (!rri_req) 1365 if (!rri_req)
1364 return -ENOMEM; 1366 return -ENOMEM;
1365 1367
1366 rri_resp = alloc_smp_resp(RRI_RESP_SIZE); 1368 rri_resp = alloc_smp_resp(RRI_RESP_SIZE);
1367 if (!rri_resp) { 1369 if (!rri_resp) {
1368 kfree(rri_req); 1370 kfree(rri_req);
1369 return -ENOMEM; 1371 return -ENOMEM;
1370 } 1372 }
1371 1373
1372 rri_req[1] = SMP_REPORT_ROUTE_INFO; 1374 rri_req[1] = SMP_REPORT_ROUTE_INFO;
1373 rri_req[9] = phy_id; 1375 rri_req[9] = phy_id;
1374 1376
1375 for (i = 0; i < ex->max_route_indexes ; i++) { 1377 for (i = 0; i < ex->max_route_indexes ; i++) {
1376 *(__be16 *)(rri_req+6) = cpu_to_be16(i); 1378 *(__be16 *)(rri_req+6) = cpu_to_be16(i);
1377 res = smp_execute_task(dev, rri_req, RRI_REQ_SIZE, rri_resp, 1379 res = smp_execute_task(dev, rri_req, RRI_REQ_SIZE, rri_resp,
1378 RRI_RESP_SIZE); 1380 RRI_RESP_SIZE);
1379 if (res) 1381 if (res)
1380 goto out; 1382 goto out;
1381 res = rri_resp[2]; 1383 res = rri_resp[2];
1382 if (res == SMP_RESP_NO_INDEX) { 1384 if (res == SMP_RESP_NO_INDEX) {
1383 SAS_DPRINTK("overflow of indexes: dev %016llx " 1385 SAS_DPRINTK("overflow of indexes: dev %016llx "
1384 "phy 0x%x index 0x%x\n", 1386 "phy 0x%x index 0x%x\n",
1385 SAS_ADDR(dev->sas_addr), phy_id, i); 1387 SAS_ADDR(dev->sas_addr), phy_id, i);
1386 goto out; 1388 goto out;
1387 } else if (res != SMP_RESP_FUNC_ACC) { 1389 } else if (res != SMP_RESP_FUNC_ACC) {
1388 SAS_DPRINTK("%s: dev %016llx phy 0x%x index 0x%x " 1390 SAS_DPRINTK("%s: dev %016llx phy 0x%x index 0x%x "
1389 "result 0x%x\n", __func__, 1391 "result 0x%x\n", __func__,
1390 SAS_ADDR(dev->sas_addr), phy_id, i, res); 1392 SAS_ADDR(dev->sas_addr), phy_id, i, res);
1391 goto out; 1393 goto out;
1392 } 1394 }
1393 if (SAS_ADDR(sas_addr) != 0) { 1395 if (SAS_ADDR(sas_addr) != 0) {
1394 if (SAS_ADDR(rri_resp+16) == SAS_ADDR(sas_addr)) { 1396 if (SAS_ADDR(rri_resp+16) == SAS_ADDR(sas_addr)) {
1395 *index = i; 1397 *index = i;
1396 if ((rri_resp[12] & 0x80) == 0x80) 1398 if ((rri_resp[12] & 0x80) == 0x80)
1397 *present = 0; 1399 *present = 0;
1398 else 1400 else
1399 *present = 1; 1401 *present = 1;
1400 goto out; 1402 goto out;
1401 } else if (SAS_ADDR(rri_resp+16) == 0) { 1403 } else if (SAS_ADDR(rri_resp+16) == 0) {
1402 *index = i; 1404 *index = i;
1403 *present = 0; 1405 *present = 0;
1404 goto out; 1406 goto out;
1405 } 1407 }
1406 } else if (SAS_ADDR(rri_resp+16) == 0 && 1408 } else if (SAS_ADDR(rri_resp+16) == 0 &&
1407 phy->last_da_index < i) { 1409 phy->last_da_index < i) {
1408 phy->last_da_index = i; 1410 phy->last_da_index = i;
1409 *index = i; 1411 *index = i;
1410 *present = 0; 1412 *present = 0;
1411 goto out; 1413 goto out;
1412 } 1414 }
1413 } 1415 }
1414 res = -1; 1416 res = -1;
1415 out: 1417 out:
1416 kfree(rri_req); 1418 kfree(rri_req);
1417 kfree(rri_resp); 1419 kfree(rri_resp);
1418 return res; 1420 return res;
1419 } 1421 }
1420 1422
1421 #define CRI_REQ_SIZE 44 1423 #define CRI_REQ_SIZE 44
1422 #define CRI_RESP_SIZE 8 1424 #define CRI_RESP_SIZE 8
1423 1425
1424 static int sas_configure_set(struct domain_device *dev, int phy_id, 1426 static int sas_configure_set(struct domain_device *dev, int phy_id,
1425 u8 *sas_addr, int index, int include) 1427 u8 *sas_addr, int index, int include)
1426 { 1428 {
1427 int res; 1429 int res;
1428 u8 *cri_req; 1430 u8 *cri_req;
1429 u8 *cri_resp; 1431 u8 *cri_resp;
1430 1432
1431 cri_req = alloc_smp_req(CRI_REQ_SIZE); 1433 cri_req = alloc_smp_req(CRI_REQ_SIZE);
1432 if (!cri_req) 1434 if (!cri_req)
1433 return -ENOMEM; 1435 return -ENOMEM;
1434 1436
1435 cri_resp = alloc_smp_resp(CRI_RESP_SIZE); 1437 cri_resp = alloc_smp_resp(CRI_RESP_SIZE);
1436 if (!cri_resp) { 1438 if (!cri_resp) {
1437 kfree(cri_req); 1439 kfree(cri_req);
1438 return -ENOMEM; 1440 return -ENOMEM;
1439 } 1441 }
1440 1442
1441 cri_req[1] = SMP_CONF_ROUTE_INFO; 1443 cri_req[1] = SMP_CONF_ROUTE_INFO;
1442 *(__be16 *)(cri_req+6) = cpu_to_be16(index); 1444 *(__be16 *)(cri_req+6) = cpu_to_be16(index);
1443 cri_req[9] = phy_id; 1445 cri_req[9] = phy_id;
1444 if (SAS_ADDR(sas_addr) == 0 || !include) 1446 if (SAS_ADDR(sas_addr) == 0 || !include)
1445 cri_req[12] |= 0x80; 1447 cri_req[12] |= 0x80;
1446 memcpy(cri_req+16, sas_addr, SAS_ADDR_SIZE); 1448 memcpy(cri_req+16, sas_addr, SAS_ADDR_SIZE);
1447 1449
1448 res = smp_execute_task(dev, cri_req, CRI_REQ_SIZE, cri_resp, 1450 res = smp_execute_task(dev, cri_req, CRI_REQ_SIZE, cri_resp,
1449 CRI_RESP_SIZE); 1451 CRI_RESP_SIZE);
1450 if (res) 1452 if (res)
1451 goto out; 1453 goto out;
1452 res = cri_resp[2]; 1454 res = cri_resp[2];
1453 if (res == SMP_RESP_NO_INDEX) { 1455 if (res == SMP_RESP_NO_INDEX) {
1454 SAS_DPRINTK("overflow of indexes: dev %016llx phy 0x%x " 1456 SAS_DPRINTK("overflow of indexes: dev %016llx phy 0x%x "
1455 "index 0x%x\n", 1457 "index 0x%x\n",
1456 SAS_ADDR(dev->sas_addr), phy_id, index); 1458 SAS_ADDR(dev->sas_addr), phy_id, index);
1457 } 1459 }
1458 out: 1460 out:
1459 kfree(cri_req); 1461 kfree(cri_req);
1460 kfree(cri_resp); 1462 kfree(cri_resp);
1461 return res; 1463 return res;
1462 } 1464 }
1463 1465
1464 static int sas_configure_phy(struct domain_device *dev, int phy_id, 1466 static int sas_configure_phy(struct domain_device *dev, int phy_id,
1465 u8 *sas_addr, int include) 1467 u8 *sas_addr, int include)
1466 { 1468 {
1467 int index; 1469 int index;
1468 int present; 1470 int present;
1469 int res; 1471 int res;
1470 1472
1471 res = sas_configure_present(dev, phy_id, sas_addr, &index, &present); 1473 res = sas_configure_present(dev, phy_id, sas_addr, &index, &present);
1472 if (res) 1474 if (res)
1473 return res; 1475 return res;
1474 if (include ^ present) 1476 if (include ^ present)
1475 return sas_configure_set(dev, phy_id, sas_addr, index,include); 1477 return sas_configure_set(dev, phy_id, sas_addr, index,include);
1476 1478
1477 return res; 1479 return res;
1478 } 1480 }
1479 1481
1480 /** 1482 /**
1481 * sas_configure_parent -- configure routing table of parent 1483 * sas_configure_parent -- configure routing table of parent
1482 * parent: parent expander 1484 * parent: parent expander
1483 * child: child expander 1485 * child: child expander
1484 * sas_addr: SAS port identifier of device directly attached to child 1486 * sas_addr: SAS port identifier of device directly attached to child
1485 */ 1487 */
1486 static int sas_configure_parent(struct domain_device *parent, 1488 static int sas_configure_parent(struct domain_device *parent,
1487 struct domain_device *child, 1489 struct domain_device *child,
1488 u8 *sas_addr, int include) 1490 u8 *sas_addr, int include)
1489 { 1491 {
1490 struct expander_device *ex_parent = &parent->ex_dev; 1492 struct expander_device *ex_parent = &parent->ex_dev;
1491 int res = 0; 1493 int res = 0;
1492 int i; 1494 int i;
1493 1495
1494 if (parent->parent) { 1496 if (parent->parent) {
1495 res = sas_configure_parent(parent->parent, parent, sas_addr, 1497 res = sas_configure_parent(parent->parent, parent, sas_addr,
1496 include); 1498 include);
1497 if (res) 1499 if (res)
1498 return res; 1500 return res;
1499 } 1501 }
1500 1502
1501 if (ex_parent->conf_route_table == 0) { 1503 if (ex_parent->conf_route_table == 0) {
1502 SAS_DPRINTK("ex %016llx has self-configuring routing table\n", 1504 SAS_DPRINTK("ex %016llx has self-configuring routing table\n",
1503 SAS_ADDR(parent->sas_addr)); 1505 SAS_ADDR(parent->sas_addr));
1504 return 0; 1506 return 0;
1505 } 1507 }
1506 1508
1507 for (i = 0; i < ex_parent->num_phys; i++) { 1509 for (i = 0; i < ex_parent->num_phys; i++) {
1508 struct ex_phy *phy = &ex_parent->ex_phy[i]; 1510 struct ex_phy *phy = &ex_parent->ex_phy[i];
1509 1511
1510 if ((phy->routing_attr == TABLE_ROUTING) && 1512 if ((phy->routing_attr == TABLE_ROUTING) &&
1511 (SAS_ADDR(phy->attached_sas_addr) == 1513 (SAS_ADDR(phy->attached_sas_addr) ==
1512 SAS_ADDR(child->sas_addr))) { 1514 SAS_ADDR(child->sas_addr))) {
1513 res = sas_configure_phy(parent, i, sas_addr, include); 1515 res = sas_configure_phy(parent, i, sas_addr, include);
1514 if (res) 1516 if (res)
1515 return res; 1517 return res;
1516 } 1518 }
1517 } 1519 }
1518 1520
1519 return res; 1521 return res;
1520 } 1522 }
1521 1523
1522 /** 1524 /**
1523 * sas_configure_routing -- configure routing 1525 * sas_configure_routing -- configure routing
1524 * dev: expander device 1526 * dev: expander device
1525 * sas_addr: port identifier of device directly attached to the expander device 1527 * sas_addr: port identifier of device directly attached to the expander device
1526 */ 1528 */
1527 static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr) 1529 static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr)
1528 { 1530 {
1529 if (dev->parent) 1531 if (dev->parent)
1530 return sas_configure_parent(dev->parent, dev, sas_addr, 1); 1532 return sas_configure_parent(dev->parent, dev, sas_addr, 1);
1531 return 0; 1533 return 0;
1532 } 1534 }
1533 1535
1534 static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr) 1536 static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr)
1535 { 1537 {
1536 if (dev->parent) 1538 if (dev->parent)
1537 return sas_configure_parent(dev->parent, dev, sas_addr, 0); 1539 return sas_configure_parent(dev->parent, dev, sas_addr, 0);
1538 return 0; 1540 return 0;
1539 } 1541 }
1540 1542
1541 /** 1543 /**
1542 * sas_discover_expander -- expander discovery 1544 * sas_discover_expander -- expander discovery
1543 * @ex: pointer to expander domain device 1545 * @ex: pointer to expander domain device
1544 * 1546 *
1545 * See comment in sas_discover_sata(). 1547 * See comment in sas_discover_sata().
1546 */ 1548 */
1547 static int sas_discover_expander(struct domain_device *dev) 1549 static int sas_discover_expander(struct domain_device *dev)
1548 { 1550 {
1549 int res; 1551 int res;
1550 1552
1551 res = sas_notify_lldd_dev_found(dev); 1553 res = sas_notify_lldd_dev_found(dev);
1552 if (res) 1554 if (res)
1553 return res; 1555 return res;
1554 1556
1555 res = sas_ex_general(dev); 1557 res = sas_ex_general(dev);
1556 if (res) 1558 if (res)
1557 goto out_err; 1559 goto out_err;
1558 res = sas_ex_manuf_info(dev); 1560 res = sas_ex_manuf_info(dev);
1559 if (res) 1561 if (res)
1560 goto out_err; 1562 goto out_err;
1561 1563
1562 res = sas_expander_discover(dev); 1564 res = sas_expander_discover(dev);
1563 if (res) { 1565 if (res) {
1564 SAS_DPRINTK("expander %016llx discovery failed(0x%x)\n", 1566 SAS_DPRINTK("expander %016llx discovery failed(0x%x)\n",
1565 SAS_ADDR(dev->sas_addr), res); 1567 SAS_ADDR(dev->sas_addr), res);
1566 goto out_err; 1568 goto out_err;
1567 } 1569 }
1568 1570
1569 sas_check_ex_subtractive_boundary(dev); 1571 sas_check_ex_subtractive_boundary(dev);
1570 res = sas_check_parent_topology(dev); 1572 res = sas_check_parent_topology(dev);
1571 if (res) 1573 if (res)
1572 goto out_err; 1574 goto out_err;
1573 return 0; 1575 return 0;
1574 out_err: 1576 out_err:
1575 sas_notify_lldd_dev_gone(dev); 1577 sas_notify_lldd_dev_gone(dev);
1576 return res; 1578 return res;
1577 } 1579 }
1578 1580
1579 static int sas_ex_level_discovery(struct asd_sas_port *port, const int level) 1581 static int sas_ex_level_discovery(struct asd_sas_port *port, const int level)
1580 { 1582 {
1581 int res = 0; 1583 int res = 0;
1582 struct domain_device *dev; 1584 struct domain_device *dev;
1583 1585
1584 list_for_each_entry(dev, &port->dev_list, dev_list_node) { 1586 list_for_each_entry(dev, &port->dev_list, dev_list_node) {
1585 if (dev->dev_type == EDGE_DEV || 1587 if (dev->dev_type == EDGE_DEV ||
1586 dev->dev_type == FANOUT_DEV) { 1588 dev->dev_type == FANOUT_DEV) {
1587 struct sas_expander_device *ex = 1589 struct sas_expander_device *ex =
1588 rphy_to_expander_device(dev->rphy); 1590 rphy_to_expander_device(dev->rphy);
1589 1591
1590 if (level == ex->level) 1592 if (level == ex->level)
1591 res = sas_ex_discover_devices(dev, -1); 1593 res = sas_ex_discover_devices(dev, -1);
1592 else if (level > 0) 1594 else if (level > 0)
1593 res = sas_ex_discover_devices(port->port_dev, -1); 1595 res = sas_ex_discover_devices(port->port_dev, -1);
1594 1596
1595 } 1597 }
1596 } 1598 }
1597 1599
1598 return res; 1600 return res;
1599 } 1601 }
1600 1602
1601 static int sas_ex_bfs_disc(struct asd_sas_port *port) 1603 static int sas_ex_bfs_disc(struct asd_sas_port *port)
1602 { 1604 {
1603 int res; 1605 int res;
1604 int level; 1606 int level;
1605 1607
1606 do { 1608 do {
1607 level = port->disc.max_level; 1609 level = port->disc.max_level;
1608 res = sas_ex_level_discovery(port, level); 1610 res = sas_ex_level_discovery(port, level);
1609 mb(); 1611 mb();
1610 } while (level < port->disc.max_level); 1612 } while (level < port->disc.max_level);
1611 1613
1612 return res; 1614 return res;
1613 } 1615 }
1614 1616
1615 int sas_discover_root_expander(struct domain_device *dev) 1617 int sas_discover_root_expander(struct domain_device *dev)
1616 { 1618 {
1617 int res; 1619 int res;
1618 struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy); 1620 struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy);
1619 1621
1620 res = sas_rphy_add(dev->rphy); 1622 res = sas_rphy_add(dev->rphy);
1621 if (res) 1623 if (res)
1622 goto out_err; 1624 goto out_err;
1623 1625
1624 ex->level = dev->port->disc.max_level; /* 0 */ 1626 ex->level = dev->port->disc.max_level; /* 0 */
1625 res = sas_discover_expander(dev); 1627 res = sas_discover_expander(dev);
1626 if (res) 1628 if (res)
1627 goto out_err2; 1629 goto out_err2;
1628 1630
1629 sas_ex_bfs_disc(dev->port); 1631 sas_ex_bfs_disc(dev->port);
1630 1632
1631 return res; 1633 return res;
1632 1634
1633 out_err2: 1635 out_err2:
1634 sas_rphy_remove(dev->rphy); 1636 sas_rphy_remove(dev->rphy);
1635 out_err: 1637 out_err:
1636 return res; 1638 return res;
1637 } 1639 }
1638 1640
1639 /* ---------- Domain revalidation ---------- */ 1641 /* ---------- Domain revalidation ---------- */
1640 1642
1641 static int sas_get_phy_discover(struct domain_device *dev, 1643 static int sas_get_phy_discover(struct domain_device *dev,
1642 int phy_id, struct smp_resp *disc_resp) 1644 int phy_id, struct smp_resp *disc_resp)
1643 { 1645 {
1644 int res; 1646 int res;
1645 u8 *disc_req; 1647 u8 *disc_req;
1646 1648
1647 disc_req = alloc_smp_req(DISCOVER_REQ_SIZE); 1649 disc_req = alloc_smp_req(DISCOVER_REQ_SIZE);
1648 if (!disc_req) 1650 if (!disc_req)
1649 return -ENOMEM; 1651 return -ENOMEM;
1650 1652
1651 disc_req[1] = SMP_DISCOVER; 1653 disc_req[1] = SMP_DISCOVER;
1652 disc_req[9] = phy_id; 1654 disc_req[9] = phy_id;
1653 1655
1654 res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE, 1656 res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
1655 disc_resp, DISCOVER_RESP_SIZE); 1657 disc_resp, DISCOVER_RESP_SIZE);
1656 if (res) 1658 if (res)
1657 goto out; 1659 goto out;
1658 else if (disc_resp->result != SMP_RESP_FUNC_ACC) { 1660 else if (disc_resp->result != SMP_RESP_FUNC_ACC) {
1659 res = disc_resp->result; 1661 res = disc_resp->result;
1660 goto out; 1662 goto out;
1661 } 1663 }
1662 out: 1664 out:
1663 kfree(disc_req); 1665 kfree(disc_req);
1664 return res; 1666 return res;
1665 } 1667 }
1666 1668
1667 static int sas_get_phy_change_count(struct domain_device *dev, 1669 static int sas_get_phy_change_count(struct domain_device *dev,
1668 int phy_id, int *pcc) 1670 int phy_id, int *pcc)
1669 { 1671 {
1670 int res; 1672 int res;
1671 struct smp_resp *disc_resp; 1673 struct smp_resp *disc_resp;
1672 1674
1673 disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE); 1675 disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
1674 if (!disc_resp) 1676 if (!disc_resp)
1675 return -ENOMEM; 1677 return -ENOMEM;
1676 1678
1677 res = sas_get_phy_discover(dev, phy_id, disc_resp); 1679 res = sas_get_phy_discover(dev, phy_id, disc_resp);
1678 if (!res) 1680 if (!res)
1679 *pcc = disc_resp->disc.change_count; 1681 *pcc = disc_resp->disc.change_count;
1680 1682
1681 kfree(disc_resp); 1683 kfree(disc_resp);
1682 return res; 1684 return res;
1683 } 1685 }
1684 1686
1685 static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id, 1687 static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
1686 u8 *sas_addr, enum sas_dev_type *type) 1688 u8 *sas_addr, enum sas_dev_type *type)
1687 { 1689 {
1688 int res; 1690 int res;
1689 struct smp_resp *disc_resp; 1691 struct smp_resp *disc_resp;
1690 struct discover_resp *dr; 1692 struct discover_resp *dr;
1691 1693
1692 disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE); 1694 disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
1693 if (!disc_resp) 1695 if (!disc_resp)
1694 return -ENOMEM; 1696 return -ENOMEM;
1695 dr = &disc_resp->disc; 1697 dr = &disc_resp->disc;
1696 1698
1697 res = sas_get_phy_discover(dev, phy_id, disc_resp); 1699 res = sas_get_phy_discover(dev, phy_id, disc_resp);
1698 if (res == 0) { 1700 if (res == 0) {
1699 memcpy(sas_addr, disc_resp->disc.attached_sas_addr, 8); 1701 memcpy(sas_addr, disc_resp->disc.attached_sas_addr, 8);
1700 *type = to_dev_type(dr); 1702 *type = to_dev_type(dr);
1701 if (*type == 0) 1703 if (*type == 0)
1702 memset(sas_addr, 0, 8); 1704 memset(sas_addr, 0, 8);
1703 } 1705 }
1704 kfree(disc_resp); 1706 kfree(disc_resp);
1705 return res; 1707 return res;
1706 } 1708 }
1707 1709
1708 static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id, 1710 static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id,
1709 int from_phy, bool update) 1711 int from_phy, bool update)
1710 { 1712 {
1711 struct expander_device *ex = &dev->ex_dev; 1713 struct expander_device *ex = &dev->ex_dev;
1712 int res = 0; 1714 int res = 0;
1713 int i; 1715 int i;
1714 1716
1715 for (i = from_phy; i < ex->num_phys; i++) { 1717 for (i = from_phy; i < ex->num_phys; i++) {
1716 int phy_change_count = 0; 1718 int phy_change_count = 0;
1717 1719
1718 res = sas_get_phy_change_count(dev, i, &phy_change_count); 1720 res = sas_get_phy_change_count(dev, i, &phy_change_count);
1719 if (res) 1721 if (res)
1720 goto out; 1722 goto out;
1721 else if (phy_change_count != ex->ex_phy[i].phy_change_count) { 1723 else if (phy_change_count != ex->ex_phy[i].phy_change_count) {
1722 if (update) 1724 if (update)
1723 ex->ex_phy[i].phy_change_count = 1725 ex->ex_phy[i].phy_change_count =
1724 phy_change_count; 1726 phy_change_count;
1725 *phy_id = i; 1727 *phy_id = i;
1726 return 0; 1728 return 0;
1727 } 1729 }
1728 } 1730 }
1729 out: 1731 out:
1730 return res; 1732 return res;
1731 } 1733 }
1732 1734
1733 static int sas_get_ex_change_count(struct domain_device *dev, int *ecc) 1735 static int sas_get_ex_change_count(struct domain_device *dev, int *ecc)
1734 { 1736 {
1735 int res; 1737 int res;
1736 u8 *rg_req; 1738 u8 *rg_req;
1737 struct smp_resp *rg_resp; 1739 struct smp_resp *rg_resp;
1738 1740
1739 rg_req = alloc_smp_req(RG_REQ_SIZE); 1741 rg_req = alloc_smp_req(RG_REQ_SIZE);
1740 if (!rg_req) 1742 if (!rg_req)
1741 return -ENOMEM; 1743 return -ENOMEM;
1742 1744
1743 rg_resp = alloc_smp_resp(RG_RESP_SIZE); 1745 rg_resp = alloc_smp_resp(RG_RESP_SIZE);
1744 if (!rg_resp) { 1746 if (!rg_resp) {
1745 kfree(rg_req); 1747 kfree(rg_req);
1746 return -ENOMEM; 1748 return -ENOMEM;
1747 } 1749 }
1748 1750
1749 rg_req[1] = SMP_REPORT_GENERAL; 1751 rg_req[1] = SMP_REPORT_GENERAL;
1750 1752
1751 res = smp_execute_task(dev, rg_req, RG_REQ_SIZE, rg_resp, 1753 res = smp_execute_task(dev, rg_req, RG_REQ_SIZE, rg_resp,
1752 RG_RESP_SIZE); 1754 RG_RESP_SIZE);
1753 if (res) 1755 if (res)
1754 goto out; 1756 goto out;
1755 if (rg_resp->result != SMP_RESP_FUNC_ACC) { 1757 if (rg_resp->result != SMP_RESP_FUNC_ACC) {
1756 res = rg_resp->result; 1758 res = rg_resp->result;
1757 goto out; 1759 goto out;
1758 } 1760 }
1759 1761
1760 *ecc = be16_to_cpu(rg_resp->rg.change_count); 1762 *ecc = be16_to_cpu(rg_resp->rg.change_count);
1761 out: 1763 out:
1762 kfree(rg_resp); 1764 kfree(rg_resp);
1763 kfree(rg_req); 1765 kfree(rg_req);
1764 return res; 1766 return res;
1765 } 1767 }
1766 /** 1768 /**
1767 * sas_find_bcast_dev - find the device issue BROADCAST(CHANGE). 1769 * sas_find_bcast_dev - find the device issue BROADCAST(CHANGE).
1768 * @dev:domain device to be detect. 1770 * @dev:domain device to be detect.
1769 * @src_dev: the device which originated BROADCAST(CHANGE). 1771 * @src_dev: the device which originated BROADCAST(CHANGE).
1770 * 1772 *
1771 * Add self-configuration expander suport. Suppose two expander cascading, 1773 * Add self-configuration expander suport. Suppose two expander cascading,
1772 * when the first level expander is self-configuring, hotplug the disks in 1774 * when the first level expander is self-configuring, hotplug the disks in
1773 * second level expander, BROADCAST(CHANGE) will not only be originated 1775 * second level expander, BROADCAST(CHANGE) will not only be originated
1774 * in the second level expander, but also be originated in the first level 1776 * in the second level expander, but also be originated in the first level
1775 * expander (see SAS protocol SAS 2r-14, 7.11 for detail), it is to say, 1777 * expander (see SAS protocol SAS 2r-14, 7.11 for detail), it is to say,
1776 * expander changed count in two level expanders will all increment at least 1778 * expander changed count in two level expanders will all increment at least
1777 * once, but the phy which chang count has changed is the source device which 1779 * once, but the phy which chang count has changed is the source device which
1778 * we concerned. 1780 * we concerned.
1779 */ 1781 */
1780 1782
1781 static int sas_find_bcast_dev(struct domain_device *dev, 1783 static int sas_find_bcast_dev(struct domain_device *dev,
1782 struct domain_device **src_dev) 1784 struct domain_device **src_dev)
1783 { 1785 {
1784 struct expander_device *ex = &dev->ex_dev; 1786 struct expander_device *ex = &dev->ex_dev;
1785 int ex_change_count = -1; 1787 int ex_change_count = -1;
1786 int phy_id = -1; 1788 int phy_id = -1;
1787 int res; 1789 int res;
1788 struct domain_device *ch; 1790 struct domain_device *ch;
1789 1791
1790 res = sas_get_ex_change_count(dev, &ex_change_count); 1792 res = sas_get_ex_change_count(dev, &ex_change_count);
1791 if (res) 1793 if (res)
1792 goto out; 1794 goto out;
1793 if (ex_change_count != -1 && ex_change_count != ex->ex_change_count) { 1795 if (ex_change_count != -1 && ex_change_count != ex->ex_change_count) {
1794 /* Just detect if this expander phys phy change count changed, 1796 /* Just detect if this expander phys phy change count changed,
1795 * in order to determine if this expander originate BROADCAST, 1797 * in order to determine if this expander originate BROADCAST,
1796 * and do not update phy change count field in our structure. 1798 * and do not update phy change count field in our structure.
1797 */ 1799 */
1798 res = sas_find_bcast_phy(dev, &phy_id, 0, false); 1800 res = sas_find_bcast_phy(dev, &phy_id, 0, false);
1799 if (phy_id != -1) { 1801 if (phy_id != -1) {
1800 *src_dev = dev; 1802 *src_dev = dev;
1801 ex->ex_change_count = ex_change_count; 1803 ex->ex_change_count = ex_change_count;
1802 SAS_DPRINTK("Expander phy change count has changed\n"); 1804 SAS_DPRINTK("Expander phy change count has changed\n");
1803 return res; 1805 return res;
1804 } else 1806 } else
1805 SAS_DPRINTK("Expander phys DID NOT change\n"); 1807 SAS_DPRINTK("Expander phys DID NOT change\n");
1806 } 1808 }
1807 list_for_each_entry(ch, &ex->children, siblings) { 1809 list_for_each_entry(ch, &ex->children, siblings) {
1808 if (ch->dev_type == EDGE_DEV || ch->dev_type == FANOUT_DEV) { 1810 if (ch->dev_type == EDGE_DEV || ch->dev_type == FANOUT_DEV) {
1809 res = sas_find_bcast_dev(ch, src_dev); 1811 res = sas_find_bcast_dev(ch, src_dev);
1810 if (*src_dev) 1812 if (*src_dev)
1811 return res; 1813 return res;
1812 } 1814 }
1813 } 1815 }
1814 out: 1816 out:
1815 return res; 1817 return res;
1816 } 1818 }
1817 1819
1818 static void sas_unregister_ex_tree(struct asd_sas_port *port, struct domain_device *dev) 1820 static void sas_unregister_ex_tree(struct asd_sas_port *port, struct domain_device *dev)
1819 { 1821 {
1820 struct expander_device *ex = &dev->ex_dev; 1822 struct expander_device *ex = &dev->ex_dev;
1821 struct domain_device *child, *n; 1823 struct domain_device *child, *n;
1822 1824
1823 list_for_each_entry_safe(child, n, &ex->children, siblings) { 1825 list_for_each_entry_safe(child, n, &ex->children, siblings) {
1824 set_bit(SAS_DEV_GONE, &child->state); 1826 set_bit(SAS_DEV_GONE, &child->state);
1825 if (child->dev_type == EDGE_DEV || 1827 if (child->dev_type == EDGE_DEV ||
1826 child->dev_type == FANOUT_DEV) 1828 child->dev_type == FANOUT_DEV)
1827 sas_unregister_ex_tree(port, child); 1829 sas_unregister_ex_tree(port, child);
1828 else 1830 else
1829 sas_unregister_dev(port, child); 1831 sas_unregister_dev(port, child);
1830 } 1832 }
1831 sas_unregister_dev(port, dev); 1833 sas_unregister_dev(port, dev);
1832 } 1834 }
1833 1835
1834 static void sas_unregister_devs_sas_addr(struct domain_device *parent, 1836 static void sas_unregister_devs_sas_addr(struct domain_device *parent,
1835 int phy_id, bool last) 1837 int phy_id, bool last)
1836 { 1838 {
1837 struct expander_device *ex_dev = &parent->ex_dev; 1839 struct expander_device *ex_dev = &parent->ex_dev;
1838 struct ex_phy *phy = &ex_dev->ex_phy[phy_id]; 1840 struct ex_phy *phy = &ex_dev->ex_phy[phy_id];
1839 struct domain_device *child, *n, *found = NULL; 1841 struct domain_device *child, *n, *found = NULL;
1840 if (last) { 1842 if (last) {
1841 list_for_each_entry_safe(child, n, 1843 list_for_each_entry_safe(child, n,
1842 &ex_dev->children, siblings) { 1844 &ex_dev->children, siblings) {
1843 if (SAS_ADDR(child->sas_addr) == 1845 if (SAS_ADDR(child->sas_addr) ==
1844 SAS_ADDR(phy->attached_sas_addr)) { 1846 SAS_ADDR(phy->attached_sas_addr)) {
1845 set_bit(SAS_DEV_GONE, &child->state); 1847 set_bit(SAS_DEV_GONE, &child->state);
1846 if (child->dev_type == EDGE_DEV || 1848 if (child->dev_type == EDGE_DEV ||
1847 child->dev_type == FANOUT_DEV) 1849 child->dev_type == FANOUT_DEV)
1848 sas_unregister_ex_tree(parent->port, child); 1850 sas_unregister_ex_tree(parent->port, child);
1849 else 1851 else
1850 sas_unregister_dev(parent->port, child); 1852 sas_unregister_dev(parent->port, child);
1851 found = child; 1853 found = child;
1852 break; 1854 break;
1853 } 1855 }
1854 } 1856 }
1855 sas_disable_routing(parent, phy->attached_sas_addr); 1857 sas_disable_routing(parent, phy->attached_sas_addr);
1856 } 1858 }
1857 memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); 1859 memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
1858 if (phy->port) { 1860 if (phy->port) {
1859 sas_port_delete_phy(phy->port, phy->phy); 1861 sas_port_delete_phy(phy->port, phy->phy);
1860 sas_device_set_phy(found, phy->port); 1862 sas_device_set_phy(found, phy->port);
1861 if (phy->port->num_phys == 0) 1863 if (phy->port->num_phys == 0)
1862 sas_port_delete(phy->port); 1864 sas_port_delete(phy->port);
1863 phy->port = NULL; 1865 phy->port = NULL;
1864 } 1866 }
1865 } 1867 }
1866 1868
1867 static int sas_discover_bfs_by_root_level(struct domain_device *root, 1869 static int sas_discover_bfs_by_root_level(struct domain_device *root,
1868 const int level) 1870 const int level)
1869 { 1871 {
1870 struct expander_device *ex_root = &root->ex_dev; 1872 struct expander_device *ex_root = &root->ex_dev;
1871 struct domain_device *child; 1873 struct domain_device *child;
1872 int res = 0; 1874 int res = 0;
1873 1875
1874 list_for_each_entry(child, &ex_root->children, siblings) { 1876 list_for_each_entry(child, &ex_root->children, siblings) {
1875 if (child->dev_type == EDGE_DEV || 1877 if (child->dev_type == EDGE_DEV ||
1876 child->dev_type == FANOUT_DEV) { 1878 child->dev_type == FANOUT_DEV) {
1877 struct sas_expander_device *ex = 1879 struct sas_expander_device *ex =
1878 rphy_to_expander_device(child->rphy); 1880 rphy_to_expander_device(child->rphy);
1879 1881
1880 if (level > ex->level) 1882 if (level > ex->level)
1881 res = sas_discover_bfs_by_root_level(child, 1883 res = sas_discover_bfs_by_root_level(child,
1882 level); 1884 level);
1883 else if (level == ex->level) 1885 else if (level == ex->level)
1884 res = sas_ex_discover_devices(child, -1); 1886 res = sas_ex_discover_devices(child, -1);
1885 } 1887 }
1886 } 1888 }
1887 return res; 1889 return res;
1888 } 1890 }
1889 1891
1890 static int sas_discover_bfs_by_root(struct domain_device *dev) 1892 static int sas_discover_bfs_by_root(struct domain_device *dev)
1891 { 1893 {
1892 int res; 1894 int res;
1893 struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy); 1895 struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy);
1894 int level = ex->level+1; 1896 int level = ex->level+1;
1895 1897
1896 res = sas_ex_discover_devices(dev, -1); 1898 res = sas_ex_discover_devices(dev, -1);
1897 if (res) 1899 if (res)
1898 goto out; 1900 goto out;
1899 do { 1901 do {
1900 res = sas_discover_bfs_by_root_level(dev, level); 1902 res = sas_discover_bfs_by_root_level(dev, level);
1901 mb(); 1903 mb();
1902 level += 1; 1904 level += 1;
1903 } while (level <= dev->port->disc.max_level); 1905 } while (level <= dev->port->disc.max_level);
1904 out: 1906 out:
1905 return res; 1907 return res;
1906 } 1908 }
1907 1909
1908 static int sas_discover_new(struct domain_device *dev, int phy_id) 1910 static int sas_discover_new(struct domain_device *dev, int phy_id)
1909 { 1911 {
1910 struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id]; 1912 struct ex_phy *ex_phy = &dev->ex_dev.ex_phy[phy_id];
1911 struct domain_device *child; 1913 struct domain_device *child;
1912 bool found = false; 1914 bool found = false;
1913 int res, i; 1915 int res, i;
1914 1916
1915 SAS_DPRINTK("ex %016llx phy%d new device attached\n", 1917 SAS_DPRINTK("ex %016llx phy%d new device attached\n",
1916 SAS_ADDR(dev->sas_addr), phy_id); 1918 SAS_ADDR(dev->sas_addr), phy_id);
1917 res = sas_ex_phy_discover(dev, phy_id); 1919 res = sas_ex_phy_discover(dev, phy_id);
1918 if (res) 1920 if (res)
1919 goto out; 1921 goto out;
1920 /* to support the wide port inserted */ 1922 /* to support the wide port inserted */
1921 for (i = 0; i < dev->ex_dev.num_phys; i++) { 1923 for (i = 0; i < dev->ex_dev.num_phys; i++) {
1922 struct ex_phy *ex_phy_temp = &dev->ex_dev.ex_phy[i]; 1924 struct ex_phy *ex_phy_temp = &dev->ex_dev.ex_phy[i];
1923 if (i == phy_id) 1925 if (i == phy_id)
1924 continue; 1926 continue;
1925 if (SAS_ADDR(ex_phy_temp->attached_sas_addr) == 1927 if (SAS_ADDR(ex_phy_temp->attached_sas_addr) ==
1926 SAS_ADDR(ex_phy->attached_sas_addr)) { 1928 SAS_ADDR(ex_phy->attached_sas_addr)) {
1927 found = true; 1929 found = true;
1928 break; 1930 break;
1929 } 1931 }
1930 } 1932 }
1931 if (found) { 1933 if (found) {
1932 sas_ex_join_wide_port(dev, phy_id); 1934 sas_ex_join_wide_port(dev, phy_id);
1933 return 0; 1935 return 0;
1934 } 1936 }
1935 res = sas_ex_discover_devices(dev, phy_id); 1937 res = sas_ex_discover_devices(dev, phy_id);
1936 if (!res) 1938 if (!res)
1937 goto out; 1939 goto out;
1938 list_for_each_entry(child, &dev->ex_dev.children, siblings) { 1940 list_for_each_entry(child, &dev->ex_dev.children, siblings) {
1939 if (SAS_ADDR(child->sas_addr) == 1941 if (SAS_ADDR(child->sas_addr) ==
1940 SAS_ADDR(ex_phy->attached_sas_addr)) { 1942 SAS_ADDR(ex_phy->attached_sas_addr)) {
1941 if (child->dev_type == EDGE_DEV || 1943 if (child->dev_type == EDGE_DEV ||
1942 child->dev_type == FANOUT_DEV) 1944 child->dev_type == FANOUT_DEV)
1943 res = sas_discover_bfs_by_root(child); 1945 res = sas_discover_bfs_by_root(child);
1944 break; 1946 break;
1945 } 1947 }
1946 } 1948 }
1947 out: 1949 out:
1948 return res; 1950 return res;
1949 } 1951 }
1950 1952
1951 static bool dev_type_flutter(enum sas_dev_type new, enum sas_dev_type old) 1953 static bool dev_type_flutter(enum sas_dev_type new, enum sas_dev_type old)
1952 { 1954 {
1953 if (old == new) 1955 if (old == new)
1954 return true; 1956 return true;
1955 1957
1956 /* treat device directed resets as flutter, if we went 1958 /* treat device directed resets as flutter, if we went
1957 * SAS_END_DEV to SATA_PENDING the link needs recovery 1959 * SAS_END_DEV to SATA_PENDING the link needs recovery
1958 */ 1960 */
1959 if ((old == SATA_PENDING && new == SAS_END_DEV) || 1961 if ((old == SATA_PENDING && new == SAS_END_DEV) ||
1960 (old == SAS_END_DEV && new == SATA_PENDING)) 1962 (old == SAS_END_DEV && new == SATA_PENDING))
1961 return true; 1963 return true;
1962 1964
1963 return false; 1965 return false;
1964 } 1966 }
1965 1967
1966 static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) 1968 static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last)
1967 { 1969 {
1968 struct expander_device *ex = &dev->ex_dev; 1970 struct expander_device *ex = &dev->ex_dev;
1969 struct ex_phy *phy = &ex->ex_phy[phy_id]; 1971 struct ex_phy *phy = &ex->ex_phy[phy_id];
1970 enum sas_dev_type type = NO_DEVICE; 1972 enum sas_dev_type type = NO_DEVICE;
1971 u8 sas_addr[8]; 1973 u8 sas_addr[8];
1972 int res; 1974 int res;
1973 1975
1974 res = sas_get_phy_attached_dev(dev, phy_id, sas_addr, &type); 1976 res = sas_get_phy_attached_dev(dev, phy_id, sas_addr, &type);
1975 switch (res) { 1977 switch (res) {
1976 case SMP_RESP_NO_PHY: 1978 case SMP_RESP_NO_PHY:
1977 phy->phy_state = PHY_NOT_PRESENT; 1979 phy->phy_state = PHY_NOT_PRESENT;
1978 sas_unregister_devs_sas_addr(dev, phy_id, last); 1980 sas_unregister_devs_sas_addr(dev, phy_id, last);
1979 return res; 1981 return res;
1980 case SMP_RESP_PHY_VACANT: 1982 case SMP_RESP_PHY_VACANT:
1981 phy->phy_state = PHY_VACANT; 1983 phy->phy_state = PHY_VACANT;
1982 sas_unregister_devs_sas_addr(dev, phy_id, last); 1984 sas_unregister_devs_sas_addr(dev, phy_id, last);
1983 return res; 1985 return res;
1984 case SMP_RESP_FUNC_ACC: 1986 case SMP_RESP_FUNC_ACC:
1985 break; 1987 break;
1986 } 1988 }
1987 1989
1988 if (SAS_ADDR(sas_addr) == 0) { 1990 if (SAS_ADDR(sas_addr) == 0) {
1989 phy->phy_state = PHY_EMPTY; 1991 phy->phy_state = PHY_EMPTY;
1990 sas_unregister_devs_sas_addr(dev, phy_id, last); 1992 sas_unregister_devs_sas_addr(dev, phy_id, last);
1991 return res; 1993 return res;
1992 } else if (SAS_ADDR(sas_addr) == SAS_ADDR(phy->attached_sas_addr) && 1994 } else if (SAS_ADDR(sas_addr) == SAS_ADDR(phy->attached_sas_addr) &&
1993 dev_type_flutter(type, phy->attached_dev_type)) { 1995 dev_type_flutter(type, phy->attached_dev_type)) {
1994 struct domain_device *ata_dev = sas_ex_to_ata(dev, phy_id); 1996 struct domain_device *ata_dev = sas_ex_to_ata(dev, phy_id);
1995 char *action = ""; 1997 char *action = "";
1996 1998
1997 sas_ex_phy_discover(dev, phy_id); 1999 sas_ex_phy_discover(dev, phy_id);
1998 2000
1999 if (ata_dev && phy->attached_dev_type == SATA_PENDING) 2001 if (ata_dev && phy->attached_dev_type == SATA_PENDING)
2000 action = ", needs recovery"; 2002 action = ", needs recovery";
2001 SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter%s\n", 2003 SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter%s\n",
2002 SAS_ADDR(dev->sas_addr), phy_id, action); 2004 SAS_ADDR(dev->sas_addr), phy_id, action);
2003 return res; 2005 return res;
2004 } 2006 }
2005 2007
2006 /* delete the old link */ 2008 /* delete the old link */
2007 if (SAS_ADDR(phy->attached_sas_addr) && 2009 if (SAS_ADDR(phy->attached_sas_addr) &&
2008 SAS_ADDR(sas_addr) != SAS_ADDR(phy->attached_sas_addr)) { 2010 SAS_ADDR(sas_addr) != SAS_ADDR(phy->attached_sas_addr)) {
2009 SAS_DPRINTK("ex %016llx phy 0x%x replace %016llx\n", 2011 SAS_DPRINTK("ex %016llx phy 0x%x replace %016llx\n",
2010 SAS_ADDR(dev->sas_addr), phy_id, 2012 SAS_ADDR(dev->sas_addr), phy_id,
2011 SAS_ADDR(phy->attached_sas_addr)); 2013 SAS_ADDR(phy->attached_sas_addr));
2012 sas_unregister_devs_sas_addr(dev, phy_id, last); 2014 sas_unregister_devs_sas_addr(dev, phy_id, last);
2013 } 2015 }
2014 2016
2015 return sas_discover_new(dev, phy_id); 2017 return sas_discover_new(dev, phy_id);
2016 } 2018 }
2017 2019
2018 /** 2020 /**
2019 * sas_rediscover - revalidate the domain. 2021 * sas_rediscover - revalidate the domain.
2020 * @dev:domain device to be detect. 2022 * @dev:domain device to be detect.
2021 * @phy_id: the phy id will be detected. 2023 * @phy_id: the phy id will be detected.
2022 * 2024 *
2023 * NOTE: this process _must_ quit (return) as soon as any connection 2025 * NOTE: this process _must_ quit (return) as soon as any connection
2024 * errors are encountered. Connection recovery is done elsewhere. 2026 * errors are encountered. Connection recovery is done elsewhere.
2025 * Discover process only interrogates devices in order to discover the 2027 * Discover process only interrogates devices in order to discover the
2026 * domain.For plugging out, we un-register the device only when it is 2028 * domain.For plugging out, we un-register the device only when it is
2027 * the last phy in the port, for other phys in this port, we just delete it 2029 * the last phy in the port, for other phys in this port, we just delete it
2028 * from the port.For inserting, we do discovery when it is the 2030 * from the port.For inserting, we do discovery when it is the
2029 * first phy,for other phys in this port, we add it to the port to 2031 * first phy,for other phys in this port, we add it to the port to
2030 * forming the wide-port. 2032 * forming the wide-port.
2031 */ 2033 */
2032 static int sas_rediscover(struct domain_device *dev, const int phy_id) 2034 static int sas_rediscover(struct domain_device *dev, const int phy_id)
2033 { 2035 {
2034 struct expander_device *ex = &dev->ex_dev; 2036 struct expander_device *ex = &dev->ex_dev;
2035 struct ex_phy *changed_phy = &ex->ex_phy[phy_id]; 2037 struct ex_phy *changed_phy = &ex->ex_phy[phy_id];
2036 int res = 0; 2038 int res = 0;
2037 int i; 2039 int i;
2038 bool last = true; /* is this the last phy of the port */ 2040 bool last = true; /* is this the last phy of the port */
2039 2041
2040 SAS_DPRINTK("ex %016llx phy%d originated BROADCAST(CHANGE)\n", 2042 SAS_DPRINTK("ex %016llx phy%d originated BROADCAST(CHANGE)\n",
2041 SAS_ADDR(dev->sas_addr), phy_id); 2043 SAS_ADDR(dev->sas_addr), phy_id);
2042 2044
2043 if (SAS_ADDR(changed_phy->attached_sas_addr) != 0) { 2045 if (SAS_ADDR(changed_phy->attached_sas_addr) != 0) {
2044 for (i = 0; i < ex->num_phys; i++) { 2046 for (i = 0; i < ex->num_phys; i++) {
2045 struct ex_phy *phy = &ex->ex_phy[i]; 2047 struct ex_phy *phy = &ex->ex_phy[i];
2046 2048
2047 if (i == phy_id) 2049 if (i == phy_id)
2048 continue; 2050 continue;
2049 if (SAS_ADDR(phy->attached_sas_addr) == 2051 if (SAS_ADDR(phy->attached_sas_addr) ==
2050 SAS_ADDR(changed_phy->attached_sas_addr)) { 2052 SAS_ADDR(changed_phy->attached_sas_addr)) {
2051 SAS_DPRINTK("phy%d part of wide port with " 2053 SAS_DPRINTK("phy%d part of wide port with "
2052 "phy%d\n", phy_id, i); 2054 "phy%d\n", phy_id, i);
2053 last = false; 2055 last = false;
2054 break; 2056 break;
2055 } 2057 }
2056 } 2058 }
2057 res = sas_rediscover_dev(dev, phy_id, last); 2059 res = sas_rediscover_dev(dev, phy_id, last);
2058 } else 2060 } else
2059 res = sas_discover_new(dev, phy_id); 2061 res = sas_discover_new(dev, phy_id);
2060 return res; 2062 return res;
2061 } 2063 }
2062 2064
2063 /** 2065 /**
2064 * sas_revalidate_domain -- revalidate the domain 2066 * sas_revalidate_domain -- revalidate the domain
2065 * @port: port to the domain of interest 2067 * @port: port to the domain of interest
2066 * 2068 *
2067 * NOTE: this process _must_ quit (return) as soon as any connection 2069 * NOTE: this process _must_ quit (return) as soon as any connection
2068 * errors are encountered. Connection recovery is done elsewhere. 2070 * errors are encountered. Connection recovery is done elsewhere.
2069 * Discover process only interrogates devices in order to discover the 2071 * Discover process only interrogates devices in order to discover the
2070 * domain. 2072 * domain.
2071 */ 2073 */
2072 int sas_ex_revalidate_domain(struct domain_device *port_dev) 2074 int sas_ex_revalidate_domain(struct domain_device *port_dev)
2073 { 2075 {
2074 int res; 2076 int res;
2075 struct domain_device *dev = NULL; 2077 struct domain_device *dev = NULL;
2076 2078
2077 res = sas_find_bcast_dev(port_dev, &dev); 2079 res = sas_find_bcast_dev(port_dev, &dev);
2078 if (res) 2080 if (res)
2079 goto out; 2081 goto out;
2080 if (dev) { 2082 if (dev) {
2081 struct expander_device *ex = &dev->ex_dev; 2083 struct expander_device *ex = &dev->ex_dev;
2082 int i = 0, phy_id; 2084 int i = 0, phy_id;
2083 2085
2084 do { 2086 do {
2085 phy_id = -1; 2087 phy_id = -1;
2086 res = sas_find_bcast_phy(dev, &phy_id, i, true); 2088 res = sas_find_bcast_phy(dev, &phy_id, i, true);
2087 if (phy_id == -1) 2089 if (phy_id == -1)
2088 break; 2090 break;
2089 res = sas_rediscover(dev, phy_id); 2091 res = sas_rediscover(dev, phy_id);
2090 i = phy_id + 1; 2092 i = phy_id + 1;
2091 } while (i < ex->num_phys); 2093 } while (i < ex->num_phys);
2092 } 2094 }
2093 out: 2095 out:
2094 return res; 2096 return res;
2095 } 2097 }
2096 2098
2097 int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, 2099 int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
2098 struct request *req) 2100 struct request *req)
2099 { 2101 {
2100 struct domain_device *dev; 2102 struct domain_device *dev;
2101 int ret, type; 2103 int ret, type;
2102 struct request *rsp = req->next_rq; 2104 struct request *rsp = req->next_rq;
2103 2105
2104 if (!rsp) { 2106 if (!rsp) {
2105 printk("%s: space for a smp response is missing\n", 2107 printk("%s: space for a smp response is missing\n",
2106 __func__); 2108 __func__);
2107 return -EINVAL; 2109 return -EINVAL;
2108 } 2110 }
2109 2111
2110 /* no rphy means no smp target support (ie aic94xx host) */ 2112 /* no rphy means no smp target support (ie aic94xx host) */
2111 if (!rphy) 2113 if (!rphy)
2112 return sas_smp_host_handler(shost, req, rsp); 2114 return sas_smp_host_handler(shost, req, rsp);
2113 2115
2114 type = rphy->identify.device_type; 2116 type = rphy->identify.device_type;
2115 2117
2116 if (type != SAS_EDGE_EXPANDER_DEVICE && 2118 if (type != SAS_EDGE_EXPANDER_DEVICE &&
2117 type != SAS_FANOUT_EXPANDER_DEVICE) { 2119 type != SAS_FANOUT_EXPANDER_DEVICE) {
2118 printk("%s: can we send a smp request to a device?\n", 2120 printk("%s: can we send a smp request to a device?\n",
2119 __func__); 2121 __func__);
2120 return -EINVAL; 2122 return -EINVAL;
2121 } 2123 }
2122 2124
2123 dev = sas_find_dev_by_rphy(rphy); 2125 dev = sas_find_dev_by_rphy(rphy);
2124 if (!dev) { 2126 if (!dev) {
2125 printk("%s: fail to find a domain_device?\n", __func__); 2127 printk("%s: fail to find a domain_device?\n", __func__);
2126 return -EINVAL; 2128 return -EINVAL;
2127 } 2129 }
2128 2130
2129 /* do we need to support multiple segments? */ 2131 /* do we need to support multiple segments? */
2130 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { 2132 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
2131 printk("%s: multiple segments req %u %u, rsp %u %u\n", 2133 printk("%s: multiple segments req %u %u, rsp %u %u\n",
2132 __func__, req->bio->bi_vcnt, blk_rq_bytes(req), 2134 __func__, req->bio->bi_vcnt, blk_rq_bytes(req),
2133 rsp->bio->bi_vcnt, blk_rq_bytes(rsp)); 2135 rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
2134 return -EINVAL; 2136 return -EINVAL;
2135 } 2137 }
2136 2138
2137 ret = smp_execute_task(dev, bio_data(req->bio), blk_rq_bytes(req), 2139 ret = smp_execute_task(dev, bio_data(req->bio), blk_rq_bytes(req),
2138 bio_data(rsp->bio), blk_rq_bytes(rsp)); 2140 bio_data(rsp->bio), blk_rq_bytes(rsp));
2139 if (ret > 0) { 2141 if (ret > 0) {
2140 /* positive number is the untransferred residual */ 2142 /* positive number is the untransferred residual */
2141 rsp->resid_len = ret; 2143 rsp->resid_len = ret;
2142 req->resid_len = 0; 2144 req->resid_len = 0;
2143 ret = 0; 2145 ret = 0;
2144 } else if (ret == 0) { 2146 } else if (ret == 0) {
2145 rsp->resid_len = 0; 2147 rsp->resid_len = 0;
2146 req->resid_len = 0; 2148 req->resid_len = 0;
2147 } 2149 }
2148 2150
2149 return ret; 2151 return ret;
2150 } 2152 }
2151 2153