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