xref: /linux/drivers/message/fusion/mptsas.c (revision 643d1f7fe3aa12c8bdea6fa5b4ba874ff6dd601d)
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 	/* save config data */
1705 	port_info->num_phys = buffer->NumPhys;
1706 	port_info->phy_info = kcalloc(port_info->num_phys,
1707 		sizeof(*port_info->phy_info),GFP_KERNEL);
1708 	if (!port_info->phy_info) {
1709 		error = -ENOMEM;
1710 		goto out_free_consistent;
1711 	}
1712 
1713 	for (i = 0; i < port_info->num_phys; i++) {
1714 		port_info->phy_info[i].portinfo = port_info;
1715 		port_info->phy_info[i].handle =
1716 		    le16_to_cpu(buffer->DevHandle);
1717 	}
1718 
1719  out_free_consistent:
1720 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1721 			    buffer, dma_handle);
1722  out:
1723 	return error;
1724 }
1725 
1726 static int
1727 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
1728 		u32 form, u32 form_specific)
1729 {
1730 	ConfigExtendedPageHeader_t hdr;
1731 	CONFIGPARMS cfg;
1732 	SasExpanderPage1_t *buffer;
1733 	dma_addr_t dma_handle;
1734 	int error=0;
1735 
1736 	if (ioc->sas_discovery_runtime &&
1737 		mptsas_is_end_device(&phy_info->attached))
1738 			goto out;
1739 
1740 	hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
1741 	hdr.ExtPageLength = 0;
1742 	hdr.PageNumber = 1;
1743 	hdr.Reserved1 = 0;
1744 	hdr.Reserved2 = 0;
1745 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1746 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
1747 
1748 	cfg.cfghdr.ehdr = &hdr;
1749 	cfg.physAddr = -1;
1750 	cfg.pageAddr = form + form_specific;
1751 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1752 	cfg.dir = 0;	/* read */
1753 	cfg.timeout = 10;
1754 
1755 	error = mpt_config(ioc, &cfg);
1756 	if (error)
1757 		goto out;
1758 
1759 	if (!hdr.ExtPageLength) {
1760 		error = -ENXIO;
1761 		goto out;
1762 	}
1763 
1764 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1765 				      &dma_handle);
1766 	if (!buffer) {
1767 		error = -ENOMEM;
1768 		goto out;
1769 	}
1770 
1771 	cfg.physAddr = dma_handle;
1772 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1773 
1774 	error = mpt_config(ioc, &cfg);
1775 	if (error)
1776 		goto out_free_consistent;
1777 
1778 
1779 	mptsas_print_expander_pg1(ioc, buffer);
1780 
1781 	/* save config data */
1782 	phy_info->phy_id = buffer->PhyIdentifier;
1783 	phy_info->port_id = buffer->PhysicalPort;
1784 	phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
1785 	phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
1786 	phy_info->hw_link_rate = buffer->HwLinkRate;
1787 	phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
1788 	phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
1789 
1790  out_free_consistent:
1791 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1792 			    buffer, dma_handle);
1793  out:
1794 	return error;
1795 }
1796 
1797 static void
1798 mptsas_parse_device_info(struct sas_identify *identify,
1799 		struct mptsas_devinfo *device_info)
1800 {
1801 	u16 protocols;
1802 
1803 	identify->sas_address = device_info->sas_address;
1804 	identify->phy_identifier = device_info->phy_id;
1805 
1806 	/*
1807 	 * Fill in Phy Initiator Port Protocol.
1808 	 * Bits 6:3, more than one bit can be set, fall through cases.
1809 	 */
1810 	protocols = device_info->device_info & 0x78;
1811 	identify->initiator_port_protocols = 0;
1812 	if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
1813 		identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
1814 	if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1815 		identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
1816 	if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
1817 		identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
1818 	if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
1819 		identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
1820 
1821 	/*
1822 	 * Fill in Phy Target Port Protocol.
1823 	 * Bits 10:7, more than one bit can be set, fall through cases.
1824 	 */
1825 	protocols = device_info->device_info & 0x780;
1826 	identify->target_port_protocols = 0;
1827 	if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
1828 		identify->target_port_protocols |= SAS_PROTOCOL_SSP;
1829 	if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
1830 		identify->target_port_protocols |= SAS_PROTOCOL_STP;
1831 	if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
1832 		identify->target_port_protocols |= SAS_PROTOCOL_SMP;
1833 	if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1834 		identify->target_port_protocols |= SAS_PROTOCOL_SATA;
1835 
1836 	/*
1837 	 * Fill in Attached device type.
1838 	 */
1839 	switch (device_info->device_info &
1840 			MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
1841 	case MPI_SAS_DEVICE_INFO_NO_DEVICE:
1842 		identify->device_type = SAS_PHY_UNUSED;
1843 		break;
1844 	case MPI_SAS_DEVICE_INFO_END_DEVICE:
1845 		identify->device_type = SAS_END_DEVICE;
1846 		break;
1847 	case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
1848 		identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
1849 		break;
1850 	case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
1851 		identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
1852 		break;
1853 	}
1854 }
1855 
1856 static int mptsas_probe_one_phy(struct device *dev,
1857 		struct mptsas_phyinfo *phy_info, int index, int local)
1858 {
1859 	MPT_ADAPTER *ioc;
1860 	struct sas_phy *phy;
1861 	struct sas_port *port;
1862 	int error = 0;
1863 
1864 	if (!dev) {
1865 		error = -ENODEV;
1866 		goto out;
1867 	}
1868 
1869 	if (!phy_info->phy) {
1870 		phy = sas_phy_alloc(dev, index);
1871 		if (!phy) {
1872 			error = -ENOMEM;
1873 			goto out;
1874 		}
1875 	} else
1876 		phy = phy_info->phy;
1877 
1878 	mptsas_parse_device_info(&phy->identify, &phy_info->identify);
1879 
1880 	/*
1881 	 * Set Negotiated link rate.
1882 	 */
1883 	switch (phy_info->negotiated_link_rate) {
1884 	case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
1885 		phy->negotiated_linkrate = SAS_PHY_DISABLED;
1886 		break;
1887 	case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
1888 		phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
1889 		break;
1890 	case MPI_SAS_IOUNIT0_RATE_1_5:
1891 		phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
1892 		break;
1893 	case MPI_SAS_IOUNIT0_RATE_3_0:
1894 		phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
1895 		break;
1896 	case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
1897 	case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
1898 	default:
1899 		phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
1900 		break;
1901 	}
1902 
1903 	/*
1904 	 * Set Max hardware link rate.
1905 	 */
1906 	switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1907 	case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
1908 		phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1909 		break;
1910 	case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1911 		phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1912 		break;
1913 	default:
1914 		break;
1915 	}
1916 
1917 	/*
1918 	 * Set Max programmed link rate.
1919 	 */
1920 	switch (phy_info->programmed_link_rate &
1921 			MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
1922 	case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
1923 		phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1924 		break;
1925 	case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
1926 		phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1927 		break;
1928 	default:
1929 		break;
1930 	}
1931 
1932 	/*
1933 	 * Set Min hardware link rate.
1934 	 */
1935 	switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
1936 	case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
1937 		phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
1938 		break;
1939 	case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1940 		phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
1941 		break;
1942 	default:
1943 		break;
1944 	}
1945 
1946 	/*
1947 	 * Set Min programmed link rate.
1948 	 */
1949 	switch (phy_info->programmed_link_rate &
1950 			MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
1951 	case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
1952 		phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
1953 		break;
1954 	case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
1955 		phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
1956 		break;
1957 	default:
1958 		break;
1959 	}
1960 
1961 	if (!phy_info->phy) {
1962 
1963 		error = sas_phy_add(phy);
1964 		if (error) {
1965 			sas_phy_free(phy);
1966 			goto out;
1967 		}
1968 		phy_info->phy = phy;
1969 	}
1970 
1971 	if (!phy_info->attached.handle ||
1972 			!phy_info->port_details)
1973 		goto out;
1974 
1975 	port = mptsas_get_port(phy_info);
1976 	ioc = phy_to_ioc(phy_info->phy);
1977 
1978 	if (phy_info->sas_port_add_phy) {
1979 
1980 		if (!port) {
1981 			port = sas_port_alloc_num(dev);
1982 			if (!port) {
1983 				error = -ENOMEM;
1984 				goto out;
1985 			}
1986 			error = sas_port_add(port);
1987 			if (error) {
1988 				dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1989 					"%s: exit at line=%d\n", ioc->name,
1990 					__FUNCTION__, __LINE__));
1991 				goto out;
1992 			}
1993 			mptsas_set_port(ioc, phy_info, port);
1994 			dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1995 			    "sas_port_alloc: port=%p dev=%p port_id=%d\n",
1996 			    ioc->name, port, dev, port->port_identifier));
1997 		}
1998 		dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_port_add_phy: phy_id=%d\n",
1999 		    ioc->name, phy_info->phy_id));
2000 		sas_port_add_phy(port, phy_info->phy);
2001 		phy_info->sas_port_add_phy = 0;
2002 	}
2003 
2004 	if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
2005 
2006 		struct sas_rphy *rphy;
2007 		struct device *parent;
2008 		struct sas_identify identify;
2009 
2010 		parent = dev->parent->parent;
2011 		/*
2012 		 * Let the hotplug_work thread handle processing
2013 		 * the adding/removing of devices that occur
2014 		 * after start of day.
2015 		 */
2016 		if (ioc->sas_discovery_runtime &&
2017 			mptsas_is_end_device(&phy_info->attached))
2018 				goto out;
2019 
2020 		mptsas_parse_device_info(&identify, &phy_info->attached);
2021 		if (scsi_is_host_device(parent)) {
2022 			struct mptsas_portinfo *port_info;
2023 			int i;
2024 
2025 			mutex_lock(&ioc->sas_topology_mutex);
2026 			port_info = mptsas_find_portinfo_by_handle(ioc,
2027 								   ioc->handle);
2028 			mutex_unlock(&ioc->sas_topology_mutex);
2029 
2030 			for (i = 0; i < port_info->num_phys; i++)
2031 				if (port_info->phy_info[i].identify.sas_address ==
2032 				    identify.sas_address) {
2033 					sas_port_mark_backlink(port);
2034 					goto out;
2035 				}
2036 
2037 		} else if (scsi_is_sas_rphy(parent)) {
2038 			struct sas_rphy *parent_rphy = dev_to_rphy(parent);
2039 			if (identify.sas_address ==
2040 			    parent_rphy->identify.sas_address) {
2041 				sas_port_mark_backlink(port);
2042 				goto out;
2043 			}
2044 		}
2045 
2046 		switch (identify.device_type) {
2047 		case SAS_END_DEVICE:
2048 			rphy = sas_end_device_alloc(port);
2049 			break;
2050 		case SAS_EDGE_EXPANDER_DEVICE:
2051 		case SAS_FANOUT_EXPANDER_DEVICE:
2052 			rphy = sas_expander_alloc(port, identify.device_type);
2053 			break;
2054 		default:
2055 			rphy = NULL;
2056 			break;
2057 		}
2058 		if (!rphy) {
2059 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2060 				"%s: exit at line=%d\n", ioc->name,
2061 				__FUNCTION__, __LINE__));
2062 			goto out;
2063 		}
2064 
2065 		rphy->identify = identify;
2066 		error = sas_rphy_add(rphy);
2067 		if (error) {
2068 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2069 				"%s: exit at line=%d\n", ioc->name,
2070 				__FUNCTION__, __LINE__));
2071 			sas_rphy_free(rphy);
2072 			goto out;
2073 		}
2074 		mptsas_set_rphy(ioc, phy_info, rphy);
2075 	}
2076 
2077  out:
2078 	return error;
2079 }
2080 
2081 static int
2082 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
2083 {
2084 	struct mptsas_portinfo *port_info, *hba;
2085 	int error = -ENOMEM, i;
2086 
2087 	hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
2088 	if (! hba)
2089 		goto out;
2090 
2091 	error = mptsas_sas_io_unit_pg0(ioc, hba);
2092 	if (error)
2093 		goto out_free_port_info;
2094 
2095 	mptsas_sas_io_unit_pg1(ioc);
2096 	mutex_lock(&ioc->sas_topology_mutex);
2097 	ioc->handle = hba->phy_info[0].handle;
2098 	port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
2099 	if (!port_info) {
2100 		port_info = hba;
2101 		list_add_tail(&port_info->list, &ioc->sas_topology);
2102 	} else {
2103 		for (i = 0; i < hba->num_phys; i++) {
2104 			port_info->phy_info[i].negotiated_link_rate =
2105 				hba->phy_info[i].negotiated_link_rate;
2106 			port_info->phy_info[i].handle =
2107 				hba->phy_info[i].handle;
2108 			port_info->phy_info[i].port_id =
2109 				hba->phy_info[i].port_id;
2110 		}
2111 		kfree(hba->phy_info);
2112 		kfree(hba);
2113 		hba = NULL;
2114 	}
2115 	mutex_unlock(&ioc->sas_topology_mutex);
2116 	for (i = 0; i < port_info->num_phys; i++) {
2117 		mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
2118 			(MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
2119 			 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
2120 
2121 		mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
2122 			(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2123 			 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2124 			 port_info->phy_info[i].handle);
2125 		port_info->phy_info[i].identify.phy_id =
2126 		    port_info->phy_info[i].phy_id = i;
2127 		if (port_info->phy_info[i].attached.handle)
2128 			mptsas_sas_device_pg0(ioc,
2129 				&port_info->phy_info[i].attached,
2130 				(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2131 				 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2132 				port_info->phy_info[i].attached.handle);
2133 	}
2134 
2135 	mptsas_setup_wide_ports(ioc, port_info);
2136 
2137 	for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2138 		mptsas_probe_one_phy(&ioc->sh->shost_gendev,
2139 		    &port_info->phy_info[i], ioc->sas_index, 1);
2140 
2141 	return 0;
2142 
2143  out_free_port_info:
2144 	kfree(hba);
2145  out:
2146 	return error;
2147 }
2148 
2149 static int
2150 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
2151 {
2152 	struct mptsas_portinfo *port_info, *p, *ex;
2153 	struct device *parent;
2154 	struct sas_rphy *rphy;
2155 	int error = -ENOMEM, i, j;
2156 
2157 	ex = kzalloc(sizeof(*port_info), GFP_KERNEL);
2158 	if (!ex)
2159 		goto out;
2160 
2161 	error = mptsas_sas_expander_pg0(ioc, ex,
2162 	    (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
2163 	     MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
2164 	if (error)
2165 		goto out_free_port_info;
2166 
2167 	*handle = ex->phy_info[0].handle;
2168 
2169 	mutex_lock(&ioc->sas_topology_mutex);
2170 	port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
2171 	if (!port_info) {
2172 		port_info = ex;
2173 		list_add_tail(&port_info->list, &ioc->sas_topology);
2174 	} else {
2175 		for (i = 0; i < ex->num_phys; i++) {
2176 			port_info->phy_info[i].handle =
2177 				ex->phy_info[i].handle;
2178 			port_info->phy_info[i].port_id =
2179 				ex->phy_info[i].port_id;
2180 		}
2181 		kfree(ex->phy_info);
2182 		kfree(ex);
2183 		ex = NULL;
2184 	}
2185 	mutex_unlock(&ioc->sas_topology_mutex);
2186 
2187 	for (i = 0; i < port_info->num_phys; i++) {
2188 		mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
2189 			(MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
2190 			 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
2191 
2192 		if (port_info->phy_info[i].identify.handle) {
2193 			mptsas_sas_device_pg0(ioc,
2194 				&port_info->phy_info[i].identify,
2195 				(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2196 				 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2197 				port_info->phy_info[i].identify.handle);
2198 			port_info->phy_info[i].identify.phy_id =
2199 			    port_info->phy_info[i].phy_id;
2200 		}
2201 
2202 		if (port_info->phy_info[i].attached.handle) {
2203 			mptsas_sas_device_pg0(ioc,
2204 				&port_info->phy_info[i].attached,
2205 				(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
2206 				 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2207 				port_info->phy_info[i].attached.handle);
2208 			port_info->phy_info[i].attached.phy_id =
2209 			    port_info->phy_info[i].phy_id;
2210 		}
2211 	}
2212 
2213 	parent = &ioc->sh->shost_gendev;
2214 	for (i = 0; i < port_info->num_phys; i++) {
2215 		mutex_lock(&ioc->sas_topology_mutex);
2216 		list_for_each_entry(p, &ioc->sas_topology, list) {
2217 			for (j = 0; j < p->num_phys; j++) {
2218 				if (port_info->phy_info[i].identify.handle !=
2219 						p->phy_info[j].attached.handle)
2220 					continue;
2221 				rphy = mptsas_get_rphy(&p->phy_info[j]);
2222 				parent = &rphy->dev;
2223 			}
2224 		}
2225 		mutex_unlock(&ioc->sas_topology_mutex);
2226 	}
2227 
2228 	mptsas_setup_wide_ports(ioc, port_info);
2229 
2230 	for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
2231 		mptsas_probe_one_phy(parent, &port_info->phy_info[i],
2232 		    ioc->sas_index, 0);
2233 
2234 	return 0;
2235 
2236  out_free_port_info:
2237 	if (ex) {
2238 		kfree(ex->phy_info);
2239 		kfree(ex);
2240 	}
2241  out:
2242 	return error;
2243 }
2244 
2245 /*
2246  * mptsas_delete_expander_phys
2247  *
2248  *
2249  * This will traverse topology, and remove expanders
2250  * that are no longer present
2251  */
2252 static void
2253 mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
2254 {
2255 	struct mptsas_portinfo buffer;
2256 	struct mptsas_portinfo *port_info, *n, *parent;
2257 	struct mptsas_phyinfo *phy_info;
2258 	struct sas_port * port;
2259 	int i;
2260 	u64	expander_sas_address;
2261 
2262 	mutex_lock(&ioc->sas_topology_mutex);
2263 	list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
2264 
2265 		if (port_info->phy_info &&
2266 		    (!(port_info->phy_info[0].identify.device_info &
2267 		    MPI_SAS_DEVICE_INFO_SMP_TARGET)))
2268 			continue;
2269 
2270 		if (mptsas_sas_expander_pg0(ioc, &buffer,
2271 		     (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
2272 		     MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
2273 		     port_info->phy_info[0].handle)) {
2274 
2275 			/*
2276 			 * Obtain the port_info instance to the parent port
2277 			 */
2278 			parent = mptsas_find_portinfo_by_handle(ioc,
2279 			    port_info->phy_info[0].identify.handle_parent);
2280 
2281 			if (!parent)
2282 				goto next_port;
2283 
2284 			expander_sas_address =
2285 				port_info->phy_info[0].identify.sas_address;
2286 
2287 			/*
2288 			 * Delete rphys in the parent that point
2289 			 * to this expander.  The transport layer will
2290 			 * cleanup all the children.
2291 			 */
2292 			phy_info = parent->phy_info;
2293 			for (i = 0; i < parent->num_phys; i++, phy_info++) {
2294 				port = mptsas_get_port(phy_info);
2295 				if (!port)
2296 					continue;
2297 				if (phy_info->attached.sas_address !=
2298 					expander_sas_address)
2299 					continue;
2300 				dsaswideprintk(ioc,
2301 				    dev_printk(KERN_DEBUG, &port->dev,
2302 				    MYIOC_s_FMT "delete port (%d)\n", ioc->name,
2303 				    port->port_identifier));
2304 				sas_port_delete(port);
2305 				mptsas_port_delete(ioc, phy_info->port_details);
2306 			}
2307  next_port:
2308 
2309 			phy_info = port_info->phy_info;
2310 			for (i = 0; i < port_info->num_phys; i++, phy_info++)
2311 				mptsas_port_delete(ioc, phy_info->port_details);
2312 
2313 			list_del(&port_info->list);
2314 			kfree(port_info->phy_info);
2315 			kfree(port_info);
2316 		}
2317 		/*
2318 		* Free this memory allocated from inside
2319 		* mptsas_sas_expander_pg0
2320 		*/
2321 		kfree(buffer.phy_info);
2322 	}
2323 	mutex_unlock(&ioc->sas_topology_mutex);
2324 }
2325 
2326 /*
2327  * Start of day discovery
2328  */
2329 static void
2330 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
2331 {
2332 	u32 handle = 0xFFFF;
2333 	int i;
2334 
2335 	mutex_lock(&ioc->sas_discovery_mutex);
2336 	mptsas_probe_hba_phys(ioc);
2337 	while (!mptsas_probe_expander_phys(ioc, &handle))
2338 		;
2339 	/*
2340 	  Reporting RAID volumes.
2341 	*/
2342 	if (!ioc->ir_firmware)
2343 		goto out;
2344 	if (!ioc->raid_data.pIocPg2)
2345 		goto out;
2346 	if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
2347 		goto out;
2348 	for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
2349 		scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
2350 		    ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
2351 	}
2352  out:
2353 	mutex_unlock(&ioc->sas_discovery_mutex);
2354 }
2355 
2356 /*
2357  * Work queue thread to handle Runtime discovery
2358  * Mere purpose is the hot add/delete of expanders
2359  *(Mutex UNLOCKED)
2360  */
2361 static void
2362 __mptsas_discovery_work(MPT_ADAPTER *ioc)
2363 {
2364 	u32 handle = 0xFFFF;
2365 
2366 	ioc->sas_discovery_runtime=1;
2367 	mptsas_delete_expander_phys(ioc);
2368 	mptsas_probe_hba_phys(ioc);
2369 	while (!mptsas_probe_expander_phys(ioc, &handle))
2370 		;
2371 	ioc->sas_discovery_runtime=0;
2372 }
2373 
2374 /*
2375  * Work queue thread to handle Runtime discovery
2376  * Mere purpose is the hot add/delete of expanders
2377  *(Mutex LOCKED)
2378  */
2379 static void
2380 mptsas_discovery_work(struct work_struct *work)
2381 {
2382 	struct mptsas_discovery_event *ev =
2383 		container_of(work, struct mptsas_discovery_event, work);
2384 	MPT_ADAPTER *ioc = ev->ioc;
2385 
2386 	mutex_lock(&ioc->sas_discovery_mutex);
2387 	__mptsas_discovery_work(ioc);
2388 	mutex_unlock(&ioc->sas_discovery_mutex);
2389 	kfree(ev);
2390 }
2391 
2392 static struct mptsas_phyinfo *
2393 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
2394 {
2395 	struct mptsas_portinfo *port_info;
2396 	struct mptsas_phyinfo *phy_info = NULL;
2397 	int i;
2398 
2399 	mutex_lock(&ioc->sas_topology_mutex);
2400 	list_for_each_entry(port_info, &ioc->sas_topology, list) {
2401 		for (i = 0; i < port_info->num_phys; i++) {
2402 			if (!mptsas_is_end_device(
2403 				&port_info->phy_info[i].attached))
2404 				continue;
2405 			if (port_info->phy_info[i].attached.sas_address
2406 			    != sas_address)
2407 				continue;
2408 			phy_info = &port_info->phy_info[i];
2409 			break;
2410 		}
2411 	}
2412 	mutex_unlock(&ioc->sas_topology_mutex);
2413 	return phy_info;
2414 }
2415 
2416 static struct mptsas_phyinfo *
2417 mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u8 channel, u8 id)
2418 {
2419 	struct mptsas_portinfo *port_info;
2420 	struct mptsas_phyinfo *phy_info = NULL;
2421 	int i;
2422 
2423 	mutex_lock(&ioc->sas_topology_mutex);
2424 	list_for_each_entry(port_info, &ioc->sas_topology, list) {
2425 		for (i = 0; i < port_info->num_phys; i++) {
2426 			if (!mptsas_is_end_device(
2427 				&port_info->phy_info[i].attached))
2428 				continue;
2429 			if (port_info->phy_info[i].attached.id != id)
2430 				continue;
2431 			if (port_info->phy_info[i].attached.channel != channel)
2432 				continue;
2433 			phy_info = &port_info->phy_info[i];
2434 			break;
2435 		}
2436 	}
2437 	mutex_unlock(&ioc->sas_topology_mutex);
2438 	return phy_info;
2439 }
2440 
2441 static struct mptsas_phyinfo *
2442 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2443 {
2444 	struct mptsas_portinfo *port_info;
2445 	struct mptsas_phyinfo *phy_info = NULL;
2446 	int i;
2447 
2448 	mutex_lock(&ioc->sas_topology_mutex);
2449 	list_for_each_entry(port_info, &ioc->sas_topology, list) {
2450 		for (i = 0; i < port_info->num_phys; i++) {
2451 			if (!mptsas_is_end_device(
2452 				&port_info->phy_info[i].attached))
2453 				continue;
2454 			if (port_info->phy_info[i].attached.phys_disk_num == ~0)
2455 				continue;
2456 			if (port_info->phy_info[i].attached.phys_disk_num != id)
2457 				continue;
2458 			if (port_info->phy_info[i].attached.channel != channel)
2459 				continue;
2460 			phy_info = &port_info->phy_info[i];
2461 			break;
2462 		}
2463 	}
2464 	mutex_unlock(&ioc->sas_topology_mutex);
2465 	return phy_info;
2466 }
2467 
2468 /*
2469  * Work queue thread to clear the persitency table
2470  */
2471 static void
2472 mptsas_persist_clear_table(struct work_struct *work)
2473 {
2474 	MPT_ADAPTER *ioc = container_of(work, MPT_ADAPTER, sas_persist_task);
2475 
2476 	mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
2477 }
2478 
2479 static void
2480 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
2481 {
2482 	int rc;
2483 
2484 	sdev->no_uld_attach = data ? 1 : 0;
2485 	rc = scsi_device_reprobe(sdev);
2486 }
2487 
2488 static void
2489 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
2490 {
2491 	starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
2492 			mptsas_reprobe_lun);
2493 }
2494 
2495 static void
2496 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
2497 {
2498 	CONFIGPARMS			cfg;
2499 	ConfigPageHeader_t		hdr;
2500 	dma_addr_t			dma_handle;
2501 	pRaidVolumePage0_t		buffer = NULL;
2502 	RaidPhysDiskPage0_t 		phys_disk;
2503 	int				i;
2504 	struct mptsas_hotplug_event 	*ev;
2505 
2506 	memset(&cfg, 0 , sizeof(CONFIGPARMS));
2507 	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
2508 	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
2509 	cfg.pageAddr = (channel << 8) + id;
2510 	cfg.cfghdr.hdr = &hdr;
2511 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2512 
2513 	if (mpt_config(ioc, &cfg) != 0)
2514 		goto out;
2515 
2516 	if (!hdr.PageLength)
2517 		goto out;
2518 
2519 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
2520 	    &dma_handle);
2521 
2522 	if (!buffer)
2523 		goto out;
2524 
2525 	cfg.physAddr = dma_handle;
2526 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2527 
2528 	if (mpt_config(ioc, &cfg) != 0)
2529 		goto out;
2530 
2531 	if (!(buffer->VolumeStatus.Flags &
2532 	    MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
2533 		goto out;
2534 
2535 	if (!buffer->NumPhysDisks)
2536 		goto out;
2537 
2538 	for (i = 0; i < buffer->NumPhysDisks; i++) {
2539 
2540 		if (mpt_raid_phys_disk_pg0(ioc,
2541 		    buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
2542 			continue;
2543 
2544 		ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2545 		if (!ev) {
2546 			printk(MYIOC_s_WARN_FMT "mptsas: lost hotplug event\n", ioc->name);
2547 			goto out;
2548 		}
2549 
2550 		INIT_WORK(&ev->work, mptsas_hotplug_work);
2551 		ev->ioc = ioc;
2552 		ev->id = phys_disk.PhysDiskID;
2553 		ev->channel = phys_disk.PhysDiskBus;
2554 		ev->phys_disk_num_valid = 1;
2555 		ev->phys_disk_num = phys_disk.PhysDiskNum;
2556 		ev->event_type = MPTSAS_ADD_DEVICE;
2557 		schedule_work(&ev->work);
2558 	}
2559 
2560  out:
2561 	if (buffer)
2562 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
2563 		    dma_handle);
2564 }
2565 /*
2566  * Work queue thread to handle SAS hotplug events
2567  */
2568 static void
2569 mptsas_hotplug_work(struct work_struct *work)
2570 {
2571 	struct mptsas_hotplug_event *ev =
2572 		container_of(work, struct mptsas_hotplug_event, work);
2573 
2574 	MPT_ADAPTER *ioc = ev->ioc;
2575 	struct mptsas_phyinfo *phy_info;
2576 	struct sas_rphy *rphy;
2577 	struct sas_port *port;
2578 	struct scsi_device *sdev;
2579 	struct scsi_target * starget;
2580 	struct sas_identify identify;
2581 	char *ds = NULL;
2582 	struct mptsas_devinfo sas_device;
2583 	VirtTarget *vtarget;
2584 	VirtDevice *vdevice;
2585 
2586 	mutex_lock(&ioc->sas_discovery_mutex);
2587 	switch (ev->event_type) {
2588 	case MPTSAS_DEL_DEVICE:
2589 
2590 		phy_info = NULL;
2591 		if (ev->phys_disk_num_valid) {
2592 			if (ev->hidden_raid_component){
2593 				if (mptsas_sas_device_pg0(ioc, &sas_device,
2594 				    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2595 				     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2596 				    (ev->channel << 8) + ev->id)) {
2597 					dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2598 					"%s: exit at line=%d\n", ioc->name,
2599 						__FUNCTION__, __LINE__));
2600 					break;
2601 				}
2602 				phy_info = mptsas_find_phyinfo_by_sas_address(
2603 				    ioc, sas_device.sas_address);
2604 			}else
2605 				phy_info = mptsas_find_phyinfo_by_phys_disk_num(
2606 				    ioc, ev->channel, ev->phys_disk_num);
2607 		}
2608 
2609 		if (!phy_info)
2610 			phy_info = mptsas_find_phyinfo_by_target(ioc,
2611 			    ev->channel, ev->id);
2612 
2613 		/*
2614 		 * Sanity checks, for non-existing phys and remote rphys.
2615 		 */
2616 		if (!phy_info){
2617 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2618 				"%s: exit at line=%d\n", ioc->name,
2619 				__FUNCTION__, __LINE__));
2620 			break;
2621 		}
2622 		if (!phy_info->port_details) {
2623 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2624 				"%s: exit at line=%d\n", ioc->name,
2625 			       	__FUNCTION__, __LINE__));
2626 			break;
2627 		}
2628 		rphy = mptsas_get_rphy(phy_info);
2629 		if (!rphy) {
2630 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2631 				"%s: exit at line=%d\n", ioc->name,
2632 			       	__FUNCTION__, __LINE__));
2633 			break;
2634 		}
2635 
2636 		port = mptsas_get_port(phy_info);
2637 		if (!port) {
2638 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2639 				"%s: exit at line=%d\n", ioc->name,
2640 			       	__FUNCTION__, __LINE__));
2641 			break;
2642 		}
2643 
2644 		starget = mptsas_get_starget(phy_info);
2645 		if (starget) {
2646 			vtarget = starget->hostdata;
2647 
2648 			if (!vtarget) {
2649 				dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2650 					"%s: exit at line=%d\n", ioc->name,
2651 					__FUNCTION__, __LINE__));
2652 				break;
2653 			}
2654 
2655 			/*
2656 			 * Handling  RAID components
2657 			 */
2658 			if (ev->phys_disk_num_valid &&
2659 			    ev->hidden_raid_component) {
2660 				printk(MYIOC_s_INFO_FMT
2661 				    "RAID Hidding: channel=%d, id=%d, "
2662 				    "physdsk %d \n", ioc->name, ev->channel,
2663 				    ev->id, ev->phys_disk_num);
2664 				vtarget->id = ev->phys_disk_num;
2665 				vtarget->tflags |=
2666 				    MPT_TARGET_FLAGS_RAID_COMPONENT;
2667 				mptsas_reprobe_target(starget, 1);
2668 				phy_info->attached.phys_disk_num =
2669 				    ev->phys_disk_num;
2670 			break;
2671 			}
2672 		}
2673 
2674 		if (phy_info->attached.device_info &
2675 		    MPI_SAS_DEVICE_INFO_SSP_TARGET)
2676 			ds = "ssp";
2677 		if (phy_info->attached.device_info &
2678 		    MPI_SAS_DEVICE_INFO_STP_TARGET)
2679 			ds = "stp";
2680 		if (phy_info->attached.device_info &
2681 		    MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2682 			ds = "sata";
2683 
2684 		printk(MYIOC_s_INFO_FMT
2685 		       "removing %s device, channel %d, id %d, phy %d\n",
2686 		       ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
2687 		dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
2688 		    "delete port (%d)\n", ioc->name, port->port_identifier);
2689 		sas_port_delete(port);
2690 		mptsas_port_delete(ioc, phy_info->port_details);
2691 		break;
2692 	case MPTSAS_ADD_DEVICE:
2693 
2694 		if (ev->phys_disk_num_valid)
2695 			mpt_findImVolumes(ioc);
2696 
2697 		/*
2698 		 * Refresh sas device pg0 data
2699 		 */
2700 		if (mptsas_sas_device_pg0(ioc, &sas_device,
2701 		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2702 		     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2703 			(ev->channel << 8) + ev->id)) {
2704 				dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2705 					"%s: exit at line=%d\n", ioc->name,
2706 					__FUNCTION__, __LINE__));
2707 			break;
2708 		}
2709 
2710 		__mptsas_discovery_work(ioc);
2711 
2712 		phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
2713 				sas_device.sas_address);
2714 
2715 		if (!phy_info || !phy_info->port_details) {
2716 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2717 				"%s: exit at line=%d\n", ioc->name,
2718 			       	__FUNCTION__, __LINE__));
2719 			break;
2720 		}
2721 
2722 		starget = mptsas_get_starget(phy_info);
2723 		if (starget && (!ev->hidden_raid_component)){
2724 
2725 			vtarget = starget->hostdata;
2726 
2727 			if (!vtarget) {
2728 				dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2729 				    "%s: exit at line=%d\n", ioc->name,
2730 				    __FUNCTION__, __LINE__));
2731 				break;
2732 			}
2733 			/*
2734 			 * Handling  RAID components
2735 			 */
2736 			if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
2737 				printk(MYIOC_s_INFO_FMT
2738 				    "RAID Exposing: channel=%d, id=%d, "
2739 				    "physdsk %d \n", ioc->name, ev->channel,
2740 				    ev->id, ev->phys_disk_num);
2741 				vtarget->tflags &=
2742 				    ~MPT_TARGET_FLAGS_RAID_COMPONENT;
2743 				vtarget->id = ev->id;
2744 				mptsas_reprobe_target(starget, 0);
2745 				phy_info->attached.phys_disk_num = ~0;
2746 			}
2747 			break;
2748 		}
2749 
2750 		if (mptsas_get_rphy(phy_info)) {
2751 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2752 				"%s: exit at line=%d\n", ioc->name,
2753 			       	__FUNCTION__, __LINE__));
2754 			if (ev->channel) printk("%d\n", __LINE__);
2755 			break;
2756 		}
2757 
2758 		port = mptsas_get_port(phy_info);
2759 		if (!port) {
2760 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2761 				"%s: exit at line=%d\n", ioc->name,
2762 			       	__FUNCTION__, __LINE__));
2763 			break;
2764 		}
2765 		memcpy(&phy_info->attached, &sas_device,
2766 		    sizeof(struct mptsas_devinfo));
2767 
2768 		if (phy_info->attached.device_info &
2769 		    MPI_SAS_DEVICE_INFO_SSP_TARGET)
2770 			ds = "ssp";
2771 		if (phy_info->attached.device_info &
2772 		    MPI_SAS_DEVICE_INFO_STP_TARGET)
2773 			ds = "stp";
2774 		if (phy_info->attached.device_info &
2775 		    MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2776 			ds = "sata";
2777 
2778 		printk(MYIOC_s_INFO_FMT
2779 		       "attaching %s device, channel %d, id %d, phy %d\n",
2780 		       ioc->name, ds, ev->channel, ev->id, ev->phy_id);
2781 
2782 		mptsas_parse_device_info(&identify, &phy_info->attached);
2783 		rphy = sas_end_device_alloc(port);
2784 		if (!rphy) {
2785 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2786 				"%s: exit at line=%d\n", ioc->name,
2787 			       	__FUNCTION__, __LINE__));
2788 			break; /* non-fatal: an rphy can be added later */
2789 		}
2790 
2791 		rphy->identify = identify;
2792 		if (sas_rphy_add(rphy)) {
2793 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
2794 				"%s: exit at line=%d\n", ioc->name,
2795 			       	__FUNCTION__, __LINE__));
2796 			sas_rphy_free(rphy);
2797 			break;
2798 		}
2799 		mptsas_set_rphy(ioc, phy_info, rphy);
2800 		break;
2801 	case MPTSAS_ADD_RAID:
2802 		sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2803 		    ev->id, 0);
2804 		if (sdev) {
2805 			scsi_device_put(sdev);
2806 			break;
2807 		}
2808 		printk(MYIOC_s_INFO_FMT
2809 		       "attaching raid volume, channel %d, id %d\n",
2810 		       ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2811 		scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL, ev->id, 0);
2812 		mpt_findImVolumes(ioc);
2813 		break;
2814 	case MPTSAS_DEL_RAID:
2815 		sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2816 		    ev->id, 0);
2817 		if (!sdev)
2818 			break;
2819 		printk(MYIOC_s_INFO_FMT
2820 		       "removing raid volume, channel %d, id %d\n",
2821 		       ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2822 		vdevice = sdev->hostdata;
2823 		scsi_remove_device(sdev);
2824 		scsi_device_put(sdev);
2825 		mpt_findImVolumes(ioc);
2826 		break;
2827 	case MPTSAS_ADD_INACTIVE_VOLUME:
2828 		mptsas_adding_inactive_raid_components(ioc,
2829 		    ev->channel, ev->id);
2830 		break;
2831 	case MPTSAS_IGNORE_EVENT:
2832 	default:
2833 		break;
2834 	}
2835 
2836 	mutex_unlock(&ioc->sas_discovery_mutex);
2837 	kfree(ev);
2838 }
2839 
2840 static void
2841 mptsas_send_sas_event(MPT_ADAPTER *ioc,
2842 		EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
2843 {
2844 	struct mptsas_hotplug_event *ev;
2845 	u32 device_info = le32_to_cpu(sas_event_data->DeviceInfo);
2846 	__le64 sas_address;
2847 
2848 	if ((device_info &
2849 	     (MPI_SAS_DEVICE_INFO_SSP_TARGET |
2850 	      MPI_SAS_DEVICE_INFO_STP_TARGET |
2851 	      MPI_SAS_DEVICE_INFO_SATA_DEVICE )) == 0)
2852 		return;
2853 
2854 	switch (sas_event_data->ReasonCode) {
2855 	case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
2856 
2857 		mptsas_target_reset_queue(ioc, sas_event_data);
2858 		break;
2859 
2860 	case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
2861 		ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2862 		if (!ev) {
2863 			printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name);
2864 			break;
2865 		}
2866 
2867 		INIT_WORK(&ev->work, mptsas_hotplug_work);
2868 		ev->ioc = ioc;
2869 		ev->handle = le16_to_cpu(sas_event_data->DevHandle);
2870 		ev->parent_handle =
2871 		    le16_to_cpu(sas_event_data->ParentDevHandle);
2872 		ev->channel = sas_event_data->Bus;
2873 		ev->id = sas_event_data->TargetID;
2874 		ev->phy_id = sas_event_data->PhyNum;
2875 		memcpy(&sas_address, &sas_event_data->SASAddress,
2876 		    sizeof(__le64));
2877 		ev->sas_address = le64_to_cpu(sas_address);
2878 		ev->device_info = device_info;
2879 
2880 		if (sas_event_data->ReasonCode &
2881 		    MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
2882 			ev->event_type = MPTSAS_ADD_DEVICE;
2883 		else
2884 			ev->event_type = MPTSAS_DEL_DEVICE;
2885 		schedule_work(&ev->work);
2886 		break;
2887 	case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
2888 	/*
2889 	 * Persistent table is full.
2890 	 */
2891 		INIT_WORK(&ioc->sas_persist_task,
2892 		    mptsas_persist_clear_table);
2893 		schedule_work(&ioc->sas_persist_task);
2894 		break;
2895 	/*
2896 	 * TODO, handle other events
2897 	 */
2898 	case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
2899 	case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
2900 	case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
2901 	case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
2902 	case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
2903 	case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
2904 	case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
2905 	default:
2906 		break;
2907 	}
2908 }
2909 static void
2910 mptsas_send_raid_event(MPT_ADAPTER *ioc,
2911 		EVENT_DATA_RAID *raid_event_data)
2912 {
2913 	struct mptsas_hotplug_event *ev;
2914 	int status = le32_to_cpu(raid_event_data->SettingsStatus);
2915 	int state = (status >> 8) & 0xff;
2916 
2917 	if (ioc->bus_type != SAS)
2918 		return;
2919 
2920 	ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2921 	if (!ev) {
2922 		printk(MYIOC_s_WARN_FMT "lost hotplug event\n", ioc->name);
2923 		return;
2924 	}
2925 
2926 	INIT_WORK(&ev->work, mptsas_hotplug_work);
2927 	ev->ioc = ioc;
2928 	ev->id = raid_event_data->VolumeID;
2929 	ev->channel = raid_event_data->VolumeBus;
2930 	ev->event_type = MPTSAS_IGNORE_EVENT;
2931 
2932 	switch (raid_event_data->ReasonCode) {
2933 	case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
2934 		ev->phys_disk_num_valid = 1;
2935 		ev->phys_disk_num = raid_event_data->PhysDiskNum;
2936 		ev->event_type = MPTSAS_ADD_DEVICE;
2937 		break;
2938 	case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
2939 		ev->phys_disk_num_valid = 1;
2940 		ev->phys_disk_num = raid_event_data->PhysDiskNum;
2941 		ev->hidden_raid_component = 1;
2942 		ev->event_type = MPTSAS_DEL_DEVICE;
2943 		break;
2944 	case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
2945 		switch (state) {
2946 		case MPI_PD_STATE_ONLINE:
2947 		case MPI_PD_STATE_NOT_COMPATIBLE:
2948 			ev->phys_disk_num_valid = 1;
2949 			ev->phys_disk_num = raid_event_data->PhysDiskNum;
2950 			ev->hidden_raid_component = 1;
2951 			ev->event_type = MPTSAS_ADD_DEVICE;
2952 			break;
2953 		case MPI_PD_STATE_MISSING:
2954 		case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
2955 		case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
2956 		case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
2957 			ev->phys_disk_num_valid = 1;
2958 			ev->phys_disk_num = raid_event_data->PhysDiskNum;
2959 			ev->event_type = MPTSAS_DEL_DEVICE;
2960 			break;
2961 		default:
2962 			break;
2963 		}
2964 		break;
2965 	case MPI_EVENT_RAID_RC_VOLUME_DELETED:
2966 		ev->event_type = MPTSAS_DEL_RAID;
2967 		break;
2968 	case MPI_EVENT_RAID_RC_VOLUME_CREATED:
2969 		ev->event_type = MPTSAS_ADD_RAID;
2970 		break;
2971 	case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
2972 		switch (state) {
2973 		case MPI_RAIDVOL0_STATUS_STATE_FAILED:
2974 		case MPI_RAIDVOL0_STATUS_STATE_MISSING:
2975 			ev->event_type = MPTSAS_DEL_RAID;
2976 			break;
2977 		case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
2978 		case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
2979 			ev->event_type = MPTSAS_ADD_RAID;
2980 			break;
2981 		default:
2982 			break;
2983 		}
2984 		break;
2985 	default:
2986 		break;
2987 	}
2988 	schedule_work(&ev->work);
2989 }
2990 
2991 static void
2992 mptsas_send_discovery_event(MPT_ADAPTER *ioc,
2993 	EVENT_DATA_SAS_DISCOVERY *discovery_data)
2994 {
2995 	struct mptsas_discovery_event *ev;
2996 
2997 	/*
2998 	 * DiscoveryStatus
2999 	 *
3000 	 * This flag will be non-zero when firmware
3001 	 * kicks off discovery, and return to zero
3002 	 * once its completed.
3003 	 */
3004 	if (discovery_data->DiscoveryStatus)
3005 		return;
3006 
3007 	ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
3008 	if (!ev)
3009 		return;
3010 	INIT_WORK(&ev->work, mptsas_discovery_work);
3011 	ev->ioc = ioc;
3012 	schedule_work(&ev->work);
3013 };
3014 
3015 /*
3016  * mptsas_send_ir2_event - handle exposing hidden disk when
3017  * an inactive raid volume is added
3018  *
3019  * @ioc: Pointer to MPT_ADAPTER structure
3020  * @ir2_data
3021  *
3022  */
3023 static void
3024 mptsas_send_ir2_event(MPT_ADAPTER *ioc, PTR_MPI_EVENT_DATA_IR2 ir2_data)
3025 {
3026 	struct mptsas_hotplug_event *ev;
3027 
3028 	if (ir2_data->ReasonCode !=
3029 	    MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED)
3030 		return;
3031 
3032 	ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
3033 	if (!ev)
3034 		return;
3035 
3036 	INIT_WORK(&ev->work, mptsas_hotplug_work);
3037 	ev->ioc = ioc;
3038 	ev->id = ir2_data->TargetID;
3039 	ev->channel = ir2_data->Bus;
3040 	ev->event_type = MPTSAS_ADD_INACTIVE_VOLUME;
3041 
3042 	schedule_work(&ev->work);
3043 };
3044 
3045 static int
3046 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
3047 {
3048 	int rc=1;
3049 	u8 event = le32_to_cpu(reply->Event) & 0xFF;
3050 
3051 	if (!ioc->sh)
3052 		goto out;
3053 
3054 	/*
3055 	 * sas_discovery_ignore_events
3056 	 *
3057 	 * This flag is to prevent anymore processing of
3058 	 * sas events once mptsas_remove function is called.
3059 	 */
3060 	if (ioc->sas_discovery_ignore_events) {
3061 		rc = mptscsih_event_process(ioc, reply);
3062 		goto out;
3063 	}
3064 
3065 	switch (event) {
3066 	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
3067 		mptsas_send_sas_event(ioc,
3068 			(EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data);
3069 		break;
3070 	case MPI_EVENT_INTEGRATED_RAID:
3071 		mptsas_send_raid_event(ioc,
3072 			(EVENT_DATA_RAID *)reply->Data);
3073 		break;
3074 	case MPI_EVENT_PERSISTENT_TABLE_FULL:
3075 		INIT_WORK(&ioc->sas_persist_task,
3076 		    mptsas_persist_clear_table);
3077 		schedule_work(&ioc->sas_persist_task);
3078 		break;
3079 	 case MPI_EVENT_SAS_DISCOVERY:
3080 		mptsas_send_discovery_event(ioc,
3081 			(EVENT_DATA_SAS_DISCOVERY *)reply->Data);
3082 		break;
3083 	case MPI_EVENT_IR2:
3084 		mptsas_send_ir2_event(ioc,
3085 		    (PTR_MPI_EVENT_DATA_IR2)reply->Data);
3086 		break;
3087 	default:
3088 		rc = mptscsih_event_process(ioc, reply);
3089 		break;
3090 	}
3091  out:
3092 
3093 	return rc;
3094 }
3095 
3096 static int
3097 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3098 {
3099 	struct Scsi_Host	*sh;
3100 	MPT_SCSI_HOST		*hd;
3101 	MPT_ADAPTER 		*ioc;
3102 	unsigned long		 flags;
3103 	int			 ii;
3104 	int			 numSGE = 0;
3105 	int			 scale;
3106 	int			 ioc_cap;
3107 	int			error=0;
3108 	int			r;
3109 
3110 	r = mpt_attach(pdev,id);
3111 	if (r)
3112 		return r;
3113 
3114 	ioc = pci_get_drvdata(pdev);
3115 	ioc->DoneCtx = mptsasDoneCtx;
3116 	ioc->TaskCtx = mptsasTaskCtx;
3117 	ioc->InternalCtx = mptsasInternalCtx;
3118 
3119 	/*  Added sanity check on readiness of the MPT adapter.
3120 	 */
3121 	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
3122 		printk(MYIOC_s_WARN_FMT
3123 		  "Skipping because it's not operational!\n",
3124 		  ioc->name);
3125 		error = -ENODEV;
3126 		goto out_mptsas_probe;
3127 	}
3128 
3129 	if (!ioc->active) {
3130 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
3131 		  ioc->name);
3132 		error = -ENODEV;
3133 		goto out_mptsas_probe;
3134 	}
3135 
3136 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
3137 	 */
3138 	ioc_cap = 0;
3139 	for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
3140 		if (ioc->pfacts[ii].ProtocolFlags &
3141 				MPI_PORTFACTS_PROTOCOL_INITIATOR)
3142 			ioc_cap++;
3143 	}
3144 
3145 	if (!ioc_cap) {
3146 		printk(MYIOC_s_WARN_FMT
3147 			"Skipping ioc=%p because SCSI Initiator mode "
3148 			"is NOT enabled!\n", ioc->name, ioc);
3149 		return 0;
3150 	}
3151 
3152 	sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
3153 	if (!sh) {
3154 		printk(MYIOC_s_WARN_FMT
3155 			"Unable to register controller with SCSI subsystem\n",
3156 			ioc->name);
3157 		error = -1;
3158 		goto out_mptsas_probe;
3159         }
3160 
3161 	spin_lock_irqsave(&ioc->FreeQlock, flags);
3162 
3163 	/* Attach the SCSI Host to the IOC structure
3164 	 */
3165 	ioc->sh = sh;
3166 
3167 	sh->io_port = 0;
3168 	sh->n_io_port = 0;
3169 	sh->irq = 0;
3170 
3171 	/* set 16 byte cdb's */
3172 	sh->max_cmd_len = 16;
3173 
3174 	sh->max_id = ioc->pfacts[0].PortSCSIID;
3175 	sh->max_lun = max_lun;
3176 
3177 	sh->transportt = mptsas_transport_template;
3178 
3179 	sh->this_id = ioc->pfacts[0].PortSCSIID;
3180 
3181 	/* Required entry.
3182 	 */
3183 	sh->unique_id = ioc->id;
3184 
3185 	INIT_LIST_HEAD(&ioc->sas_topology);
3186 	mutex_init(&ioc->sas_topology_mutex);
3187 	mutex_init(&ioc->sas_discovery_mutex);
3188 	mutex_init(&ioc->sas_mgmt.mutex);
3189 	init_completion(&ioc->sas_mgmt.done);
3190 
3191 	/* Verify that we won't exceed the maximum
3192 	 * number of chain buffers
3193 	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
3194 	 * For 32bit SGE's:
3195 	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
3196 	 *               + (req_sz - 64)/sizeof(SGE)
3197 	 * A slightly different algorithm is required for
3198 	 * 64bit SGEs.
3199 	 */
3200 	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3201 	if (sizeof(dma_addr_t) == sizeof(u64)) {
3202 		numSGE = (scale - 1) *
3203 		  (ioc->facts.MaxChainDepth-1) + scale +
3204 		  (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
3205 		  sizeof(u32));
3206 	} else {
3207 		numSGE = 1 + (scale - 1) *
3208 		  (ioc->facts.MaxChainDepth-1) + scale +
3209 		  (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
3210 		  sizeof(u32));
3211 	}
3212 
3213 	if (numSGE < sh->sg_tablesize) {
3214 		/* Reset this value */
3215 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3216 		  "Resetting sg_tablesize to %d from %d\n",
3217 		  ioc->name, numSGE, sh->sg_tablesize));
3218 		sh->sg_tablesize = numSGE;
3219 	}
3220 
3221 	hd = shost_priv(sh);
3222 	hd->ioc = ioc;
3223 
3224 	/* SCSI needs scsi_cmnd lookup table!
3225 	 * (with size equal to req_depth*PtrSz!)
3226 	 */
3227 	ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
3228 	if (!ioc->ScsiLookup) {
3229 		error = -ENOMEM;
3230 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3231 		goto out_mptsas_probe;
3232 	}
3233 	spin_lock_init(&ioc->scsi_lookup_lock);
3234 
3235 	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
3236 		 ioc->name, ioc->ScsiLookup));
3237 
3238 	/* Clear the TM flags
3239 	 */
3240 	hd->tmPending = 0;
3241 	hd->tmState = TM_STATE_NONE;
3242 	hd->resetPending = 0;
3243 	hd->abortSCpnt = NULL;
3244 
3245 	/* Clear the pointer used to store
3246 	 * single-threaded commands, i.e., those
3247 	 * issued during a bus scan, dv and
3248 	 * configuration pages.
3249 	 */
3250 	hd->cmdPtr = NULL;
3251 
3252 	/* Initialize this SCSI Hosts' timers
3253 	 * To use, set the timer expires field
3254 	 * and add_timer
3255 	 */
3256 	init_timer(&hd->timer);
3257 	hd->timer.data = (unsigned long) hd;
3258 	hd->timer.function = mptscsih_timer_expired;
3259 
3260 	ioc->sas_data.ptClear = mpt_pt_clear;
3261 
3262 	init_waitqueue_head(&hd->scandv_waitq);
3263 	hd->scandv_wait_done = 0;
3264 	hd->last_queue_full = 0;
3265 	INIT_LIST_HEAD(&hd->target_reset_list);
3266 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3267 
3268 	if (ioc->sas_data.ptClear==1) {
3269 		mptbase_sas_persist_operation(
3270 		    ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
3271 	}
3272 
3273 	error = scsi_add_host(sh, &ioc->pcidev->dev);
3274 	if (error) {
3275 		dprintk(ioc, printk(MYIOC_s_ERR_FMT
3276 		  "scsi_add_host failed\n", ioc->name));
3277 		goto out_mptsas_probe;
3278 	}
3279 
3280 	mptsas_scan_sas_topology(ioc);
3281 
3282 	return 0;
3283 
3284  out_mptsas_probe:
3285 
3286 	mptscsih_remove(pdev);
3287 	return error;
3288 }
3289 
3290 static void __devexit mptsas_remove(struct pci_dev *pdev)
3291 {
3292 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
3293 	struct mptsas_portinfo *p, *n;
3294 	int i;
3295 
3296 	ioc->sas_discovery_ignore_events = 1;
3297 	sas_remove_host(ioc->sh);
3298 
3299 	mutex_lock(&ioc->sas_topology_mutex);
3300 	list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
3301 		list_del(&p->list);
3302 		for (i = 0 ; i < p->num_phys ; i++)
3303 			mptsas_port_delete(ioc, p->phy_info[i].port_details);
3304 		kfree(p->phy_info);
3305 		kfree(p);
3306 	}
3307 	mutex_unlock(&ioc->sas_topology_mutex);
3308 
3309 	mptscsih_remove(pdev);
3310 }
3311 
3312 static struct pci_device_id mptsas_pci_table[] = {
3313 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
3314 		PCI_ANY_ID, PCI_ANY_ID },
3315 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
3316 		PCI_ANY_ID, PCI_ANY_ID },
3317 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
3318 		PCI_ANY_ID, PCI_ANY_ID },
3319 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
3320 		PCI_ANY_ID, PCI_ANY_ID },
3321 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
3322 		PCI_ANY_ID, PCI_ANY_ID },
3323 	{0}	/* Terminating entry */
3324 };
3325 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
3326 
3327 
3328 static struct pci_driver mptsas_driver = {
3329 	.name		= "mptsas",
3330 	.id_table	= mptsas_pci_table,
3331 	.probe		= mptsas_probe,
3332 	.remove		= __devexit_p(mptsas_remove),
3333 	.shutdown	= mptscsih_shutdown,
3334 #ifdef CONFIG_PM
3335 	.suspend	= mptscsih_suspend,
3336 	.resume		= mptscsih_resume,
3337 #endif
3338 };
3339 
3340 static int __init
3341 mptsas_init(void)
3342 {
3343 	int error;
3344 
3345 	show_mptmod_ver(my_NAME, my_VERSION);
3346 
3347 	mptsas_transport_template =
3348 	    sas_attach_transport(&mptsas_transport_functions);
3349 	if (!mptsas_transport_template)
3350 		return -ENODEV;
3351 
3352 	mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
3353 	mptsasTaskCtx = mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
3354 	mptsasInternalCtx =
3355 		mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
3356 	mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
3357 
3358 	mpt_event_register(mptsasDoneCtx, mptsas_event_process);
3359 	mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
3360 
3361 	error = pci_register_driver(&mptsas_driver);
3362 	if (error)
3363 		sas_release_transport(mptsas_transport_template);
3364 
3365 	return error;
3366 }
3367 
3368 static void __exit
3369 mptsas_exit(void)
3370 {
3371 	pci_unregister_driver(&mptsas_driver);
3372 	sas_release_transport(mptsas_transport_template);
3373 
3374 	mpt_reset_deregister(mptsasDoneCtx);
3375 	mpt_event_deregister(mptsasDoneCtx);
3376 
3377 	mpt_deregister(mptsasMgmtCtx);
3378 	mpt_deregister(mptsasInternalCtx);
3379 	mpt_deregister(mptsasTaskCtx);
3380 	mpt_deregister(mptsasDoneCtx);
3381 }
3382 
3383 module_init(mptsas_init);
3384 module_exit(mptsas_exit);
3385