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