[SCSI] mpt fusion: adding/removing white space
[linux-block.git] / drivers / message / fusion / mptsas.c
CommitLineData
0c33b27d
CH
1/*
2 * linux/drivers/message/fusion/mptsas.c
f36789e2
PS
3 * For use with LSI PCI chip/adapter(s)
4 * running LSI Fusion MPT (Message Passing Technology) firmware.
0c33b27d 5 *
f36789e2 6 * Copyright (c) 1999-2007 LSI Corporation
16d20101 7 * (mailto:DL-MPTFusionLinux@lsi.com)
9f4203b3 8 * Copyright (c) 2005-2007 Dell
0c33b27d
CH
9 */
10/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11/*
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; version 2 of the License.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 NO WARRANTY
22 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26 solely responsible for determining the appropriateness of using and
27 distributing the Program and assumes all risks associated with its
28 exercise of rights under this Agreement, including but not limited to
29 the risks and costs of program errors, damage to or loss of data,
30 programs or equipment, and unavailability or interruption of operations.
31
32 DISCLAIMER OF LIABILITY
33 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40
41 You should have received a copy of the GNU General Public License
42 along with this program; if not, write to the Free Software
43 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
44*/
45/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46
47#include <linux/module.h>
48#include <linux/kernel.h>
49#include <linux/init.h>
50#include <linux/errno.h>
cd354f1a 51#include <linux/jiffies.h>
0c33b27d 52#include <linux/workqueue.h>
547f9a21 53#include <linux/delay.h> /* for mdelay */
0c33b27d 54
547f9a21 55#include <scsi/scsi.h>
0c33b27d
CH
56#include <scsi/scsi_cmnd.h>
57#include <scsi/scsi_device.h>
58#include <scsi/scsi_host.h>
59#include <scsi/scsi_transport_sas.h>
547f9a21 60#include <scsi/scsi_dbg.h>
0c33b27d
CH
61
62#include "mptbase.h"
63#include "mptscsih.h"
56af97ae 64#include "mptsas.h"
0c33b27d
CH
65
66
67#define my_NAME "Fusion MPT SAS Host driver"
68#define my_VERSION MPT_LINUX_VERSION_COMMON
69#define MYNAM "mptsas"
70
e8bf3941
JB
71/*
72 * Reserved channel for integrated raid
73 */
74#define MPTSAS_RAID_CHANNEL 1
75
0c33b27d
CH
76MODULE_AUTHOR(MODULEAUTHOR);
77MODULE_DESCRIPTION(my_NAME);
78MODULE_LICENSE("GPL");
9f4203b3 79MODULE_VERSION(my_VERSION);
0c33b27d 80
0c33b27d
CH
81static int mpt_pt_clear;
82module_param(mpt_pt_clear, int, 0);
83MODULE_PARM_DESC(mpt_pt_clear,
ba856d32 84 " Clear persistency table: enable=1 "
0c33b27d
CH
85 "(default=MPTSCSIH_PT_CLEAR=0)");
86
793955f5
EM
87/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
88#define MPTSAS_MAX_LUN (16895)
89static int max_lun = MPTSAS_MAX_LUN;
90module_param(max_lun, int, 0);
91MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
92
f606f571
PS
93static u8 mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
94static u8 mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
95static u8 mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
96static u8 mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
0c33b27d 97
b506ade9 98static void mptsas_hotplug_work(struct work_struct *work);
0c33b27d 99
d6ecdd63
PS
100static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
101 MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
102{
29dd3609
EM
103 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
104 "---- IO UNIT PAGE 0 ------------\n", ioc->name));
105 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
106 ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
107 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
108 ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
109 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
110 ioc->name, phy_data->Port));
111 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
112 ioc->name, phy_data->PortFlags));
113 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
114 ioc->name, phy_data->PhyFlags));
115 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
116 ioc->name, phy_data->NegotiatedLinkRate));
117 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
118 "Controller PHY Device Info=0x%X\n", ioc->name,
119 le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
120 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
121 ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
b5141128
CH
122}
123
d6ecdd63 124static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
b5141128
CH
125{
126 __le64 sas_address;
127
128 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
129
29dd3609
EM
130 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
131 "---- SAS PHY PAGE 0 ------------\n", ioc->name));
132 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
133 "Attached Device Handle=0x%X\n", ioc->name,
134 le16_to_cpu(pg0->AttachedDevHandle)));
135 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
136 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
137 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
138 "Attached PHY Identifier=0x%X\n", ioc->name,
139 pg0->AttachedPhyIdentifier));
140 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
141 ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
142 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
143 ioc->name, pg0->ProgrammedLinkRate));
144 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
145 ioc->name, pg0->ChangeCount));
146 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
147 ioc->name, le32_to_cpu(pg0->PhyInfo)));
b5141128
CH
148}
149
d6ecdd63 150static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
b5141128 151{
29dd3609
EM
152 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
153 "---- SAS PHY PAGE 1 ------------\n", ioc->name));
154 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
155 ioc->name, pg1->InvalidDwordCount));
156 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
157 "Running Disparity Error Count=0x%x\n", ioc->name,
158 pg1->RunningDisparityErrorCount));
159 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
160 "Loss Dword Synch Count=0x%x\n", ioc->name,
161 pg1->LossDwordSynchCount));
162 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
163 "PHY Reset Problem Count=0x%x\n\n", ioc->name,
164 pg1->PhyResetProblemCount));
b5141128
CH
165}
166
d6ecdd63 167static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
b5141128
CH
168{
169 __le64 sas_address;
170
171 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
172
29dd3609
EM
173 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
174 "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
175 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
176 ioc->name, le16_to_cpu(pg0->DevHandle)));
177 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
178 ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
179 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
180 ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
181 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
182 ioc->name, le16_to_cpu(pg0->Slot)));
183 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
184 ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
185 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
186 ioc->name, pg0->TargetID));
187 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
188 ioc->name, pg0->Bus));
189 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
190 ioc->name, pg0->PhyNum));
191 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
192 ioc->name, le16_to_cpu(pg0->AccessStatus)));
193 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
194 ioc->name, le32_to_cpu(pg0->DeviceInfo)));
195 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
196 ioc->name, le16_to_cpu(pg0->Flags)));
197 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
198 ioc->name, pg0->PhysicalPort));
b5141128
CH
199}
200
d6ecdd63
PS
201static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
202{
29dd3609
EM
203 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
204 "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
205 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
206 ioc->name, pg1->PhysicalPort));
207 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
208 ioc->name, pg1->PhyIdentifier));
209 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
210 ioc->name, pg1->NegotiatedLinkRate));
211 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
212 ioc->name, pg1->ProgrammedLinkRate));
213 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
214 ioc->name, pg1->HwLinkRate));
215 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
216 ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
217 dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
218 "Attached Device Handle=0x%X\n\n", ioc->name,
219 le16_to_cpu(pg1->AttachedDevHandle)));
b5141128 220}
b5141128 221
e3094447
CH
222static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
223{
224 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
225 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
226}
227
228static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
229{
230 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
231 return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
232}
233
e6b2d76a
ME
234/*
235 * mptsas_find_portinfo_by_handle
236 *
237 * This function should be called with the sas_topology_mutex already held
238 */
239static struct mptsas_portinfo *
240mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
241{
242 struct mptsas_portinfo *port_info, *rc=NULL;
243 int i;
244
245 list_for_each_entry(port_info, &ioc->sas_topology, list)
246 for (i = 0; i < port_info->num_phys; i++)
247 if (port_info->phy_info[i].identify.handle == handle) {
248 rc = port_info;
249 goto out;
250 }
251 out:
252 return rc;
253}
254
bd23e94c
ME
255/*
256 * Returns true if there is a scsi end device
257 */
258static inline int
259mptsas_is_end_device(struct mptsas_devinfo * attached)
260{
547f9a21 261 if ((attached->sas_address) &&
bd23e94c
ME
262 (attached->device_info &
263 MPI_SAS_DEVICE_INFO_END_DEVICE) &&
264 ((attached->device_info &
265 MPI_SAS_DEVICE_INFO_SSP_TARGET) |
266 (attached->device_info &
267 MPI_SAS_DEVICE_INFO_STP_TARGET) |
268 (attached->device_info &
269 MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
270 return 1;
271 else
272 return 0;
273}
274
547f9a21 275/* no mutex */
376ac830 276static void
d6ecdd63 277mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
547f9a21
EM
278{
279 struct mptsas_portinfo *port_info;
280 struct mptsas_phyinfo *phy_info;
281 u8 i;
282
283 if (!port_details)
284 return;
285
286 port_info = port_details->port_info;
287 phy_info = port_info->phy_info;
288
29dd3609
EM
289 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
290 "bitmask=0x%016llX\n", ioc->name, __FUNCTION__, port_details,
f99be43b
EM
291 port_details->num_phys, (unsigned long long)
292 port_details->phy_bitmask));
547f9a21
EM
293
294 for (i = 0; i < port_info->num_phys; i++, phy_info++) {
295 if(phy_info->port_details != port_details)
296 continue;
297 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
298 phy_info->port_details = NULL;
299 }
300 kfree(port_details);
301}
302
303static inline struct sas_rphy *
304mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
305{
306 if (phy_info->port_details)
307 return phy_info->port_details->rphy;
308 else
309 return NULL;
310}
311
312static inline void
d6ecdd63 313mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
547f9a21
EM
314{
315 if (phy_info->port_details) {
316 phy_info->port_details->rphy = rphy;
29dd3609
EM
317 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
318 ioc->name, rphy));
547f9a21
EM
319 }
320
547f9a21 321 if (rphy) {
29dd3609
EM
322 dsaswideprintk(ioc, dev_printk(MYIOC_s_DEBUG_FMT,
323 &rphy->dev, "add:", ioc->name));
324 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
325 ioc->name, rphy, rphy->dev.release));
547f9a21 326 }
547f9a21
EM
327}
328
329static inline struct sas_port *
330mptsas_get_port(struct mptsas_phyinfo *phy_info)
331{
332 if (phy_info->port_details)
333 return phy_info->port_details->port;
334 else
335 return NULL;
336}
337
338static inline void
d6ecdd63 339mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
547f9a21
EM
340{
341 if (phy_info->port_details)
342 phy_info->port_details->port = port;
343
547f9a21 344 if (port) {
29dd3609
EM
345 dsaswideprintk(ioc, dev_printk(MYIOC_s_DEBUG_FMT,
346 &port->dev, "add:", ioc->name));
347 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
348 ioc->name, port, port->dev.release));
547f9a21 349 }
547f9a21
EM
350}
351
352static inline struct scsi_target *
353mptsas_get_starget(struct mptsas_phyinfo *phy_info)
354{
355 if (phy_info->port_details)
356 return phy_info->port_details->starget;
357 else
358 return NULL;
359}
360
361static inline void
362mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
363starget)
364{
365 if (phy_info->port_details)
366 phy_info->port_details->starget = starget;
367}
368
369
370/*
371 * mptsas_setup_wide_ports
372 *
373 * Updates for new and existing narrow/wide port configuration
374 * in the sas_topology
375 */
376ac830 376static void
547f9a21
EM
377mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
378{
379 struct mptsas_portinfo_details * port_details;
380 struct mptsas_phyinfo *phy_info, *phy_info_cmp;
381 u64 sas_address;
382 int i, j;
383
384 mutex_lock(&ioc->sas_topology_mutex);
385
386 phy_info = port_info->phy_info;
387 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
388 if (phy_info->attached.handle)
389 continue;
390 port_details = phy_info->port_details;
391 if (!port_details)
392 continue;
393 if (port_details->num_phys < 2)
394 continue;
395 /*
396 * Removing a phy from a port, letting the last
397 * phy be removed by firmware events.
398 */
29dd3609
EM
399 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
400 "%s: [%p]: deleting phy = %d\n",
401 ioc->name, __FUNCTION__, port_details, i));
547f9a21
EM
402 port_details->num_phys--;
403 port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
404 memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
405 sas_port_delete_phy(port_details->port, phy_info->phy);
406 phy_info->port_details = NULL;
407 }
408
409 /*
410 * Populate and refresh the tree
411 */
412 phy_info = port_info->phy_info;
413 for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
414 sas_address = phy_info->attached.sas_address;
29dd3609
EM
415 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
416 ioc->name, i, (unsigned long long)sas_address));
547f9a21
EM
417 if (!sas_address)
418 continue;
419 port_details = phy_info->port_details;
420 /*
421 * Forming a port
422 */
423 if (!port_details) {
424 port_details = kzalloc(sizeof(*port_details),
425 GFP_KERNEL);
426 if (!port_details)
427 goto out;
428 port_details->num_phys = 1;
429 port_details->port_info = port_info;
547f9a21
EM
430 if (phy_info->phy_id < 64 )
431 port_details->phy_bitmask |=
432 (1 << phy_info->phy_id);
433 phy_info->sas_port_add_phy=1;
29dd3609 434 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
f99be43b 435 "phy_id=%d sas_address=0x%018llX\n",
29dd3609 436 ioc->name, i, (unsigned long long)sas_address));
547f9a21
EM
437 phy_info->port_details = port_details;
438 }
439
440 if (i == port_info->num_phys - 1)
441 continue;
442 phy_info_cmp = &port_info->phy_info[i + 1];
443 for (j = i + 1 ; j < port_info->num_phys ; j++,
444 phy_info_cmp++) {
445 if (!phy_info_cmp->attached.sas_address)
446 continue;
447 if (sas_address != phy_info_cmp->attached.sas_address)
448 continue;
449 if (phy_info_cmp->port_details == port_details )
450 continue;
29dd3609 451 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
f99be43b 452 "\t\tphy_id=%d sas_address=0x%018llX\n",
29dd3609 453 ioc->name, j, (unsigned long long)
f99be43b 454 phy_info_cmp->attached.sas_address));
547f9a21
EM
455 if (phy_info_cmp->port_details) {
456 port_details->rphy =
457 mptsas_get_rphy(phy_info_cmp);
458 port_details->port =
459 mptsas_get_port(phy_info_cmp);
460 port_details->starget =
461 mptsas_get_starget(phy_info_cmp);
547f9a21
EM
462 port_details->num_phys =
463 phy_info_cmp->port_details->num_phys;
547f9a21
EM
464 if (!phy_info_cmp->port_details->num_phys)
465 kfree(phy_info_cmp->port_details);
466 } else
467 phy_info_cmp->sas_port_add_phy=1;
468 /*
469 * Adding a phy to a port
470 */
471 phy_info_cmp->port_details = port_details;
472 if (phy_info_cmp->phy_id < 64 )
473 port_details->phy_bitmask |=
474 (1 << phy_info_cmp->phy_id);
475 port_details->num_phys++;
476 }
477 }
478
479 out:
480
547f9a21
EM
481 for (i = 0; i < port_info->num_phys; i++) {
482 port_details = port_info->phy_info[i].port_details;
483 if (!port_details)
484 continue;
29dd3609 485 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
f99be43b 486 "%s: [%p]: phy_id=%02d num_phys=%02d "
29dd3609 487 "bitmask=0x%016llX\n", ioc->name, __FUNCTION__,
f99be43b
EM
488 port_details, i, port_details->num_phys,
489 (unsigned long long)port_details->phy_bitmask));
29dd3609
EM
490 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
491 ioc->name, port_details->port, port_details->rphy));
547f9a21 492 }
29dd3609 493 dsaswideprintk(ioc, printk("\n"));
547f9a21
EM
494 mutex_unlock(&ioc->sas_topology_mutex);
495}
496
df9e062a
EM
497/**
498 * csmisas_find_vtarget
499 *
500 * @ioc
501 * @volume_id
502 * @volume_bus
503 *
504 **/
505static VirtTarget *
506mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
507{
508 struct scsi_device *sdev;
509 VirtDevice *vdev;
510 VirtTarget *vtarget = NULL;
511
512 shost_for_each_device(sdev, ioc->sh) {
513 if ((vdev = sdev->hostdata) == NULL)
514 continue;
515 if (vdev->vtarget->id == id &&
516 vdev->vtarget->channel == channel)
517 vtarget = vdev->vtarget;
518 }
519 return vtarget;
520}
521
522/**
523 * mptsas_target_reset
524 *
525 * Issues TARGET_RESET to end device using handshaking method
526 *
527 * @ioc
528 * @channel
529 * @id
530 *
531 * Returns (1) success
532 * (0) failure
533 *
534 **/
535static int
536mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
537{
538 MPT_FRAME_HDR *mf;
539 SCSITaskMgmt_t *pScsiTm;
540
541 if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
d6ecdd63 542 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n",
df9e062a
EM
543 ioc->name,__FUNCTION__, __LINE__));
544 return 0;
545 }
546
547 /* Format the Request
548 */
549 pScsiTm = (SCSITaskMgmt_t *) mf;
550 memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
551 pScsiTm->TargetID = id;
552 pScsiTm->Bus = channel;
553 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
554 pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
555 pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
556
d6ecdd63 557 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
df9e062a 558
7a195f46 559 mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
df9e062a
EM
560
561 return 1;
562}
563
564/**
565 * mptsas_target_reset_queue
566 *
567 * Receive request for TARGET_RESET after recieving an firmware
568 * event NOT_RESPONDING_EVENT, then put command in link list
569 * and queue if task_queue already in use.
570 *
571 * @ioc
572 * @sas_event_data
573 *
574 **/
547f9a21 575static void
df9e062a
EM
576mptsas_target_reset_queue(MPT_ADAPTER *ioc,
577 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
547f9a21 578{
df9e062a
EM
579 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
580 VirtTarget *vtarget = NULL;
581 struct mptsas_target_reset_event *target_reset_list;
582 u8 id, channel;
547f9a21 583
df9e062a
EM
584 id = sas_event_data->TargetID;
585 channel = sas_event_data->Bus;
586
587 if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
588 return;
589
590 vtarget->deleted = 1; /* block IO */
591
592 target_reset_list = kzalloc(sizeof(*target_reset_list),
593 GFP_ATOMIC);
594 if (!target_reset_list) {
d6ecdd63 595 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
df9e062a
EM
596 ioc->name,__FUNCTION__, __LINE__));
597 return;
598 }
599
600 memcpy(&target_reset_list->sas_event_data, sas_event_data,
601 sizeof(*sas_event_data));
602 list_add_tail(&target_reset_list->list, &hd->target_reset_list);
603
604 if (hd->resetPending)
605 return;
606
607 if (mptsas_target_reset(ioc, channel, id)) {
608 target_reset_list->target_reset_issued = 1;
609 hd->resetPending = 1;
610 }
611}
612
613/**
614 * mptsas_dev_reset_complete
615 *
616 * Completion for TARGET_RESET after NOT_RESPONDING_EVENT,
617 * enable work queue to finish off removing device from upper layers.
618 * then send next TARGET_RESET in the queue.
619 *
620 * @ioc
621 *
622 **/
623static void
624mptsas_dev_reset_complete(MPT_ADAPTER *ioc)
625{
626 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
627 struct list_head *head = &hd->target_reset_list;
628 struct mptsas_target_reset_event *target_reset_list;
629 struct mptsas_hotplug_event *ev;
630 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
631 u8 id, channel;
632 __le64 sas_address;
633
634 if (list_empty(head))
635 return;
636
637 target_reset_list = list_entry(head->next, struct mptsas_target_reset_event, list);
638
639 sas_event_data = &target_reset_list->sas_event_data;
640 id = sas_event_data->TargetID;
641 channel = sas_event_data->Bus;
642 hd->resetPending = 0;
643
644 /*
645 * retry target reset
646 */
647 if (!target_reset_list->target_reset_issued) {
648 if (mptsas_target_reset(ioc, channel, id)) {
649 target_reset_list->target_reset_issued = 1;
650 hd->resetPending = 1;
651 }
652 return;
653 }
654
655 /*
656 * enable work queue to remove device from upper layers
657 */
658 list_del(&target_reset_list->list);
659
660 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
661 if (!ev) {
d6ecdd63 662 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
df9e062a
EM
663 ioc->name,__FUNCTION__, __LINE__));
664 return;
665 }
666
667 INIT_WORK(&ev->work, mptsas_hotplug_work);
668 ev->ioc = ioc;
669 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
670 ev->parent_handle =
671 le16_to_cpu(sas_event_data->ParentDevHandle);
672 ev->channel = channel;
673 ev->id =id;
674 ev->phy_id = sas_event_data->PhyNum;
675 memcpy(&sas_address, &sas_event_data->SASAddress,
676 sizeof(__le64));
677 ev->sas_address = le64_to_cpu(sas_address);
678 ev->device_info = le32_to_cpu(sas_event_data->DeviceInfo);
679 ev->event_type = MPTSAS_DEL_DEVICE;
680 schedule_work(&ev->work);
681 kfree(target_reset_list);
682
683 /*
684 * issue target reset to next device in the queue
685 */
686
687 head = &hd->target_reset_list;
688 if (list_empty(head))
689 return;
690
691 target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
692 list);
693
694 sas_event_data = &target_reset_list->sas_event_data;
695 id = sas_event_data->TargetID;
696 channel = sas_event_data->Bus;
697
698 if (mptsas_target_reset(ioc, channel, id)) {
699 target_reset_list->target_reset_issued = 1;
700 hd->resetPending = 1;
701 }
702}
703
704/**
705 * mptsas_taskmgmt_complete
706 *
707 * @ioc
708 * @mf
709 * @mr
710 *
711 **/
712static int
713mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
714{
715 mptsas_dev_reset_complete(ioc);
716 return mptscsih_taskmgmt_complete(ioc, mf, mr);
717}
718
719/**
720 * mptscsih_ioc_reset
721 *
722 * @ioc
723 * @reset_phase
724 *
725 **/
726static int
727mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
728{
ba76ef24 729 MPT_SCSI_HOST *hd;
df9e062a
EM
730 struct mptsas_target_reset_event *target_reset_list, *n;
731 int rc;
732
733 rc = mptscsih_ioc_reset(ioc, reset_phase);
734
735 if (ioc->bus_type != SAS)
736 goto out;
737
738 if (reset_phase != MPT_IOC_POST_RESET)
739 goto out;
740
ba76ef24
JL
741 if (!ioc->sh || !ioc->sh->hostdata)
742 goto out;
743 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
744 if (!hd->ioc)
df9e062a
EM
745 goto out;
746
747 if (list_empty(&hd->target_reset_list))
748 goto out;
749
750 /* flush the target_reset_list */
751 list_for_each_entry_safe(target_reset_list, n,
752 &hd->target_reset_list, list) {
753 list_del(&target_reset_list->list);
754 kfree(target_reset_list);
547f9a21 755 }
df9e062a
EM
756
757 out:
758 return rc;
547f9a21
EM
759}
760
e3094447 761static int
52435430 762mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
e3094447
CH
763 u32 form, u32 form_specific)
764{
765 ConfigExtendedPageHeader_t hdr;
766 CONFIGPARMS cfg;
767 SasEnclosurePage0_t *buffer;
768 dma_addr_t dma_handle;
769 int error;
770 __le64 le_identifier;
771
772 memset(&hdr, 0, sizeof(hdr));
773 hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
774 hdr.PageNumber = 0;
775 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
776 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
777
778 cfg.cfghdr.ehdr = &hdr;
779 cfg.physAddr = -1;
780 cfg.pageAddr = form + form_specific;
781 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
782 cfg.dir = 0; /* read */
783 cfg.timeout = 10;
784
785 error = mpt_config(ioc, &cfg);
786 if (error)
787 goto out;
788 if (!hdr.ExtPageLength) {
789 error = -ENXIO;
790 goto out;
791 }
792
793 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
794 &dma_handle);
795 if (!buffer) {
796 error = -ENOMEM;
797 goto out;
798 }
799
800 cfg.physAddr = dma_handle;
801 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
802
803 error = mpt_config(ioc, &cfg);
804 if (error)
805 goto out_free_consistent;
806
807 /* save config data */
808 memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
809 enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
810 enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
811 enclosure->flags = le16_to_cpu(buffer->Flags);
812 enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
813 enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
814 enclosure->start_id = buffer->StartTargetID;
815 enclosure->start_channel = buffer->StartBus;
816 enclosure->sep_id = buffer->SEPTargetID;
817 enclosure->sep_channel = buffer->SEPBus;
818
819 out_free_consistent:
820 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
821 buffer, dma_handle);
822 out:
823 return error;
824}
b5141128 825
f013db32
JB
826static int
827mptsas_slave_configure(struct scsi_device *sdev)
828{
3c0c25b9 829
e8bf3941
JB
830 if (sdev->channel == MPTSAS_RAID_CHANNEL)
831 goto out;
832
833 sas_read_port_mode_page(sdev);
f013db32 834
e8bf3941 835 out:
f013db32
JB
836 return mptscsih_slave_configure(sdev);
837}
838
547f9a21
EM
839static int
840mptsas_target_alloc(struct scsi_target *starget)
841{
842 struct Scsi_Host *host = dev_to_shost(&starget->dev);
843 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
844 VirtTarget *vtarget;
793955f5 845 u8 id, channel;
547f9a21
EM
846 struct sas_rphy *rphy;
847 struct mptsas_portinfo *p;
848 int i;
849
850 vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
851 if (!vtarget)
852 return -ENOMEM;
853
854 vtarget->starget = starget;
855 vtarget->ioc_id = hd->ioc->id;
793955f5
EM
856 vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
857 id = starget->id;
547f9a21
EM
858 channel = 0;
859
793955f5
EM
860 /*
861 * RAID volumes placed beyond the last expected port.
862 */
863 if (starget->channel == MPTSAS_RAID_CHANNEL) {
864 for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
865 if (id == hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID)
866 channel = hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus;
547f9a21 867 goto out;
793955f5 868 }
547f9a21
EM
869
870 rphy = dev_to_rphy(starget->dev.parent);
871 mutex_lock(&hd->ioc->sas_topology_mutex);
872 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
873 for (i = 0; i < p->num_phys; i++) {
874 if (p->phy_info[i].attached.sas_address !=
875 rphy->identify.sas_address)
876 continue;
793955f5 877 id = p->phy_info[i].attached.id;
547f9a21
EM
878 channel = p->phy_info[i].attached.channel;
879 mptsas_set_starget(&p->phy_info[i], starget);
880
881 /*
882 * Exposing hidden raid components
883 */
793955f5
EM
884 if (mptscsih_is_phys_disk(hd->ioc, channel, id)) {
885 id = mptscsih_raid_id_to_num(hd->ioc,
886 channel, id);
547f9a21
EM
887 vtarget->tflags |=
888 MPT_TARGET_FLAGS_RAID_COMPONENT;
b506ade9 889 p->phy_info[i].attached.phys_disk_num = id;
547f9a21
EM
890 }
891 mutex_unlock(&hd->ioc->sas_topology_mutex);
892 goto out;
893 }
894 }
895 mutex_unlock(&hd->ioc->sas_topology_mutex);
896
897 kfree(vtarget);
898 return -ENXIO;
899
900 out:
793955f5
EM
901 vtarget->id = id;
902 vtarget->channel = channel;
547f9a21
EM
903 starget->hostdata = vtarget;
904 return 0;
905}
906
907static void
908mptsas_target_destroy(struct scsi_target *starget)
909{
910 struct Scsi_Host *host = dev_to_shost(&starget->dev);
911 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
912 struct sas_rphy *rphy;
913 struct mptsas_portinfo *p;
914 int i;
915
916 if (!starget->hostdata)
917 return;
918
e8bf3941 919 if (starget->channel == MPTSAS_RAID_CHANNEL)
547f9a21
EM
920 goto out;
921
922 rphy = dev_to_rphy(starget->dev.parent);
923 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
924 for (i = 0; i < p->num_phys; i++) {
925 if (p->phy_info[i].attached.sas_address !=
926 rphy->identify.sas_address)
927 continue;
928 mptsas_set_starget(&p->phy_info[i], NULL);
929 goto out;
930 }
931 }
932
933 out:
934 kfree(starget->hostdata);
935 starget->hostdata = NULL;
936}
937
938
0c33b27d 939static int
c7c82987 940mptsas_slave_alloc(struct scsi_device *sdev)
0c33b27d 941{
c7c82987 942 struct Scsi_Host *host = sdev->host;
0c33b27d
CH
943 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
944 struct sas_rphy *rphy;
945 struct mptsas_portinfo *p;
946 VirtDevice *vdev;
c7c82987 947 struct scsi_target *starget;
547f9a21 948 int i;
0c33b27d 949
1ca00bb7 950 vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
0c33b27d 951 if (!vdev) {
547f9a21 952 printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
0c33b27d
CH
953 hd->ioc->name, sizeof(VirtDevice));
954 return -ENOMEM;
955 }
c7c82987 956 starget = scsi_target(sdev);
547f9a21 957 vdev->vtarget = starget->hostdata;
0c33b27d 958
e8bf3941 959 if (sdev->channel == MPTSAS_RAID_CHANNEL)
816aa907 960 goto out;
816aa907 961
c7c82987 962 rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
9a28f49a 963 mutex_lock(&hd->ioc->sas_topology_mutex);
0c33b27d
CH
964 list_for_each_entry(p, &hd->ioc->sas_topology, list) {
965 for (i = 0; i < p->num_phys; i++) {
547f9a21
EM
966 if (p->phy_info[i].attached.sas_address !=
967 rphy->identify.sas_address)
968 continue;
969 vdev->lun = sdev->lun;
970 /*
971 * Exposing hidden raid components
972 */
973 if (mptscsih_is_phys_disk(hd->ioc,
793955f5
EM
974 p->phy_info[i].attached.channel,
975 p->phy_info[i].attached.id))
547f9a21
EM
976 sdev->no_uld_attach = 1;
977 mutex_unlock(&hd->ioc->sas_topology_mutex);
978 goto out;
0c33b27d
CH
979 }
980 }
9a28f49a 981 mutex_unlock(&hd->ioc->sas_topology_mutex);
0c33b27d 982
0c33b27d 983 kfree(vdev);
23f236ed 984 return -ENXIO;
0c33b27d
CH
985
986 out:
547f9a21
EM
987 vdev->vtarget->num_luns++;
988 sdev->hostdata = vdev;
0c33b27d
CH
989 return 0;
990}
991
547f9a21
EM
992static int
993mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
9a28f49a 994{
547f9a21 995 VirtDevice *vdev = SCpnt->device->hostdata;
7d3eecf7 996
793955f5 997 if (!vdev || !vdev->vtarget || vdev->vtarget->deleted) {
547f9a21
EM
998 SCpnt->result = DID_NO_CONNECT << 16;
999 done(SCpnt);
1000 return 0;
7d3eecf7 1001 }
547f9a21 1002
793955f5
EM
1003// scsi_print_command(SCpnt);
1004
547f9a21 1005 return mptscsih_qcmd(SCpnt,done);
9a28f49a
CH
1006}
1007
547f9a21 1008
0c33b27d 1009static struct scsi_host_template mptsas_driver_template = {
f78496da 1010 .module = THIS_MODULE,
0c33b27d
CH
1011 .proc_name = "mptsas",
1012 .proc_info = mptscsih_proc_info,
1013 .name = "MPT SPI Host",
1014 .info = mptscsih_info,
547f9a21
EM
1015 .queuecommand = mptsas_qcmd,
1016 .target_alloc = mptsas_target_alloc,
0c33b27d 1017 .slave_alloc = mptsas_slave_alloc,
f013db32 1018 .slave_configure = mptsas_slave_configure,
547f9a21
EM
1019 .target_destroy = mptsas_target_destroy,
1020 .slave_destroy = mptscsih_slave_destroy,
0c33b27d
CH
1021 .change_queue_depth = mptscsih_change_queue_depth,
1022 .eh_abort_handler = mptscsih_abort,
1023 .eh_device_reset_handler = mptscsih_dev_reset,
1024 .eh_bus_reset_handler = mptscsih_bus_reset,
1025 .eh_host_reset_handler = mptscsih_host_reset,
1026 .bios_param = mptscsih_bios_param,
1027 .can_queue = MPT_FC_CAN_QUEUE,
1028 .this_id = -1,
1029 .sg_tablesize = MPT_SCSI_SG_DEPTH,
1030 .max_sectors = 8192,
1031 .cmd_per_lun = 7,
1032 .use_clustering = ENABLE_CLUSTERING,
edb9068d 1033 .shost_attrs = mptscsih_host_attrs,
0c33b27d
CH
1034};
1035
b5141128 1036static int mptsas_get_linkerrors(struct sas_phy *phy)
0c33b27d 1037{
b5141128
CH
1038 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1039 ConfigExtendedPageHeader_t hdr;
1040 CONFIGPARMS cfg;
1041 SasPhyPage1_t *buffer;
1042 dma_addr_t dma_handle;
1043 int error;
0c33b27d 1044
f4ad7b58
JB
1045 /* FIXME: only have link errors on local phys */
1046 if (!scsi_is_sas_phy_local(phy))
1047 return -EINVAL;
1048
b5141128
CH
1049 hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
1050 hdr.ExtPageLength = 0;
1051 hdr.PageNumber = 1 /* page number 1*/;
1052 hdr.Reserved1 = 0;
1053 hdr.Reserved2 = 0;
1054 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1055 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
0c33b27d 1056
b5141128
CH
1057 cfg.cfghdr.ehdr = &hdr;
1058 cfg.physAddr = -1;
1059 cfg.pageAddr = phy->identify.phy_identifier;
1060 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1061 cfg.dir = 0; /* read */
1062 cfg.timeout = 10;
0c33b27d 1063
b5141128
CH
1064 error = mpt_config(ioc, &cfg);
1065 if (error)
1066 return error;
1067 if (!hdr.ExtPageLength)
1068 return -ENXIO;
0c33b27d 1069
b5141128
CH
1070 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1071 &dma_handle);
1072 if (!buffer)
1073 return -ENOMEM;
0c33b27d 1074
b5141128
CH
1075 cfg.physAddr = dma_handle;
1076 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1077
1078 error = mpt_config(ioc, &cfg);
1079 if (error)
1080 goto out_free_consistent;
1081
d6ecdd63 1082 mptsas_print_phy_pg1(ioc, buffer);
b5141128
CH
1083
1084 phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
1085 phy->running_disparity_error_count =
1086 le32_to_cpu(buffer->RunningDisparityErrorCount);
1087 phy->loss_of_dword_sync_count =
1088 le32_to_cpu(buffer->LossDwordSynchCount);
1089 phy->phy_reset_problem_count =
1090 le32_to_cpu(buffer->PhyResetProblemCount);
1091
1092 out_free_consistent:
1093 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1094 buffer, dma_handle);
1095 return error;
0c33b27d
CH
1096}
1097
da4fa655
CH
1098static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
1099 MPT_FRAME_HDR *reply)
1100{
1101 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_COMMAND_GOOD;
1102 if (reply != NULL) {
1103 ioc->sas_mgmt.status |= MPT_SAS_MGMT_STATUS_RF_VALID;
1104 memcpy(ioc->sas_mgmt.reply, reply,
1105 min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
1106 }
1107 complete(&ioc->sas_mgmt.done);
1108 return 1;
1109}
1110
1111static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
1112{
1113 MPT_ADAPTER *ioc = phy_to_ioc(phy);
1114 SasIoUnitControlRequest_t *req;
1115 SasIoUnitControlReply_t *reply;
1116 MPT_FRAME_HDR *mf;
1117 MPIHeader_t *hdr;
1118 unsigned long timeleft;
1119 int error = -ERESTARTSYS;
1120
f4ad7b58
JB
1121 /* FIXME: fusion doesn't allow non-local phy reset */
1122 if (!scsi_is_sas_phy_local(phy))
1123 return -EINVAL;
1124
da4fa655
CH
1125 /* not implemented for expanders */
1126 if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
1127 return -ENXIO;
1128
eeb846ce 1129 if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
da4fa655
CH
1130 goto out;
1131
1132 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1133 if (!mf) {
1134 error = -ENOMEM;
1135 goto out_unlock;
1136 }
1137
1138 hdr = (MPIHeader_t *) mf;
1139 req = (SasIoUnitControlRequest_t *)mf;
1140 memset(req, 0, sizeof(SasIoUnitControlRequest_t));
1141 req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
1142 req->MsgContext = hdr->MsgContext;
1143 req->Operation = hard_reset ?
1144 MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
1145 req->PhyNum = phy->identify.phy_identifier;
1146
1147 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1148
1149 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
1150 10 * HZ);
1151 if (!timeleft) {
1152 /* On timeout reset the board */
1153 mpt_free_msg_frame(ioc, mf);
1154 mpt_HardResetHandler(ioc, CAN_SLEEP);
1155 error = -ETIMEDOUT;
1156 goto out_unlock;
1157 }
1158
1159 /* a reply frame is expected */
1160 if ((ioc->sas_mgmt.status &
1161 MPT_IOCTL_STATUS_RF_VALID) == 0) {
1162 error = -ENXIO;
1163 goto out_unlock;
1164 }
1165
1166 /* process the completed Reply Message Frame */
1167 reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
1168 if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
29dd3609
EM
1169 printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
1170 ioc->name, __FUNCTION__, reply->IOCStatus, reply->IOCLogInfo);
da4fa655
CH
1171 error = -ENXIO;
1172 goto out_unlock;
1173 }
1174
1175 error = 0;
1176
1177 out_unlock:
eeb846ce 1178 mutex_unlock(&ioc->sas_mgmt.mutex);
da4fa655
CH
1179 out:
1180 return error;
1181}
0c33b27d 1182
e3094447
CH
1183static int
1184mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
1185{
1186 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1187 int i, error;
1188 struct mptsas_portinfo *p;
1189 struct mptsas_enclosure enclosure_info;
1190 u64 enclosure_handle;
1191
1192 mutex_lock(&ioc->sas_topology_mutex);
1193 list_for_each_entry(p, &ioc->sas_topology, list) {
1194 for (i = 0; i < p->num_phys; i++) {
1195 if (p->phy_info[i].attached.sas_address ==
1196 rphy->identify.sas_address) {
1197 enclosure_handle = p->phy_info[i].
1198 attached.handle_enclosure;
1199 goto found_info;
1200 }
1201 }
1202 }
1203 mutex_unlock(&ioc->sas_topology_mutex);
1204 return -ENXIO;
1205
1206 found_info:
1207 mutex_unlock(&ioc->sas_topology_mutex);
1208 memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
52435430 1209 error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
e3094447
CH
1210 (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
1211 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
1212 if (!error)
1213 *identifier = enclosure_info.enclosure_logical_id;
1214 return error;
1215}
1216
1217static int
1218mptsas_get_bay_identifier(struct sas_rphy *rphy)
1219{
1220 MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
1221 struct mptsas_portinfo *p;
1222 int i, rc;
1223
1224 mutex_lock(&ioc->sas_topology_mutex);
1225 list_for_each_entry(p, &ioc->sas_topology, list) {
1226 for (i = 0; i < p->num_phys; i++) {
1227 if (p->phy_info[i].attached.sas_address ==
1228 rphy->identify.sas_address) {
1229 rc = p->phy_info[i].attached.slot;
1230 goto out;
1231 }
1232 }
1233 }
1234 rc = -ENXIO;
1235 out:
1236 mutex_unlock(&ioc->sas_topology_mutex);
1237 return rc;
1238}
1239
159e36fe
FT
1240static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1241 struct request *req)
1242{
1243 MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
1244 MPT_FRAME_HDR *mf;
1245 SmpPassthroughRequest_t *smpreq;
1246 struct request *rsp = req->next_rq;
1247 int ret;
1248 int flagsLength;
1249 unsigned long timeleft;
1250 char *psge;
1251 dma_addr_t dma_addr_in = 0;
1252 dma_addr_t dma_addr_out = 0;
1253 u64 sas_address = 0;
1254
1255 if (!rsp) {
29dd3609
EM
1256 printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
1257 ioc->name, __FUNCTION__);
159e36fe
FT
1258 return -EINVAL;
1259 }
1260
1261 /* do we need to support multiple segments? */
1262 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
29dd3609
EM
1263 printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
1264 ioc->name, __FUNCTION__, req->bio->bi_vcnt, req->data_len,
1265 rsp->bio->bi_vcnt, rsp->data_len);
159e36fe
FT
1266 return -EINVAL;
1267 }
1268
1269 ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
1270 if (ret)
1271 goto out;
1272
1273 mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
1274 if (!mf) {
1275 ret = -ENOMEM;
1276 goto out_unlock;
1277 }
1278
1279 smpreq = (SmpPassthroughRequest_t *)mf;
1280 memset(smpreq, 0, sizeof(*smpreq));
1281
1282 smpreq->RequestDataLength = cpu_to_le16(req->data_len - 4);
1283 smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
1284
1285 if (rphy)
1286 sas_address = rphy->identify.sas_address;
1287 else {
1288 struct mptsas_portinfo *port_info;
1289
1290 mutex_lock(&ioc->sas_topology_mutex);
1291 port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
1292 if (port_info && port_info->phy_info)
1293 sas_address =
1294 port_info->phy_info[0].phy->identify.sas_address;
1295 mutex_unlock(&ioc->sas_topology_mutex);
1296 }
1297
1298 *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
1299
1300 psge = (char *)
1301 (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
1302
1303 /* request */
1304 flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1305 MPI_SGE_FLAGS_END_OF_BUFFER |
1306 MPI_SGE_FLAGS_DIRECTION |
1307 mpt_addr_size()) << MPI_SGE_FLAGS_SHIFT;
1308 flagsLength |= (req->data_len - 4);
1309
1310 dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
1311 req->data_len, PCI_DMA_BIDIRECTIONAL);
1312 if (!dma_addr_out)
1313 goto put_mf;
1314 mpt_add_sge(psge, flagsLength, dma_addr_out);
1315 psge += (sizeof(u32) + sizeof(dma_addr_t));
1316
1317 /* response */
1318 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
1319 flagsLength |= rsp->data_len + 4;
1320 dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
1321 rsp->data_len, PCI_DMA_BIDIRECTIONAL);
1322 if (!dma_addr_in)
1323 goto unmap;
1324 mpt_add_sge(psge, flagsLength, dma_addr_in);
1325
1326 mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
1327
1328 timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
1329 if (!timeleft) {
29dd3609 1330 printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __FUNCTION__);
159e36fe
FT
1331 /* On timeout reset the board */
1332 mpt_HardResetHandler(ioc, CAN_SLEEP);
1333 ret = -ETIMEDOUT;
1334 goto unmap;
1335 }
1336 mf = NULL;
1337
1338 if (ioc->sas_mgmt.status & MPT_IOCTL_STATUS_RF_VALID) {
1339 SmpPassthroughReply_t *smprep;
1340
1341 smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
1342 memcpy(req->sense, smprep, sizeof(*smprep));
1343 req->sense_len = sizeof(*smprep);
1344 } else {
29dd3609
EM
1345 printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n",
1346 ioc->name, __FUNCTION__);
159e36fe
FT
1347 ret = -ENXIO;
1348 }
1349unmap:
1350 if (dma_addr_out)
1351 pci_unmap_single(ioc->pcidev, dma_addr_out, req->data_len,
1352 PCI_DMA_BIDIRECTIONAL);
1353 if (dma_addr_in)
1354 pci_unmap_single(ioc->pcidev, dma_addr_in, rsp->data_len,
1355 PCI_DMA_BIDIRECTIONAL);
1356put_mf:
1357 if (mf)
1358 mpt_free_msg_frame(ioc, mf);
1359out_unlock:
1360 mutex_unlock(&ioc->sas_mgmt.mutex);
1361out:
1362 return ret;
1363}
1364
b5141128
CH
1365static struct sas_function_template mptsas_transport_functions = {
1366 .get_linkerrors = mptsas_get_linkerrors,
e3094447
CH
1367 .get_enclosure_identifier = mptsas_get_enclosure_identifier,
1368 .get_bay_identifier = mptsas_get_bay_identifier,
da4fa655 1369 .phy_reset = mptsas_phy_reset,
159e36fe 1370 .smp_handler = mptsas_smp_handler,
b5141128
CH
1371};
1372
1373static struct scsi_transport_template *mptsas_transport_template;
0c33b27d
CH
1374
1375static int
1376mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
1377{
1378 ConfigExtendedPageHeader_t hdr;
1379 CONFIGPARMS cfg;
1380 SasIOUnitPage0_t *buffer;
1381 dma_addr_t dma_handle;
1382 int error, i;
1383
1384 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
1385 hdr.ExtPageLength = 0;
1386 hdr.PageNumber = 0;
1387 hdr.Reserved1 = 0;
1388 hdr.Reserved2 = 0;
1389 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1390 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1391
1392 cfg.cfghdr.ehdr = &hdr;
1393 cfg.physAddr = -1;
1394 cfg.pageAddr = 0;
1395 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1396 cfg.dir = 0; /* read */
1397 cfg.timeout = 10;
1398
1399 error = mpt_config(ioc, &cfg);
1400 if (error)
1401 goto out;
1402 if (!hdr.ExtPageLength) {
1403 error = -ENXIO;
1404 goto out;
1405 }
1406
1407 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1408 &dma_handle);
1409 if (!buffer) {
1410 error = -ENOMEM;
1411 goto out;
1412 }
1413
1414 cfg.physAddr = dma_handle;
1415 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1416
1417 error = mpt_config(ioc, &cfg);
1418 if (error)
1419 goto out_free_consistent;
1420
1421 port_info->num_phys = buffer->NumPhys;
1422 port_info->phy_info = kcalloc(port_info->num_phys,
547f9a21 1423 sizeof(*port_info->phy_info),GFP_KERNEL);
0c33b27d
CH
1424 if (!port_info->phy_info) {
1425 error = -ENOMEM;
1426 goto out_free_consistent;
1427 }
1428
edb9068d
PS
1429 ioc->nvdata_version_persistent =
1430 le16_to_cpu(buffer->NvdataVersionPersistent);
1431 ioc->nvdata_version_default =
1432 le16_to_cpu(buffer->NvdataVersionDefault);
1433
0c33b27d 1434 for (i = 0; i < port_info->num_phys; i++) {
d6ecdd63 1435 mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
0c33b27d
CH
1436 port_info->phy_info[i].phy_id = i;
1437 port_info->phy_info[i].port_id =
1438 buffer->PhyData[i].Port;
1439 port_info->phy_info[i].negotiated_link_rate =
1440 buffer->PhyData[i].NegotiatedLinkRate;
547f9a21 1441 port_info->phy_info[i].portinfo = port_info;
2ecce492
EM
1442 port_info->phy_info[i].handle =
1443 le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
0c33b27d
CH
1444 }
1445
1446 out_free_consistent:
1447 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1448 buffer, dma_handle);
1449 out:
1450 return error;
1451}
1452
edb9068d
PS
1453static int
1454mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
1455{
1456 ConfigExtendedPageHeader_t hdr;
1457 CONFIGPARMS cfg;
1458 SasIOUnitPage1_t *buffer;
1459 dma_addr_t dma_handle;
1460 int error;
1461 u16 device_missing_delay;
1462
1463 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
1464 memset(&cfg, 0, sizeof(CONFIGPARMS));
1465
1466 cfg.cfghdr.ehdr = &hdr;
1467 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1468 cfg.timeout = 10;
1469 cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1470 cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
1471 cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
1472 cfg.cfghdr.ehdr->PageNumber = 1;
1473
1474 error = mpt_config(ioc, &cfg);
1475 if (error)
1476 goto out;
1477 if (!hdr.ExtPageLength) {
1478 error = -ENXIO;
1479 goto out;
1480 }
1481
1482 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1483 &dma_handle);
1484 if (!buffer) {
1485 error = -ENOMEM;
1486 goto out;
1487 }
1488
1489 cfg.physAddr = dma_handle;
1490 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1491
1492 error = mpt_config(ioc, &cfg);
1493 if (error)
1494 goto out_free_consistent;
1495
1496 ioc->io_missing_delay =
1497 le16_to_cpu(buffer->IODeviceMissingDelay);
1498 device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
1499 ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
1500 (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
1501 device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
1502
1503 out_free_consistent:
1504 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1505 buffer, dma_handle);
1506 out:
1507 return error;
1508}
1509
0c33b27d
CH
1510static int
1511mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1512 u32 form, u32 form_specific)
1513{
1514 ConfigExtendedPageHeader_t hdr;
1515 CONFIGPARMS cfg;
1516 SasPhyPage0_t *buffer;
1517 dma_addr_t dma_handle;
1518 int error;
1519
1520 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
1521 hdr.ExtPageLength = 0;
1522 hdr.PageNumber = 0;
1523 hdr.Reserved1 = 0;
1524 hdr.Reserved2 = 0;
1525 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1526 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
1527
1528 cfg.cfghdr.ehdr = &hdr;
1529 cfg.dir = 0; /* read */
1530 cfg.timeout = 10;
1531
1532 /* Get Phy Pg 0 for each Phy. */
1533 cfg.physAddr = -1;
1534 cfg.pageAddr = form + form_specific;
1535 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1536
1537 error = mpt_config(ioc, &cfg);
1538 if (error)
1539 goto out;
1540
1541 if (!hdr.ExtPageLength) {
1542 error = -ENXIO;
1543 goto out;
1544 }
1545
1546 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1547 &dma_handle);
1548 if (!buffer) {
1549 error = -ENOMEM;
1550 goto out;
1551 }
1552
1553 cfg.physAddr = dma_handle;
1554 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1555
1556 error = mpt_config(ioc, &cfg);
1557 if (error)
1558 goto out_free_consistent;
1559
d6ecdd63 1560 mptsas_print_phy_pg0(ioc, buffer);
0c33b27d
CH
1561
1562 phy_info->hw_link_rate = buffer->HwLinkRate;
1563 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1564 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1565 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1566
1567 out_free_consistent:
1568 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1569 buffer, dma_handle);
1570 out:
1571 return error;
1572}
1573
1574static int
1575mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
1576 u32 form, u32 form_specific)
1577{
1578 ConfigExtendedPageHeader_t hdr;
1579 CONFIGPARMS cfg;
1580 SasDevicePage0_t *buffer;
1581 dma_addr_t dma_handle;
1582 __le64 sas_address;
bd23e94c
ME
1583 int error=0;
1584
1585 if (ioc->sas_discovery_runtime &&
1586 mptsas_is_end_device(device_info))
1587 goto out;
0c33b27d
CH
1588
1589 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
1590 hdr.ExtPageLength = 0;
1591 hdr.PageNumber = 0;
1592 hdr.Reserved1 = 0;
1593 hdr.Reserved2 = 0;
1594 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1595 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
1596
1597 cfg.cfghdr.ehdr = &hdr;
1598 cfg.pageAddr = form + form_specific;
1599 cfg.physAddr = -1;
1600 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1601 cfg.dir = 0; /* read */
1602 cfg.timeout = 10;
1603
db9c9174 1604 memset(device_info, 0, sizeof(struct mptsas_devinfo));
0c33b27d
CH
1605 error = mpt_config(ioc, &cfg);
1606 if (error)
1607 goto out;
1608 if (!hdr.ExtPageLength) {
1609 error = -ENXIO;
1610 goto out;
1611 }
1612
1613 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1614 &dma_handle);
1615 if (!buffer) {
1616 error = -ENOMEM;
1617 goto out;
1618 }
1619
1620 cfg.physAddr = dma_handle;
1621 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1622
1623 error = mpt_config(ioc, &cfg);
1624 if (error)
1625 goto out_free_consistent;
1626
d6ecdd63 1627 mptsas_print_device_pg0(ioc, buffer);
0c33b27d
CH
1628
1629 device_info->handle = le16_to_cpu(buffer->DevHandle);
c73787ee 1630 device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
e3094447
CH
1631 device_info->handle_enclosure =
1632 le16_to_cpu(buffer->EnclosureHandle);
1633 device_info->slot = le16_to_cpu(buffer->Slot);
0c33b27d
CH
1634 device_info->phy_id = buffer->PhyNum;
1635 device_info->port_id = buffer->PhysicalPort;
9a28f49a 1636 device_info->id = buffer->TargetID;
b506ade9 1637 device_info->phys_disk_num = ~0;
9a28f49a 1638 device_info->channel = buffer->Bus;
0c33b27d
CH
1639 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
1640 device_info->sas_address = le64_to_cpu(sas_address);
1641 device_info->device_info =
1642 le32_to_cpu(buffer->DeviceInfo);
1643
1644 out_free_consistent:
1645 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1646 buffer, dma_handle);
1647 out:
1648 return error;
1649}
1650
1651static int
1652mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
1653 u32 form, u32 form_specific)
1654{
1655 ConfigExtendedPageHeader_t hdr;
1656 CONFIGPARMS cfg;
1657 SasExpanderPage0_t *buffer;
1658 dma_addr_t dma_handle;
547f9a21 1659 int i, error;
0c33b27d
CH
1660
1661 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1662 hdr.ExtPageLength = 0;
1663 hdr.PageNumber = 0;
1664 hdr.Reserved1 = 0;
1665 hdr.Reserved2 = 0;
1666 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1667 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1668
1669 cfg.cfghdr.ehdr = &hdr;
1670 cfg.physAddr = -1;
1671 cfg.pageAddr = form + form_specific;
1672 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1673 cfg.dir = 0; /* read */
1674 cfg.timeout = 10;
1675
db9c9174 1676 memset(port_info, 0, sizeof(struct mptsas_portinfo));
0c33b27d
CH
1677 error = mpt_config(ioc, &cfg);
1678 if (error)
1679 goto out;
1680
1681 if (!hdr.ExtPageLength) {
1682 error = -ENXIO;
1683 goto out;
1684 }
1685
1686 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1687 &dma_handle);
1688 if (!buffer) {
1689 error = -ENOMEM;
1690 goto out;
1691 }
1692
1693 cfg.physAddr = dma_handle;
1694 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1695
1696 error = mpt_config(ioc, &cfg);
1697 if (error)
1698 goto out_free_consistent;
1699
1700 /* save config data */
1701 port_info->num_phys = buffer->NumPhys;
0c33b27d 1702 port_info->phy_info = kcalloc(port_info->num_phys,
547f9a21 1703 sizeof(*port_info->phy_info),GFP_KERNEL);
0c33b27d
CH
1704 if (!port_info->phy_info) {
1705 error = -ENOMEM;
1706 goto out_free_consistent;
1707 }
1708
2ecce492 1709 for (i = 0; i < port_info->num_phys; i++) {
547f9a21 1710 port_info->phy_info[i].portinfo = port_info;
2ecce492
EM
1711 port_info->phy_info[i].handle =
1712 le16_to_cpu(buffer->DevHandle);
1713 }
547f9a21 1714
0c33b27d
CH
1715 out_free_consistent:
1716 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1717 buffer, dma_handle);
1718 out:
1719 return error;
1720}
1721
1722static int
1723mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1724 u32 form, u32 form_specific)
1725{
1726 ConfigExtendedPageHeader_t hdr;
1727 CONFIGPARMS cfg;
1728 SasExpanderPage1_t *buffer;
1729 dma_addr_t dma_handle;
bd23e94c
ME
1730 int error=0;
1731
1732 if (ioc->sas_discovery_runtime &&
1733 mptsas_is_end_device(&phy_info->attached))
1734 goto out;
0c33b27d
CH
1735
1736 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1737 hdr.ExtPageLength = 0;
1738 hdr.PageNumber = 1;
1739 hdr.Reserved1 = 0;
1740 hdr.Reserved2 = 0;
1741 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1742 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1743
1744 cfg.cfghdr.ehdr = &hdr;
1745 cfg.physAddr = -1;
1746 cfg.pageAddr = form + form_specific;
1747 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1748 cfg.dir = 0; /* read */
1749 cfg.timeout = 10;
1750
1751 error = mpt_config(ioc, &cfg);
1752 if (error)
1753 goto out;
1754
1755 if (!hdr.ExtPageLength) {
1756 error = -ENXIO;
1757 goto out;
1758 }
1759
1760 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1761 &dma_handle);
1762 if (!buffer) {
1763 error = -ENOMEM;
1764 goto out;
1765 }
1766
1767 cfg.physAddr = dma_handle;
1768 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1769
1770 error = mpt_config(ioc, &cfg);
1771 if (error)
1772 goto out_free_consistent;
1773
1774
d6ecdd63 1775 mptsas_print_expander_pg1(ioc, buffer);
0c33b27d
CH
1776
1777 /* save config data */
024358ee 1778 phy_info->phy_id = buffer->PhyIdentifier;
0c33b27d
CH
1779 phy_info->port_id = buffer->PhysicalPort;
1780 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
1781 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1782 phy_info->hw_link_rate = buffer->HwLinkRate;
1783 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1784 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1785
0c33b27d
CH
1786 out_free_consistent:
1787 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1788 buffer, dma_handle);
1789 out:
1790 return error;
1791}
1792
1793static void
1794mptsas_parse_device_info(struct sas_identify *identify,
1795 struct mptsas_devinfo *device_info)
1796{
1797 u16 protocols;
1798
1799 identify->sas_address = device_info->sas_address;
1800 identify->phy_identifier = device_info->phy_id;
1801
1802 /*
1803 * Fill in Phy Initiator Port Protocol.
1804 * Bits 6:3, more than one bit can be set, fall through cases.
1805 */
1806 protocols = device_info->device_info & 0x78;
1807 identify->initiator_port_protocols = 0;
1808 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
1809 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
1810 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1811 identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
1812 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
1813 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
1814 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
1815 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
1816
1817 /*
1818 * Fill in Phy Target Port Protocol.
1819 * Bits 10:7, more than one bit can be set, fall through cases.
1820 */
1821 protocols = device_info->device_info & 0x780;
1822 identify->target_port_protocols = 0;
1823 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1824 identify->target_port_protocols |= SAS_PROTOCOL_SSP;
1825 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
1826 identify->target_port_protocols |= SAS_PROTOCOL_STP;
1827 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
1828 identify->target_port_protocols |= SAS_PROTOCOL_SMP;
1829 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1830 identify->target_port_protocols |= SAS_PROTOCOL_SATA;
1831
1832 /*
1833 * Fill in Attached device type.
1834 */
1835 switch (device_info->device_info &
1836 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
1837 case MPI_SAS_DEVICE_INFO_NO_DEVICE:
1838 identify->device_type = SAS_PHY_UNUSED;
1839 break;
1840 case MPI_SAS_DEVICE_INFO_END_DEVICE:
1841 identify->device_type = SAS_END_DEVICE;
1842 break;
1843 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
1844 identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
1845 break;
1846 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
1847 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
1848 break;
1849 }
1850}
1851
1852static int mptsas_probe_one_phy(struct device *dev,
ac01bbbd 1853 struct mptsas_phyinfo *phy_info, int index, int local)
0c33b27d 1854{
e6b2d76a 1855 MPT_ADAPTER *ioc;
9a28f49a 1856 struct sas_phy *phy;
547f9a21
EM
1857 struct sas_port *port;
1858 int error = 0;
0c33b27d 1859
547f9a21
EM
1860 if (!dev) {
1861 error = -ENODEV;
1862 goto out;
1863 }
e6b2d76a
ME
1864
1865 if (!phy_info->phy) {
1866 phy = sas_phy_alloc(dev, index);
547f9a21
EM
1867 if (!phy) {
1868 error = -ENOMEM;
1869 goto out;
1870 }
e6b2d76a
ME
1871 } else
1872 phy = phy_info->phy;
0c33b27d 1873
9a28f49a 1874 mptsas_parse_device_info(&phy->identify, &phy_info->identify);
0c33b27d
CH
1875
1876 /*
1877 * Set Negotiated link rate.
1878 */
1879 switch (phy_info->negotiated_link_rate) {
1880 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
9a28f49a 1881 phy->negotiated_linkrate = SAS_PHY_DISABLED;
0c33b27d
CH
1882 break;
1883 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
9a28f49a 1884 phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
0c33b27d
CH
1885 break;
1886 case MPI_SAS_IOUNIT0_RATE_1_5:
9a28f49a 1887 phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1888 break;
1889 case MPI_SAS_IOUNIT0_RATE_3_0:
9a28f49a 1890 phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1891 break;
1892 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
1893 case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
1894 default:
9a28f49a 1895 phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
0c33b27d
CH
1896 break;
1897 }
1898
1899 /*
1900 * Set Max hardware link rate.
1901 */
1902 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1903 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
9a28f49a 1904 phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1905 break;
1906 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
9a28f49a 1907 phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1908 break;
1909 default:
1910 break;
1911 }
1912
1913 /*
1914 * Set Max programmed link rate.
1915 */
1916 switch (phy_info->programmed_link_rate &
1917 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1918 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
9a28f49a 1919 phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1920 break;
1921 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
9a28f49a 1922 phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1923 break;
1924 default:
1925 break;
1926 }
1927
1928 /*
1929 * Set Min hardware link rate.
1930 */
1931 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
1932 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
9a28f49a 1933 phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1934 break;
1935 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
9a28f49a 1936 phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1937 break;
1938 default:
1939 break;
1940 }
1941
1942 /*
1943 * Set Min programmed link rate.
1944 */
1945 switch (phy_info->programmed_link_rate &
1946 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
1947 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
9a28f49a 1948 phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
0c33b27d
CH
1949 break;
1950 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
9a28f49a 1951 phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
0c33b27d
CH
1952 break;
1953 default:
1954 break;
1955 }
1956
e6b2d76a 1957 if (!phy_info->phy) {
ac01bbbd 1958
e6b2d76a
ME
1959 error = sas_phy_add(phy);
1960 if (error) {
1961 sas_phy_free(phy);
547f9a21 1962 goto out;
e6b2d76a
ME
1963 }
1964 phy_info->phy = phy;
0c33b27d
CH
1965 }
1966
547f9a21
EM
1967 if (!phy_info->attached.handle ||
1968 !phy_info->port_details)
1969 goto out;
1970
1971 port = mptsas_get_port(phy_info);
1972 ioc = phy_to_ioc(phy_info->phy);
1973
1974 if (phy_info->sas_port_add_phy) {
1975
1976 if (!port) {
dc22f16d 1977 port = sas_port_alloc_num(dev);
547f9a21
EM
1978 if (!port) {
1979 error = -ENOMEM;
1980 goto out;
1981 }
1982 error = sas_port_add(port);
1983 if (error) {
d6ecdd63 1984 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
547f9a21
EM
1985 "%s: exit at line=%d\n", ioc->name,
1986 __FUNCTION__, __LINE__));
1987 goto out;
1988 }
d6ecdd63 1989 mptsas_set_port(ioc, phy_info, port);
29dd3609 1990 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
dc22f16d 1991 "sas_port_alloc: port=%p dev=%p port_id=%d\n",
29dd3609 1992 ioc->name, port, dev, port->port_identifier));
547f9a21 1993 }
29dd3609
EM
1994 dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_port_add_phy: phy_id=%d\n",
1995 ioc->name, phy_info->phy_id));
547f9a21
EM
1996 sas_port_add_phy(port, phy_info->phy);
1997 phy_info->sas_port_add_phy = 0;
1998 }
1999
2000 if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
e6b2d76a 2001
0c33b27d 2002 struct sas_rphy *rphy;
2686de27 2003 struct device *parent;
f013db32 2004 struct sas_identify identify;
0c33b27d 2005
2686de27 2006 parent = dev->parent->parent;
e6b2d76a
ME
2007 /*
2008 * Let the hotplug_work thread handle processing
2009 * the adding/removing of devices that occur
2010 * after start of day.
2011 */
2012 if (ioc->sas_discovery_runtime &&
2013 mptsas_is_end_device(&phy_info->attached))
547f9a21 2014 goto out;
e6b2d76a 2015
f013db32 2016 mptsas_parse_device_info(&identify, &phy_info->attached);
2686de27
JB
2017 if (scsi_is_host_device(parent)) {
2018 struct mptsas_portinfo *port_info;
2019 int i;
2020
2021 mutex_lock(&ioc->sas_topology_mutex);
2022 port_info = mptsas_find_portinfo_by_handle(ioc,
2023 ioc->handle);
2024 mutex_unlock(&ioc->sas_topology_mutex);
2025
2026 for (i = 0; i < port_info->num_phys; i++)
2027 if (port_info->phy_info[i].identify.sas_address ==
0c269e6d
JB
2028 identify.sas_address) {
2029 sas_port_mark_backlink(port);
2686de27 2030 goto out;
0c269e6d 2031 }
2686de27
JB
2032
2033 } else if (scsi_is_sas_rphy(parent)) {
2034 struct sas_rphy *parent_rphy = dev_to_rphy(parent);
2035 if (identify.sas_address ==
0c269e6d
JB
2036 parent_rphy->identify.sas_address) {
2037 sas_port_mark_backlink(port);
2686de27 2038 goto out;
0c269e6d 2039 }
2686de27
JB
2040 }
2041
f013db32
JB
2042 switch (identify.device_type) {
2043 case SAS_END_DEVICE:
547f9a21 2044 rphy = sas_end_device_alloc(port);
f013db32
JB
2045 break;
2046 case SAS_EDGE_EXPANDER_DEVICE:
2047 case SAS_FANOUT_EXPANDER_DEVICE:
547f9a21 2048 rphy = sas_expander_alloc(port, identify.device_type);
f013db32
JB
2049 break;
2050 default:
2051 rphy = NULL;
2052 break;
2053 }
547f9a21 2054 if (!rphy) {
d6ecdd63 2055 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
547f9a21
EM
2056 "%s: exit at line=%d\n", ioc->name,
2057 __FUNCTION__, __LINE__));
2058 goto out;
2059 }
0c33b27d 2060
f013db32 2061 rphy->identify = identify;
0c33b27d
CH
2062 error = sas_rphy_add(rphy);
2063 if (error) {
d6ecdd63 2064 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
547f9a21
EM
2065 "%s: exit at line=%d\n", ioc->name,
2066 __FUNCTION__, __LINE__));
0c33b27d 2067 sas_rphy_free(rphy);
547f9a21 2068 goto out;
0c33b27d 2069 }
d6ecdd63 2070 mptsas_set_rphy(ioc, phy_info, rphy);
0c33b27d
CH
2071 }
2072
547f9a21
EM
2073 out:
2074 return error;
0c33b27d
CH
2075}
2076
2077static int
e6b2d76a 2078mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
0c33b27d 2079{
e6b2d76a 2080 struct mptsas_portinfo *port_info, *hba;
0c33b27d
CH
2081 int error = -ENOMEM, i;
2082
e6b2d76a
ME
2083 hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
2084 if (! hba)
0c33b27d 2085 goto out;
0c33b27d 2086
e6b2d76a 2087 error = mptsas_sas_io_unit_pg0(ioc, hba);
0c33b27d
CH
2088 if (error)
2089 goto out_free_port_info;
2090
edb9068d 2091 mptsas_sas_io_unit_pg1(ioc);
9a28f49a 2092 mutex_lock(&ioc->sas_topology_mutex);
2ecce492
EM
2093 ioc->handle = hba->phy_info[0].handle;
2094 port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
e6b2d76a
ME
2095 if (!port_info) {
2096 port_info = hba;
2097 list_add_tail(&port_info->list, &ioc->sas_topology);
2098 } else {
2ecce492 2099 for (i = 0; i < hba->num_phys; i++) {
e6b2d76a
ME
2100 port_info->phy_info[i].negotiated_link_rate =
2101 hba->phy_info[i].negotiated_link_rate;
2ecce492
EM
2102 port_info->phy_info[i].handle =
2103 hba->phy_info[i].handle;
2104 port_info->phy_info[i].port_id =
2105 hba->phy_info[i].port_id;
2106 }
547f9a21 2107 kfree(hba->phy_info);
e6b2d76a
ME
2108 kfree(hba);
2109 hba = NULL;
2110 }
9a28f49a 2111 mutex_unlock(&ioc->sas_topology_mutex);
0c33b27d
CH
2112 for (i = 0; i < port_info->num_phys; i++) {
2113 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
2114 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
2115 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
2116
2117 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
2ecce492
EM
2118 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2119 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2120 port_info->phy_info[i].handle);
024358ee 2121 port_info->phy_info[i].identify.phy_id =
2ecce492 2122 port_info->phy_info[i].phy_id = i;
547f9a21 2123 if (port_info->phy_info[i].attached.handle)
0c33b27d
CH
2124 mptsas_sas_device_pg0(ioc,
2125 &port_info->phy_info[i].attached,
2126 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2127 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2128 port_info->phy_info[i].attached.handle);
547f9a21 2129 }
0c33b27d 2130
547f9a21
EM
2131 mptsas_setup_wide_ports(ioc, port_info);
2132
2133 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
0c33b27d 2134 mptsas_probe_one_phy(&ioc->sh->shost_gendev,
e6b2d76a 2135 &port_info->phy_info[i], ioc->sas_index, 1);
0c33b27d
CH
2136
2137 return 0;
2138
2139 out_free_port_info:
547f9a21 2140 kfree(hba);
0c33b27d
CH
2141 out:
2142 return error;
2143}
2144
2145static int
e6b2d76a 2146mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
0c33b27d 2147{
e6b2d76a 2148 struct mptsas_portinfo *port_info, *p, *ex;
547f9a21
EM
2149 struct device *parent;
2150 struct sas_rphy *rphy;
0c33b27d
CH
2151 int error = -ENOMEM, i, j;
2152
e6b2d76a
ME
2153 ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
2154 if (!ex)
0c33b27d 2155 goto out;
0c33b27d 2156
e6b2d76a 2157 error = mptsas_sas_expander_pg0(ioc, ex,
2ecce492
EM
2158 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
2159 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
0c33b27d
CH
2160 if (error)
2161 goto out_free_port_info;
2162
2ecce492 2163 *handle = ex->phy_info[0].handle;
0c33b27d 2164
9a28f49a 2165 mutex_lock(&ioc->sas_topology_mutex);
e6b2d76a
ME
2166 port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
2167 if (!port_info) {
2168 port_info = ex;
2169 list_add_tail(&port_info->list, &ioc->sas_topology);
2170 } else {
2ecce492
EM
2171 for (i = 0; i < ex->num_phys; i++) {
2172 port_info->phy_info[i].handle =
2173 ex->phy_info[i].handle;
2174 port_info->phy_info[i].port_id =
2175 ex->phy_info[i].port_id;
2176 }
547f9a21 2177 kfree(ex->phy_info);
e6b2d76a
ME
2178 kfree(ex);
2179 ex = NULL;
2180 }
9a28f49a
CH
2181 mutex_unlock(&ioc->sas_topology_mutex);
2182
0c33b27d 2183 for (i = 0; i < port_info->num_phys; i++) {
0c33b27d
CH
2184 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
2185 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
2186 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
2187
2188 if (port_info->phy_info[i].identify.handle) {
2189 mptsas_sas_device_pg0(ioc,
2190 &port_info->phy_info[i].identify,
2191 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2192 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2193 port_info->phy_info[i].identify.handle);
024358ee
EM
2194 port_info->phy_info[i].identify.phy_id =
2195 port_info->phy_info[i].phy_id;
0c33b27d
CH
2196 }
2197
2198 if (port_info->phy_info[i].attached.handle) {
2199 mptsas_sas_device_pg0(ioc,
2200 &port_info->phy_info[i].attached,
2201 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2202 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2203 port_info->phy_info[i].attached.handle);
db9c9174
ME
2204 port_info->phy_info[i].attached.phy_id =
2205 port_info->phy_info[i].phy_id;
0c33b27d 2206 }
547f9a21 2207 }
0c33b27d 2208
547f9a21
EM
2209 parent = &ioc->sh->shost_gendev;
2210 for (i = 0; i < port_info->num_phys; i++) {
9a28f49a 2211 mutex_lock(&ioc->sas_topology_mutex);
0c33b27d
CH
2212 list_for_each_entry(p, &ioc->sas_topology, list) {
2213 for (j = 0; j < p->num_phys; j++) {
547f9a21 2214 if (port_info->phy_info[i].identify.handle !=
0c33b27d 2215 p->phy_info[j].attached.handle)
547f9a21
EM
2216 continue;
2217 rphy = mptsas_get_rphy(&p->phy_info[j]);
2218 parent = &rphy->dev;
0c33b27d
CH
2219 }
2220 }
9a28f49a 2221 mutex_unlock(&ioc->sas_topology_mutex);
547f9a21
EM
2222 }
2223
2224 mptsas_setup_wide_ports(ioc, port_info);
0c33b27d 2225
547f9a21 2226 for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
ac01bbbd 2227 mptsas_probe_one_phy(parent, &port_info->phy_info[i],
e6b2d76a 2228 ioc->sas_index, 0);
0c33b27d
CH
2229
2230 return 0;
2231
2232 out_free_port_info:
e6b2d76a 2233 if (ex) {
547f9a21 2234 kfree(ex->phy_info);
e6b2d76a
ME
2235 kfree(ex);
2236 }
0c33b27d
CH
2237 out:
2238 return error;
2239}
2240
e6b2d76a
ME
2241/*
2242 * mptsas_delete_expander_phys
2243 *
2244 *
2245 * This will traverse topology, and remove expanders
2246 * that are no longer present
2247 */
2248static void
2249mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
2250{
2251 struct mptsas_portinfo buffer;
2252 struct mptsas_portinfo *port_info, *n, *parent;
547f9a21 2253 struct mptsas_phyinfo *phy_info;
547f9a21 2254 struct sas_port * port;
e6b2d76a 2255 int i;
547f9a21 2256 u64 expander_sas_address;
e6b2d76a
ME
2257
2258 mutex_lock(&ioc->sas_topology_mutex);
2259 list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
2260
2261 if (port_info->phy_info &&
2262 (!(port_info->phy_info[0].identify.device_info &
2263 MPI_SAS_DEVICE_INFO_SMP_TARGET)))
2264 continue;
2265
2266 if (mptsas_sas_expander_pg0(ioc, &buffer,
2267 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
2ecce492
EM
2268 MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
2269 port_info->phy_info[0].handle)) {
e6b2d76a
ME
2270
2271 /*
2272 * Obtain the port_info instance to the parent port
2273 */
2274 parent = mptsas_find_portinfo_by_handle(ioc,
2275 port_info->phy_info[0].identify.handle_parent);
2276
2277 if (!parent)
2278 goto next_port;
2279
547f9a21
EM
2280 expander_sas_address =
2281 port_info->phy_info[0].identify.sas_address;
2282
e6b2d76a
ME
2283 /*
2284 * Delete rphys in the parent that point
2285 * to this expander. The transport layer will
2286 * cleanup all the children.
2287 */
547f9a21
EM
2288 phy_info = parent->phy_info;
2289 for (i = 0; i < parent->num_phys; i++, phy_info++) {
2290 port = mptsas_get_port(phy_info);
2291 if (!port)
2292 continue;
2293 if (phy_info->attached.sas_address !=
2294 expander_sas_address)
e6b2d76a 2295 continue;
d6ecdd63 2296 dsaswideprintk(ioc,
29dd3609
EM
2297 dev_printk(MYIOC_s_DEBUG_FMT, &port->dev,
2298 "delete port (%d)\n", ioc->name, port->port_identifier));
547f9a21 2299 sas_port_delete(port);
d6ecdd63 2300 mptsas_port_delete(ioc, phy_info->port_details);
e6b2d76a
ME
2301 }
2302 next_port:
547f9a21
EM
2303
2304 phy_info = port_info->phy_info;
2305 for (i = 0; i < port_info->num_phys; i++, phy_info++)
d6ecdd63 2306 mptsas_port_delete(ioc, phy_info->port_details);
547f9a21 2307
e6b2d76a 2308 list_del(&port_info->list);
547f9a21 2309 kfree(port_info->phy_info);
e6b2d76a
ME
2310 kfree(port_info);
2311 }
2312 /*
2313 * Free this memory allocated from inside
2314 * mptsas_sas_expander_pg0
2315 */
547f9a21 2316 kfree(buffer.phy_info);
e6b2d76a
ME
2317 }
2318 mutex_unlock(&ioc->sas_topology_mutex);
2319}
2320
2321/*
2322 * Start of day discovery
2323 */
0c33b27d
CH
2324static void
2325mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
2326{
2327 u32 handle = 0xFFFF;
f44e5461 2328 int i;
0c33b27d 2329
e6b2d76a
ME
2330 mutex_lock(&ioc->sas_discovery_mutex);
2331 mptsas_probe_hba_phys(ioc);
2332 while (!mptsas_probe_expander_phys(ioc, &handle))
0c33b27d 2333 ;
f44e5461
ME
2334 /*
2335 Reporting RAID volumes.
2336 */
b506ade9
EM
2337 if (!ioc->ir_firmware)
2338 goto out;
f44e5461
ME
2339 if (!ioc->raid_data.pIocPg2)
2340 goto out;
2341 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
2342 goto out;
793955f5 2343 for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
e8bf3941 2344 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
f44e5461
ME
2345 ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
2346 }
2347 out:
e6b2d76a
ME
2348 mutex_unlock(&ioc->sas_discovery_mutex);
2349}
2350
2351/*
2352 * Work queue thread to handle Runtime discovery
2353 * Mere purpose is the hot add/delete of expanders
547f9a21 2354 *(Mutex UNLOCKED)
e6b2d76a
ME
2355 */
2356static void
547f9a21 2357__mptsas_discovery_work(MPT_ADAPTER *ioc)
e6b2d76a 2358{
e6b2d76a
ME
2359 u32 handle = 0xFFFF;
2360
e6b2d76a
ME
2361 ioc->sas_discovery_runtime=1;
2362 mptsas_delete_expander_phys(ioc);
2363 mptsas_probe_hba_phys(ioc);
2364 while (!mptsas_probe_expander_phys(ioc, &handle))
2365 ;
e6b2d76a 2366 ioc->sas_discovery_runtime=0;
547f9a21
EM
2367}
2368
2369/*
2370 * Work queue thread to handle Runtime discovery
2371 * Mere purpose is the hot add/delete of expanders
2372 *(Mutex LOCKED)
2373 */
2374static void
c4028958 2375mptsas_discovery_work(struct work_struct *work)
547f9a21 2376{
c4028958
DH
2377 struct mptsas_discovery_event *ev =
2378 container_of(work, struct mptsas_discovery_event, work);
547f9a21
EM
2379 MPT_ADAPTER *ioc = ev->ioc;
2380
2381 mutex_lock(&ioc->sas_discovery_mutex);
2382 __mptsas_discovery_work(ioc);
e6b2d76a 2383 mutex_unlock(&ioc->sas_discovery_mutex);
547f9a21 2384 kfree(ev);
0c33b27d
CH
2385}
2386
9a28f49a 2387static struct mptsas_phyinfo *
547f9a21 2388mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
9a28f49a
CH
2389{
2390 struct mptsas_portinfo *port_info;
9a28f49a 2391 struct mptsas_phyinfo *phy_info = NULL;
547f9a21 2392 int i;
9a28f49a 2393
9a28f49a
CH
2394 mutex_lock(&ioc->sas_topology_mutex);
2395 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2396 for (i = 0; i < port_info->num_phys; i++) {
b506ade9
EM
2397 if (!mptsas_is_end_device(
2398 &port_info->phy_info[i].attached))
2399 continue;
547f9a21
EM
2400 if (port_info->phy_info[i].attached.sas_address
2401 != sas_address)
2402 continue;
b506ade9
EM
2403 phy_info = &port_info->phy_info[i];
2404 break;
2405 }
2406 }
2407 mutex_unlock(&ioc->sas_topology_mutex);
2408 return phy_info;
2409}
2410
2411static struct mptsas_phyinfo *
2412mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u8 channel, u8 id)
2413{
2414 struct mptsas_portinfo *port_info;
2415 struct mptsas_phyinfo *phy_info = NULL;
2416 int i;
2417
2418 mutex_lock(&ioc->sas_topology_mutex);
2419 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2420 for (i = 0; i < port_info->num_phys; i++) {
547f9a21
EM
2421 if (!mptsas_is_end_device(
2422 &port_info->phy_info[i].attached))
2423 continue;
b506ade9
EM
2424 if (port_info->phy_info[i].attached.id != id)
2425 continue;
2426 if (port_info->phy_info[i].attached.channel != channel)
2427 continue;
547f9a21
EM
2428 phy_info = &port_info->phy_info[i];
2429 break;
9a28f49a
CH
2430 }
2431 }
2432 mutex_unlock(&ioc->sas_topology_mutex);
9a28f49a
CH
2433 return phy_info;
2434}
2435
2436static struct mptsas_phyinfo *
b506ade9 2437mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
9a28f49a
CH
2438{
2439 struct mptsas_portinfo *port_info;
2440 struct mptsas_phyinfo *phy_info = NULL;
2441 int i;
2442
9a28f49a
CH
2443 mutex_lock(&ioc->sas_topology_mutex);
2444 list_for_each_entry(port_info, &ioc->sas_topology, list) {
547f9a21 2445 for (i = 0; i < port_info->num_phys; i++) {
547f9a21
EM
2446 if (!mptsas_is_end_device(
2447 &port_info->phy_info[i].attached))
2448 continue;
b506ade9
EM
2449 if (port_info->phy_info[i].attached.phys_disk_num == ~0)
2450 continue;
2451 if (port_info->phy_info[i].attached.phys_disk_num != id)
2452 continue;
2453 if (port_info->phy_info[i].attached.channel != channel)
2454 continue;
547f9a21
EM
2455 phy_info = &port_info->phy_info[i];
2456 break;
2457 }
9a28f49a
CH
2458 }
2459 mutex_unlock(&ioc->sas_topology_mutex);
9a28f49a
CH
2460 return phy_info;
2461}
2462
4b766471
ME
2463/*
2464 * Work queue thread to clear the persitency table
2465 */
2466static void
c4028958 2467mptsas_persist_clear_table(struct work_struct *work)
4b766471 2468{
c4028958 2469 MPT_ADAPTER *ioc = container_of(work, MPT_ADAPTER, sas_persist_task);
4b766471
ME
2470
2471 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2472}
2473
f44e5461
ME
2474static void
2475mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
2476{
f99be43b
EM
2477 int rc;
2478
f44e5461 2479 sdev->no_uld_attach = data ? 1 : 0;
f99be43b 2480 rc = scsi_device_reprobe(sdev);
f44e5461
ME
2481}
2482
2483static void
2484mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
2485{
2486 starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
2487 mptsas_reprobe_lun);
2488}
2489
b506ade9
EM
2490static void
2491mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
2492{
2493 CONFIGPARMS cfg;
2494 ConfigPageHeader_t hdr;
2495 dma_addr_t dma_handle;
2496 pRaidVolumePage0_t buffer = NULL;
2497 RaidPhysDiskPage0_t phys_disk;
2498 int i;
2499 struct mptsas_hotplug_event *ev;
2500
2501 memset(&cfg, 0 , sizeof(CONFIGPARMS));
2502 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
2503 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
2504 cfg.pageAddr = (channel << 8) + id;
2505 cfg.cfghdr.hdr = &hdr;
2506 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2507
2508 if (mpt_config(ioc, &cfg) != 0)
2509 goto out;
2510
2511 if (!hdr.PageLength)
2512 goto out;
2513
2514 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
2515 &dma_handle);
2516
2517 if (!buffer)
2518 goto out;
2519
2520 cfg.physAddr = dma_handle;
2521 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2522
2523 if (mpt_config(ioc, &cfg) != 0)
2524 goto out;
2525
2526 if (!(buffer->VolumeStatus.Flags &
2527 MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
2528 goto out;
2529
2530 if (!buffer->NumPhysDisks)
2531 goto out;
2532
2533 for (i = 0; i < buffer->NumPhysDisks; i++) {
2534
2535 if (mpt_raid_phys_disk_pg0(ioc,
2536 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
2537 continue;
2538
2539 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2540 if (!ev) {
29dd3609 2541 printk(MYIOC_s_WARN_FMT "mptsas: lost hotplug event\n", ioc->name);
b506ade9
EM
2542 goto out;
2543 }
2544
2545 INIT_WORK(&ev->work, mptsas_hotplug_work);
2546 ev->ioc = ioc;
2547 ev->id = phys_disk.PhysDiskID;
2548 ev->channel = phys_disk.PhysDiskBus;
2549 ev->phys_disk_num_valid = 1;
2550 ev->phys_disk_num = phys_disk.PhysDiskNum;
2551 ev->event_type = MPTSAS_ADD_DEVICE;
2552 schedule_work(&ev->work);
2553 }
2554
2555 out:
2556 if (buffer)
2557 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
2558 dma_handle);
2559}
e6b2d76a
ME
2560/*
2561 * Work queue thread to handle SAS hotplug events
2562 */
9a28f49a 2563static void
c4028958 2564mptsas_hotplug_work(struct work_struct *work)
9a28f49a 2565{
c4028958
DH
2566 struct mptsas_hotplug_event *ev =
2567 container_of(work, struct mptsas_hotplug_event, work);
b506ade9 2568
9a28f49a
CH
2569 MPT_ADAPTER *ioc = ev->ioc;
2570 struct mptsas_phyinfo *phy_info;
2571 struct sas_rphy *rphy;
547f9a21 2572 struct sas_port *port;
c73787ee 2573 struct scsi_device *sdev;
547f9a21 2574 struct scsi_target * starget;
f013db32 2575 struct sas_identify identify;
9a28f49a 2576 char *ds = NULL;
c73787ee 2577 struct mptsas_devinfo sas_device;
f44e5461 2578 VirtTarget *vtarget;
547f9a21 2579 VirtDevice *vdevice;
9a28f49a 2580
547f9a21 2581 mutex_lock(&ioc->sas_discovery_mutex);
9a28f49a
CH
2582 switch (ev->event_type) {
2583 case MPTSAS_DEL_DEVICE:
9a28f49a 2584
b506ade9
EM
2585 phy_info = NULL;
2586 if (ev->phys_disk_num_valid) {
2587 if (ev->hidden_raid_component){
2588 if (mptsas_sas_device_pg0(ioc, &sas_device,
2589 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2590 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2591 (ev->channel << 8) + ev->id)) {
d6ecdd63 2592 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
b506ade9
EM
2593 "%s: exit at line=%d\n", ioc->name,
2594 __FUNCTION__, __LINE__));
2595 break;
2596 }
2597 phy_info = mptsas_find_phyinfo_by_sas_address(
2598 ioc, sas_device.sas_address);
2599 }else
2600 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
2601 ioc, ev->channel, ev->phys_disk_num);
2602 }
2603
2604 if (!phy_info)
2605 phy_info = mptsas_find_phyinfo_by_target(ioc,
2606 ev->channel, ev->id);
e6b2d76a 2607
f44e5461
ME
2608 /*
2609 * Sanity checks, for non-existing phys and remote rphys.
2610 */
b506ade9 2611 if (!phy_info){
d6ecdd63 2612 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
b506ade9
EM
2613 "%s: exit at line=%d\n", ioc->name,
2614 __FUNCTION__, __LINE__));
2615 break;
2616 }
2617 if (!phy_info->port_details) {
d6ecdd63 2618 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
547f9a21
EM
2619 "%s: exit at line=%d\n", ioc->name,
2620 __FUNCTION__, __LINE__));
9a28f49a 2621 break;
547f9a21
EM
2622 }
2623 rphy = mptsas_get_rphy(phy_info);
2624 if (!rphy) {
d6ecdd63 2625 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
547f9a21
EM
2626 "%s: exit at line=%d\n", ioc->name,
2627 __FUNCTION__, __LINE__));
2628 break;
2629 }
b506ade9 2630
547f9a21
EM
2631 port = mptsas_get_port(phy_info);
2632 if (!port) {
d6ecdd63 2633 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
547f9a21
EM
2634 "%s: exit at line=%d\n", ioc->name,
2635 __FUNCTION__, __LINE__));
f44e5461 2636 break;
547f9a21
EM
2637 }
2638
2639 starget = mptsas_get_starget(phy_info);
2640 if (starget) {
2641 vtarget = starget->hostdata;
f44e5461 2642
547f9a21 2643 if (!vtarget) {
d6ecdd63 2644 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
547f9a21
EM
2645 "%s: exit at line=%d\n", ioc->name,
2646 __FUNCTION__, __LINE__));
f44e5461 2647 break;
547f9a21
EM
2648 }
2649
f44e5461
ME
2650 /*
2651 * Handling RAID components
2652 */
b506ade9
EM
2653 if (ev->phys_disk_num_valid &&
2654 ev->hidden_raid_component) {
2655 printk(MYIOC_s_INFO_FMT
2656 "RAID Hidding: channel=%d, id=%d, "
2657 "physdsk %d \n", ioc->name, ev->channel,
2658 ev->id, ev->phys_disk_num);
793955f5 2659 vtarget->id = ev->phys_disk_num;
b506ade9
EM
2660 vtarget->tflags |=
2661 MPT_TARGET_FLAGS_RAID_COMPONENT;
547f9a21 2662 mptsas_reprobe_target(starget, 1);
b506ade9
EM
2663 phy_info->attached.phys_disk_num =
2664 ev->phys_disk_num;
2665 break;
f44e5461 2666 }
9a28f49a
CH
2667 }
2668
b506ade9
EM
2669 if (phy_info->attached.device_info &
2670 MPI_SAS_DEVICE_INFO_SSP_TARGET)
c73787ee 2671 ds = "ssp";
b506ade9
EM
2672 if (phy_info->attached.device_info &
2673 MPI_SAS_DEVICE_INFO_STP_TARGET)
c73787ee 2674 ds = "stp";
b506ade9
EM
2675 if (phy_info->attached.device_info &
2676 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
c73787ee
ME
2677 ds = "sata";
2678
2679 printk(MYIOC_s_INFO_FMT
2680 "removing %s device, channel %d, id %d, phy %d\n",
2681 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
29dd3609
EM
2682 dev_printk(MYIOC_s_DEBUG_FMT, &port->dev,
2683 "delete port (%d)\n", ioc->name, port->port_identifier);
547f9a21 2684 sas_port_delete(port);
d6ecdd63 2685 mptsas_port_delete(ioc, phy_info->port_details);
9a28f49a
CH
2686 break;
2687 case MPTSAS_ADD_DEVICE:
c73787ee 2688
bd23e94c
ME
2689 if (ev->phys_disk_num_valid)
2690 mpt_findImVolumes(ioc);
2691
c73787ee 2692 /*
e3094447 2693 * Refresh sas device pg0 data
c73787ee 2694 */
e3094447
CH
2695 if (mptsas_sas_device_pg0(ioc, &sas_device,
2696 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
b506ade9
EM
2697 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2698 (ev->channel << 8) + ev->id)) {
d6ecdd63 2699 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
547f9a21
EM
2700 "%s: exit at line=%d\n", ioc->name,
2701 __FUNCTION__, __LINE__));
e3094447 2702 break;
547f9a21 2703 }
9a28f49a 2704
547f9a21 2705 __mptsas_discovery_work(ioc);
e6b2d76a 2706
547f9a21
EM
2707 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
2708 sas_device.sas_address);
e6b2d76a 2709
547f9a21 2710 if (!phy_info || !phy_info->port_details) {
d6ecdd63 2711 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
547f9a21
EM
2712 "%s: exit at line=%d\n", ioc->name,
2713 __FUNCTION__, __LINE__));
2714 break;
e6b2d76a
ME
2715 }
2716
547f9a21 2717 starget = mptsas_get_starget(phy_info);
b506ade9
EM
2718 if (starget && (!ev->hidden_raid_component)){
2719
547f9a21 2720 vtarget = starget->hostdata;
9a28f49a 2721
547f9a21 2722 if (!vtarget) {
d6ecdd63 2723 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
29dd3609
EM
2724 "%s: exit at line=%d\n", ioc->name,
2725 __FUNCTION__, __LINE__));
f44e5461 2726 break;
547f9a21 2727 }
f44e5461
ME
2728 /*
2729 * Handling RAID components
2730 */
2731 if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
b506ade9
EM
2732 printk(MYIOC_s_INFO_FMT
2733 "RAID Exposing: channel=%d, id=%d, "
2734 "physdsk %d \n", ioc->name, ev->channel,
2735 ev->id, ev->phys_disk_num);
2736 vtarget->tflags &=
2737 ~MPT_TARGET_FLAGS_RAID_COMPONENT;
793955f5 2738 vtarget->id = ev->id;
547f9a21 2739 mptsas_reprobe_target(starget, 0);
b506ade9 2740 phy_info->attached.phys_disk_num = ~0;
f44e5461 2741 }
9a28f49a
CH
2742 break;
2743 }
2744
547f9a21 2745 if (mptsas_get_rphy(phy_info)) {
d6ecdd63 2746 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
547f9a21
EM
2747 "%s: exit at line=%d\n", ioc->name,
2748 __FUNCTION__, __LINE__));
b506ade9 2749 if (ev->channel) printk("%d\n", __LINE__);
f44e5461 2750 break;
547f9a21 2751 }
b506ade9 2752
547f9a21
EM
2753 port = mptsas_get_port(phy_info);
2754 if (!port) {
d6ecdd63 2755 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
547f9a21
EM
2756 "%s: exit at line=%d\n", ioc->name,
2757 __FUNCTION__, __LINE__));
2758 break;
2759 }
e3094447
CH
2760 memcpy(&phy_info->attached, &sas_device,
2761 sizeof(struct mptsas_devinfo));
9a28f49a 2762
b506ade9
EM
2763 if (phy_info->attached.device_info &
2764 MPI_SAS_DEVICE_INFO_SSP_TARGET)
c73787ee 2765 ds = "ssp";
b506ade9
EM
2766 if (phy_info->attached.device_info &
2767 MPI_SAS_DEVICE_INFO_STP_TARGET)
c73787ee 2768 ds = "stp";
b506ade9
EM
2769 if (phy_info->attached.device_info &
2770 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
c73787ee
ME
2771 ds = "sata";
2772
2773 printk(MYIOC_s_INFO_FMT
2774 "attaching %s device, channel %d, id %d, phy %d\n",
2775 ioc->name, ds, ev->channel, ev->id, ev->phy_id);
2776
f013db32 2777 mptsas_parse_device_info(&identify, &phy_info->attached);
547f9a21
EM
2778 rphy = sas_end_device_alloc(port);
2779 if (!rphy) {
d6ecdd63 2780 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
547f9a21
EM
2781 "%s: exit at line=%d\n", ioc->name,
2782 __FUNCTION__, __LINE__));
9a28f49a 2783 break; /* non-fatal: an rphy can be added later */
547f9a21 2784 }
9a28f49a 2785
f013db32 2786 rphy->identify = identify;
9a28f49a 2787 if (sas_rphy_add(rphy)) {
d6ecdd63 2788 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
547f9a21
EM
2789 "%s: exit at line=%d\n", ioc->name,
2790 __FUNCTION__, __LINE__));
9a28f49a
CH
2791 sas_rphy_free(rphy);
2792 break;
2793 }
d6ecdd63 2794 mptsas_set_rphy(ioc, phy_info, rphy);
9a28f49a 2795 break;
c73787ee 2796 case MPTSAS_ADD_RAID:
e8bf3941
JB
2797 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2798 ev->id, 0);
c73787ee
ME
2799 if (sdev) {
2800 scsi_device_put(sdev);
2801 break;
2802 }
2803 printk(MYIOC_s_INFO_FMT
4b766471 2804 "attaching raid volume, channel %d, id %d\n",
e8bf3941
JB
2805 ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2806 scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
c73787ee
ME
2807 mpt_findImVolumes(ioc);
2808 break;
2809 case MPTSAS_DEL_RAID:
e8bf3941 2810 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
b506ade9 2811 ev->id, 0);
c73787ee
ME
2812 if (!sdev)
2813 break;
2814 printk(MYIOC_s_INFO_FMT
4b766471 2815 "removing raid volume, channel %d, id %d\n",
e8bf3941 2816 ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
b506ade9 2817 vdevice = sdev->hostdata;
c73787ee
ME
2818 scsi_remove_device(sdev);
2819 scsi_device_put(sdev);
2820 mpt_findImVolumes(ioc);
2821 break;
b506ade9
EM
2822 case MPTSAS_ADD_INACTIVE_VOLUME:
2823 mptsas_adding_inactive_raid_components(ioc,
2824 ev->channel, ev->id);
2825 break;
bd23e94c
ME
2826 case MPTSAS_IGNORE_EVENT:
2827 default:
2828 break;
9a28f49a
CH
2829 }
2830
e6b2d76a 2831 mutex_unlock(&ioc->sas_discovery_mutex);
547f9a21 2832 kfree(ev);
9a28f49a
CH
2833}
2834
2835static void
547f9a21 2836mptsas_send_sas_event(MPT_ADAPTER *ioc,
9a28f49a
CH
2837 EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
2838{
2839 struct mptsas_hotplug_event *ev;
2840 u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
2841 __le64 sas_address;
2842
2843 if ((device_info &
2844 (MPI_SAS_DEVICE_INFO_SSP_TARGET |
2845 MPI_SAS_DEVICE_INFO_STP_TARGET |
2846 MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
2847 return;
2848
4b766471 2849 switch (sas_event_data->ReasonCode) {
4b766471 2850 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
df9e062a
EM
2851
2852 mptsas_target_reset_queue(ioc, sas_event_data);
2853 break;
2854
2855 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
547f9a21 2856 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
4b766471 2857 if (!ev) {
29dd3609 2858 printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name);
4b766471
ME
2859 break;
2860 }
9a28f49a 2861
c4028958 2862 INIT_WORK(&ev->work, mptsas_hotplug_work);
4b766471
ME
2863 ev->ioc = ioc;
2864 ev->handle = le16_to_cpu(sas_event_data->DevHandle);
2865 ev->parent_handle =
2866 le16_to_cpu(sas_event_data->ParentDevHandle);
2867 ev->channel = sas_event_data->Bus;
2868 ev->id = sas_event_data->TargetID;
2869 ev->phy_id = sas_event_data->PhyNum;
2870 memcpy(&sas_address, &sas_event_data->SASAddress,
2871 sizeof(__le64));
2872 ev->sas_address = le64_to_cpu(sas_address);
2873 ev->device_info = device_info;
2874
2875 if (sas_event_data->ReasonCode &
2876 MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
2877 ev->event_type = MPTSAS_ADD_DEVICE;
2878 else
2879 ev->event_type = MPTSAS_DEL_DEVICE;
2880 schedule_work(&ev->work);
2881 break;
2882 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
2883 /*
2884 * Persistent table is full.
2885 */
547f9a21 2886 INIT_WORK(&ioc->sas_persist_task,
c4028958 2887 mptsas_persist_clear_table);
547f9a21 2888 schedule_work(&ioc->sas_persist_task);
4b766471 2889 break;
b506ade9
EM
2890 /*
2891 * TODO, handle other events
2892 */
4b766471 2893 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
b506ade9 2894 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
4b766471 2895 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
b506ade9
EM
2896 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
2897 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
2898 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
2899 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
4b766471
ME
2900 default:
2901 break;
9a28f49a 2902 }
9a28f49a 2903}
c73787ee 2904static void
547f9a21 2905mptsas_send_raid_event(MPT_ADAPTER *ioc,
c73787ee
ME
2906 EVENT_DATA_RAID *raid_event_data)
2907{
2908 struct mptsas_hotplug_event *ev;
bd23e94c
ME
2909 int status = le32_to_cpu(raid_event_data->SettingsStatus);
2910 int state = (status >> 8) & 0xff;
c73787ee
ME
2911
2912 if (ioc->bus_type != SAS)
2913 return;
2914
547f9a21 2915 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
c73787ee 2916 if (!ev) {
29dd3609 2917 printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name);
c73787ee
ME
2918 return;
2919 }
2920
c4028958 2921 INIT_WORK(&ev->work, mptsas_hotplug_work);
c73787ee
ME
2922 ev->ioc = ioc;
2923 ev->id = raid_event_data->VolumeID;
b506ade9 2924 ev->channel = raid_event_data->VolumeBus;
bd23e94c 2925 ev->event_type = MPTSAS_IGNORE_EVENT;
c73787ee
ME
2926
2927 switch (raid_event_data->ReasonCode) {
2928 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
b506ade9
EM
2929 ev->phys_disk_num_valid = 1;
2930 ev->phys_disk_num = raid_event_data->PhysDiskNum;
c73787ee
ME
2931 ev->event_type = MPTSAS_ADD_DEVICE;
2932 break;
2933 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
f44e5461
ME
2934 ev->phys_disk_num_valid = 1;
2935 ev->phys_disk_num = raid_event_data->PhysDiskNum;
b506ade9 2936 ev->hidden_raid_component = 1;
c73787ee
ME
2937 ev->event_type = MPTSAS_DEL_DEVICE;
2938 break;
bd23e94c
ME
2939 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
2940 switch (state) {
2941 case MPI_PD_STATE_ONLINE:
b506ade9 2942 case MPI_PD_STATE_NOT_COMPATIBLE:
bd23e94c
ME
2943 ev->phys_disk_num_valid = 1;
2944 ev->phys_disk_num = raid_event_data->PhysDiskNum;
b506ade9 2945 ev->hidden_raid_component = 1;
bd23e94c
ME
2946 ev->event_type = MPTSAS_ADD_DEVICE;
2947 break;
2948 case MPI_PD_STATE_MISSING:
bd23e94c
ME
2949 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
2950 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
2951 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
b506ade9
EM
2952 ev->phys_disk_num_valid = 1;
2953 ev->phys_disk_num = raid_event_data->PhysDiskNum;
bd23e94c
ME
2954 ev->event_type = MPTSAS_DEL_DEVICE;
2955 break;
2956 default:
2957 break;
2958 }
2959 break;
c73787ee
ME
2960 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
2961 ev->event_type = MPTSAS_DEL_RAID;
2962 break;
2963 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
2964 ev->event_type = MPTSAS_ADD_RAID;
2965 break;
2966 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
bd23e94c
ME
2967 switch (state) {
2968 case MPI_RAIDVOL0_STATUS_STATE_FAILED:
2969 case MPI_RAIDVOL0_STATUS_STATE_MISSING:
2970 ev->event_type = MPTSAS_DEL_RAID;
2971 break;
2972 case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
2973 case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
2974 ev->event_type = MPTSAS_ADD_RAID;
2975 break;
2976 default:
2977 break;
2978 }
c73787ee
ME
2979 break;
2980 default:
2981 break;
2982 }
2983 schedule_work(&ev->work);
2984}
2985
e6b2d76a 2986static void
547f9a21 2987mptsas_send_discovery_event(MPT_ADAPTER *ioc,
e6b2d76a
ME
2988 EVENT_DATA_SAS_DISCOVERY *discovery_data)
2989{
2990 struct mptsas_discovery_event *ev;
2991
2992 /*
2993 * DiscoveryStatus
2994 *
2995 * This flag will be non-zero when firmware
2996 * kicks off discovery, and return to zero
2997 * once its completed.
2998 */
2999 if (discovery_data->DiscoveryStatus)
3000 return;
3001
547f9a21 3002 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
e6b2d76a
ME
3003 if (!ev)
3004 return;
c4028958 3005 INIT_WORK(&ev->work, mptsas_discovery_work);
e6b2d76a
ME
3006 ev->ioc = ioc;
3007 schedule_work(&ev->work);
3008};
3009
b506ade9
EM
3010/*
3011 * mptsas_send_ir2_event - handle exposing hidden disk when
3012 * an inactive raid volume is added
3013 *
3014 * @ioc: Pointer to MPT_ADAPTER structure
3015 * @ir2_data
3016 *
3017 */
3018static void
3019mptsas_send_ir2_event(MPT_ADAPTER *ioc, PTR_MPI_EVENT_DATA_IR2 ir2_data)
3020{
3021 struct mptsas_hotplug_event *ev;
3022
3023 if (ir2_data->ReasonCode !=
3024 MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED)
3025 return;
3026
3027 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
3028 if (!ev)
3029 return;
3030
3031 INIT_WORK(&ev->work, mptsas_hotplug_work);
3032 ev->ioc = ioc;
3033 ev->id = ir2_data->TargetID;
3034 ev->channel = ir2_data->Bus;
3035 ev->event_type = MPTSAS_ADD_INACTIVE_VOLUME;
3036
3037 schedule_work(&ev->work);
3038};
e6b2d76a 3039
9a28f49a
CH
3040static int
3041mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
3042{
c73787ee 3043 int rc=1;
9a28f49a
CH
3044 u8 event = le32_to_cpu(reply->Event) & 0xFF;
3045
3046 if (!ioc->sh)
c73787ee 3047 goto out;
9a28f49a 3048
e6b2d76a
ME
3049 /*
3050 * sas_discovery_ignore_events
3051 *
3052 * This flag is to prevent anymore processing of
3053 * sas events once mptsas_remove function is called.
3054 */
3055 if (ioc->sas_discovery_ignore_events) {
3056 rc = mptscsih_event_process(ioc, reply);
3057 goto out;
3058 }
3059
9a28f49a
CH
3060 switch (event) {
3061 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
547f9a21 3062 mptsas_send_sas_event(ioc,
9a28f49a 3063 (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
c73787ee
ME
3064 break;
3065 case MPI_EVENT_INTEGRATED_RAID:
547f9a21 3066 mptsas_send_raid_event(ioc,
c73787ee
ME
3067 (EVENT_DATA_RAID *)reply->Data);
3068 break;
79de278e 3069 case MPI_EVENT_PERSISTENT_TABLE_FULL:
547f9a21 3070 INIT_WORK(&ioc->sas_persist_task,
c4028958 3071 mptsas_persist_clear_table);
547f9a21 3072 schedule_work(&ioc->sas_persist_task);
79de278e 3073 break;
4b766471 3074 case MPI_EVENT_SAS_DISCOVERY:
547f9a21 3075 mptsas_send_discovery_event(ioc,
e6b2d76a
ME
3076 (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
3077 break;
b506ade9
EM
3078 case MPI_EVENT_IR2:
3079 mptsas_send_ir2_event(ioc,
3080 (PTR_MPI_EVENT_DATA_IR2)reply->Data);
3081 break;
9a28f49a 3082 default:
c73787ee
ME
3083 rc = mptscsih_event_process(ioc, reply);
3084 break;
9a28f49a 3085 }
c73787ee
ME
3086 out:
3087
3088 return rc;
9a28f49a
CH
3089}
3090
0c33b27d
CH
3091static int
3092mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3093{
3094 struct Scsi_Host *sh;
3095 MPT_SCSI_HOST *hd;
3096 MPT_ADAPTER *ioc;
3097 unsigned long flags;
1ca00bb7 3098 int ii;
0c33b27d
CH
3099 int numSGE = 0;
3100 int scale;
3101 int ioc_cap;
0c33b27d
CH
3102 int error=0;
3103 int r;
3104
3105 r = mpt_attach(pdev,id);
3106 if (r)
3107 return r;
3108
3109 ioc = pci_get_drvdata(pdev);
3110 ioc->DoneCtx = mptsasDoneCtx;
3111 ioc->TaskCtx = mptsasTaskCtx;
3112 ioc->InternalCtx = mptsasInternalCtx;
3113
3114 /* Added sanity check on readiness of the MPT adapter.
3115 */
3116 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
3117 printk(MYIOC_s_WARN_FMT
3118 "Skipping because it's not operational!\n",
3119 ioc->name);
7acec1e7
MED
3120 error = -ENODEV;
3121 goto out_mptsas_probe;
0c33b27d
CH
3122 }
3123
3124 if (!ioc->active) {
3125 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
3126 ioc->name);
7acec1e7
MED
3127 error = -ENODEV;
3128 goto out_mptsas_probe;
0c33b27d
CH
3129 }
3130
3131 /* Sanity check - ensure at least 1 port is INITIATOR capable
3132 */
3133 ioc_cap = 0;
3134 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
3135 if (ioc->pfacts[ii].ProtocolFlags &
3136 MPI_PORTFACTS_PROTOCOL_INITIATOR)
3137 ioc_cap++;
3138 }
3139
3140 if (!ioc_cap) {
3141 printk(MYIOC_s_WARN_FMT
3142 "Skipping ioc=%p because SCSI Initiator mode "
3143 "is NOT enabled!\n", ioc->name, ioc);
466544d8 3144 return 0;
0c33b27d
CH
3145 }
3146
3147 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
3148 if (!sh) {
3149 printk(MYIOC_s_WARN_FMT
3150 "Unable to register controller with SCSI subsystem\n",
3151 ioc->name);
7acec1e7
MED
3152 error = -1;
3153 goto out_mptsas_probe;
0c33b27d
CH
3154 }
3155
3156 spin_lock_irqsave(&ioc->FreeQlock, flags);
3157
3158 /* Attach the SCSI Host to the IOC structure
3159 */
3160 ioc->sh = sh;
3161
3162 sh->io_port = 0;
3163 sh->n_io_port = 0;
3164 sh->irq = 0;
3165
3166 /* set 16 byte cdb's */
3167 sh->max_cmd_len = 16;
3168
793955f5
EM
3169 sh->max_id = ioc->pfacts[0].PortSCSIID;
3170 sh->max_lun = max_lun;
0c33b27d
CH
3171
3172 sh->transportt = mptsas_transport_template;
3173
0c33b27d
CH
3174 sh->this_id = ioc->pfacts[0].PortSCSIID;
3175
3176 /* Required entry.
3177 */
3178 sh->unique_id = ioc->id;
3179
3180 INIT_LIST_HEAD(&ioc->sas_topology);
9a28f49a 3181 mutex_init(&ioc->sas_topology_mutex);
e6b2d76a 3182 mutex_init(&ioc->sas_discovery_mutex);
eeb846ce 3183 mutex_init(&ioc->sas_mgmt.mutex);
da4fa655 3184 init_completion(&ioc->sas_mgmt.done);
0c33b27d
CH
3185
3186 /* Verify that we won't exceed the maximum
3187 * number of chain buffers
3188 * We can optimize: ZZ = req_sz/sizeof(SGE)
3189 * For 32bit SGE's:
3190 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
3191 * + (req_sz - 64)/sizeof(SGE)
3192 * A slightly different algorithm is required for
3193 * 64bit SGEs.
3194 */
3195 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3196 if (sizeof(dma_addr_t) == sizeof(u64)) {
3197 numSGE = (scale - 1) *
3198 (ioc->facts.MaxChainDepth-1) + scale +
3199 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
3200 sizeof(u32));
3201 } else {
3202 numSGE = 1 + (scale - 1) *
3203 (ioc->facts.MaxChainDepth-1) + scale +
3204 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
3205 sizeof(u32));
3206 }
3207
3208 if (numSGE < sh->sg_tablesize) {
3209 /* Reset this value */
d6ecdd63 3210 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
0c33b27d
CH
3211 "Resetting sg_tablesize to %d from %d\n",
3212 ioc->name, numSGE, sh->sg_tablesize));
3213 sh->sg_tablesize = numSGE;
3214 }
3215
0c33b27d
CH
3216 hd = (MPT_SCSI_HOST *) sh->hostdata;
3217 hd->ioc = ioc;
3218
3219 /* SCSI needs scsi_cmnd lookup table!
3220 * (with size equal to req_depth*PtrSz!)
3221 */
1ca00bb7
CH
3222 hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
3223 if (!hd->ScsiLookup) {
0c33b27d 3224 error = -ENOMEM;
7acec1e7 3225 goto out_mptsas_probe;
0c33b27d
CH
3226 }
3227
d6ecdd63 3228 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
1ca00bb7 3229 ioc->name, hd->ScsiLookup));
0c33b27d 3230
0c33b27d
CH
3231 /* Clear the TM flags
3232 */
3233 hd->tmPending = 0;
3234 hd->tmState = TM_STATE_NONE;
3235 hd->resetPending = 0;
3236 hd->abortSCpnt = NULL;
3237
3238 /* Clear the pointer used to store
3239 * single-threaded commands, i.e., those
3240 * issued during a bus scan, dv and
3241 * configuration pages.
3242 */
3243 hd->cmdPtr = NULL;
3244
3245 /* Initialize this SCSI Hosts' timers
3246 * To use, set the timer expires field
3247 * and add_timer
3248 */
3249 init_timer(&hd->timer);
3250 hd->timer.data = (unsigned long) hd;
3251 hd->timer.function = mptscsih_timer_expired;
3252
0c33b27d
CH
3253 ioc->sas_data.ptClear = mpt_pt_clear;
3254
df9e062a
EM
3255 init_waitqueue_head(&hd->scandv_waitq);
3256 hd->scandv_wait_done = 0;
3257 hd->last_queue_full = 0;
3258 INIT_LIST_HEAD(&hd->target_reset_list);
3259 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3260
0c33b27d
CH
3261 if (ioc->sas_data.ptClear==1) {
3262 mptbase_sas_persist_operation(
3263 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
3264 }
3265
0c33b27d
CH
3266 error = scsi_add_host(sh, &ioc->pcidev->dev);
3267 if (error) {
29dd3609
EM
3268 dprintk(ioc, printk(MYIOC_s_ERR_FMT
3269 "scsi_add_host failed\n", ioc->name));
7acec1e7 3270 goto out_mptsas_probe;
0c33b27d
CH
3271 }
3272
3273 mptsas_scan_sas_topology(ioc);
3274
3275 return 0;
3276
547f9a21 3277 out_mptsas_probe:
0c33b27d
CH
3278
3279 mptscsih_remove(pdev);
3280 return error;
3281}
3282
3283static void __devexit mptsas_remove(struct pci_dev *pdev)
3284{
3285 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
3286 struct mptsas_portinfo *p, *n;
547f9a21 3287 int i;
0c33b27d 3288
b506ade9 3289 ioc->sas_discovery_ignore_events = 1;
0c33b27d
CH
3290 sas_remove_host(ioc->sh);
3291
9a28f49a 3292 mutex_lock(&ioc->sas_topology_mutex);
0c33b27d
CH
3293 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
3294 list_del(&p->list);
547f9a21 3295 for (i = 0 ; i < p->num_phys ; i++)
d6ecdd63 3296 mptsas_port_delete(ioc, p->phy_info[i].port_details);
547f9a21 3297 kfree(p->phy_info);
0c33b27d
CH
3298 kfree(p);
3299 }
9a28f49a 3300 mutex_unlock(&ioc->sas_topology_mutex);
0c33b27d
CH
3301
3302 mptscsih_remove(pdev);
3303}
3304
3305static struct pci_device_id mptsas_pci_table[] = {
87cf8986 3306 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
0c33b27d 3307 PCI_ANY_ID, PCI_ANY_ID },
87cf8986 3308 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
0c33b27d 3309 PCI_ANY_ID, PCI_ANY_ID },
87cf8986 3310 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
0c33b27d 3311 PCI_ANY_ID, PCI_ANY_ID },
87cf8986 3312 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
0c33b27d 3313 PCI_ANY_ID, PCI_ANY_ID },
87cf8986 3314 { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
0c33b27d
CH
3315 PCI_ANY_ID, PCI_ANY_ID },
3316 {0} /* Terminating entry */
3317};
3318MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
3319
3320
3321static struct pci_driver mptsas_driver = {
3322 .name = "mptsas",
3323 .id_table = mptsas_pci_table,
3324 .probe = mptsas_probe,
3325 .remove = __devexit_p(mptsas_remove),
3326 .shutdown = mptscsih_shutdown,
3327#ifdef CONFIG_PM
3328 .suspend = mptscsih_suspend,
3329 .resume = mptscsih_resume,
3330#endif
3331};
3332
3333static int __init
3334mptsas_init(void)
3335{
57ce21bf
PS
3336 int error;
3337
0c33b27d
CH
3338 show_mptmod_ver(my_NAME, my_VERSION);
3339
3340 mptsas_transport_template =
3341 sas_attach_transport(&mptsas_transport_functions);
3342 if (!mptsas_transport_template)
3343 return -ENODEV;
3344
3345 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
df9e062a 3346 mptsasTaskCtx = mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
0c33b27d
CH
3347 mptsasInternalCtx =
3348 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
da4fa655 3349 mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
0c33b27d 3350
d6ecdd63
PS
3351 mpt_event_register(mptsasDoneCtx, mptsas_event_process);
3352 mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
0c33b27d 3353
57ce21bf
PS
3354 error = pci_register_driver(&mptsas_driver);
3355 if (error)
3356 sas_release_transport(mptsas_transport_template);
3357
3358 return error;
0c33b27d
CH
3359}
3360
3361static void __exit
3362mptsas_exit(void)
3363{
3364 pci_unregister_driver(&mptsas_driver);
3365 sas_release_transport(mptsas_transport_template);
3366
3367 mpt_reset_deregister(mptsasDoneCtx);
3368 mpt_event_deregister(mptsasDoneCtx);
3369
da4fa655 3370 mpt_deregister(mptsasMgmtCtx);
0c33b27d
CH
3371 mpt_deregister(mptsasInternalCtx);
3372 mpt_deregister(mptsasTaskCtx);
3373 mpt_deregister(mptsasDoneCtx);
3374}
3375
3376module_init(mptsas_init);
3377module_exit(mptsas_exit);