xref: /openbmc/linux/drivers/message/fusion/mptsas.c (revision d0b73b48)
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-2008 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/slab.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/jiffies.h>
52 #include <linux/workqueue.h>
53 #include <linux/delay.h>	/* for mdelay */
54 
55 #include <scsi/scsi.h>
56 #include <scsi/scsi_cmnd.h>
57 #include <scsi/scsi_device.h>
58 #include <scsi/scsi_host.h>
59 #include <scsi/scsi_transport_sas.h>
60 #include <scsi/scsi_transport.h>
61 #include <scsi/scsi_dbg.h>
62 
63 #include "mptbase.h"
64 #include "mptscsih.h"
65 #include "mptsas.h"
66 
67 
68 #define my_NAME		"Fusion MPT SAS Host driver"
69 #define my_VERSION	MPT_LINUX_VERSION_COMMON
70 #define MYNAM		"mptsas"
71 
72 /*
73  * Reserved channel for integrated raid
74  */
75 #define MPTSAS_RAID_CHANNEL	1
76 
77 #define SAS_CONFIG_PAGE_TIMEOUT		30
78 MODULE_AUTHOR(MODULEAUTHOR);
79 MODULE_DESCRIPTION(my_NAME);
80 MODULE_LICENSE("GPL");
81 MODULE_VERSION(my_VERSION);
82 
83 static int mpt_pt_clear;
84 module_param(mpt_pt_clear, int, 0);
85 MODULE_PARM_DESC(mpt_pt_clear,
86 		" Clear persistency table: enable=1  "
87 		"(default=MPTSCSIH_PT_CLEAR=0)");
88 
89 /* scsi-mid layer global parmeter is max_report_luns, which is 511 */
90 #define MPTSAS_MAX_LUN (16895)
91 static int max_lun = MPTSAS_MAX_LUN;
92 module_param(max_lun, int, 0);
93 MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
94 
95 static int mpt_loadtime_max_sectors = 8192;
96 module_param(mpt_loadtime_max_sectors, int, 0);
97 MODULE_PARM_DESC(mpt_loadtime_max_sectors,
98 		" Maximum sector define for Host Bus Adaptor.Range 64 to 8192 default=8192");
99 
100 static u8	mptsasDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
101 static u8	mptsasTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
102 static u8	mptsasInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
103 static u8	mptsasMgmtCtx = MPT_MAX_PROTOCOL_DRIVERS;
104 static u8	mptsasDeviceResetCtx = MPT_MAX_PROTOCOL_DRIVERS;
105 
106 static void mptsas_firmware_event_work(struct work_struct *work);
107 static void mptsas_send_sas_event(struct fw_event_work *fw_event);
108 static void mptsas_send_raid_event(struct fw_event_work *fw_event);
109 static void mptsas_send_ir2_event(struct fw_event_work *fw_event);
110 static void mptsas_parse_device_info(struct sas_identify *identify,
111 		struct mptsas_devinfo *device_info);
112 static inline void mptsas_set_rphy(MPT_ADAPTER *ioc,
113 		struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy);
114 static struct mptsas_phyinfo	*mptsas_find_phyinfo_by_sas_address
115 		(MPT_ADAPTER *ioc, u64 sas_address);
116 static int mptsas_sas_device_pg0(MPT_ADAPTER *ioc,
117 	struct mptsas_devinfo *device_info, u32 form, u32 form_specific);
118 static int mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc,
119 	struct mptsas_enclosure *enclosure, u32 form, u32 form_specific);
120 static int mptsas_add_end_device(MPT_ADAPTER *ioc,
121 	struct mptsas_phyinfo *phy_info);
122 static void mptsas_del_end_device(MPT_ADAPTER *ioc,
123 	struct mptsas_phyinfo *phy_info);
124 static void mptsas_send_link_status_event(struct fw_event_work *fw_event);
125 static struct mptsas_portinfo	*mptsas_find_portinfo_by_sas_address
126 		(MPT_ADAPTER *ioc, u64 sas_address);
127 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
128 		struct mptsas_portinfo *port_info, u8 force);
129 static void mptsas_send_expander_event(struct fw_event_work *fw_event);
130 static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
131 static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
132 static void mptsas_broadcast_primative_work(struct fw_event_work *fw_event);
133 static void mptsas_handle_queue_full_event(struct fw_event_work *fw_event);
134 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
135 void	mptsas_schedule_target_reset(void *ioc);
136 
137 static void mptsas_print_phy_data(MPT_ADAPTER *ioc,
138 					MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
139 {
140 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
141 	    "---- IO UNIT PAGE 0 ------------\n", ioc->name));
142 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
143 	    ioc->name, le16_to_cpu(phy_data->AttachedDeviceHandle)));
144 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Controller Handle=0x%X\n",
145 	    ioc->name, le16_to_cpu(phy_data->ControllerDevHandle)));
146 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port=0x%X\n",
147 	    ioc->name, phy_data->Port));
148 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Port Flags=0x%X\n",
149 	    ioc->name, phy_data->PortFlags));
150 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Flags=0x%X\n",
151 	    ioc->name, phy_data->PhyFlags));
152 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
153 	    ioc->name, phy_data->NegotiatedLinkRate));
154 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
155 	    "Controller PHY Device Info=0x%X\n", ioc->name,
156 	    le32_to_cpu(phy_data->ControllerPhyDeviceInfo)));
157 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DiscoveryStatus=0x%X\n\n",
158 	    ioc->name, le32_to_cpu(phy_data->DiscoveryStatus)));
159 }
160 
161 static void mptsas_print_phy_pg0(MPT_ADAPTER *ioc, SasPhyPage0_t *pg0)
162 {
163 	__le64 sas_address;
164 
165 	memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
166 
167 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
168 	    "---- SAS PHY PAGE 0 ------------\n", ioc->name));
169 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
170 	    "Attached Device Handle=0x%X\n", ioc->name,
171 	    le16_to_cpu(pg0->AttachedDevHandle)));
172 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
173 	    ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
174 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
175 	    "Attached PHY Identifier=0x%X\n", ioc->name,
176 	    pg0->AttachedPhyIdentifier));
177 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Attached Device Info=0x%X\n",
178 	    ioc->name, le32_to_cpu(pg0->AttachedDeviceInfo)));
179 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
180 	    ioc->name,  pg0->ProgrammedLinkRate));
181 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Change Count=0x%X\n",
182 	    ioc->name, pg0->ChangeCount));
183 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Info=0x%X\n\n",
184 	    ioc->name, le32_to_cpu(pg0->PhyInfo)));
185 }
186 
187 static void mptsas_print_phy_pg1(MPT_ADAPTER *ioc, SasPhyPage1_t *pg1)
188 {
189 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
190 	    "---- SAS PHY PAGE 1 ------------\n", ioc->name));
191 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Invalid Dword Count=0x%x\n",
192 	    ioc->name,  pg1->InvalidDwordCount));
193 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
194 	    "Running Disparity Error Count=0x%x\n", ioc->name,
195 	    pg1->RunningDisparityErrorCount));
196 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
197 	    "Loss Dword Synch Count=0x%x\n", ioc->name,
198 	    pg1->LossDwordSynchCount));
199 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
200 	    "PHY Reset Problem Count=0x%x\n\n", ioc->name,
201 	    pg1->PhyResetProblemCount));
202 }
203 
204 static void mptsas_print_device_pg0(MPT_ADAPTER *ioc, SasDevicePage0_t *pg0)
205 {
206 	__le64 sas_address;
207 
208 	memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
209 
210 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
211 	    "---- SAS DEVICE PAGE 0 ---------\n", ioc->name));
212 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handle=0x%X\n",
213 	    ioc->name, le16_to_cpu(pg0->DevHandle)));
214 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Handle=0x%X\n",
215 	    ioc->name, le16_to_cpu(pg0->ParentDevHandle)));
216 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Enclosure Handle=0x%X\n",
217 	    ioc->name, le16_to_cpu(pg0->EnclosureHandle)));
218 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Slot=0x%X\n",
219 	    ioc->name, le16_to_cpu(pg0->Slot)));
220 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SAS Address=0x%llX\n",
221 	    ioc->name, (unsigned long long)le64_to_cpu(sas_address)));
222 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Target ID=0x%X\n",
223 	    ioc->name, pg0->TargetID));
224 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Bus=0x%X\n",
225 	    ioc->name, pg0->Bus));
226 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Parent Phy Num=0x%X\n",
227 	    ioc->name, pg0->PhyNum));
228 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Access Status=0x%X\n",
229 	    ioc->name, le16_to_cpu(pg0->AccessStatus)));
230 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Device Info=0x%X\n",
231 	    ioc->name, le32_to_cpu(pg0->DeviceInfo)));
232 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Flags=0x%X\n",
233 	    ioc->name, le16_to_cpu(pg0->Flags)));
234 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n\n",
235 	    ioc->name, pg0->PhysicalPort));
236 }
237 
238 static void mptsas_print_expander_pg1(MPT_ADAPTER *ioc, SasExpanderPage1_t *pg1)
239 {
240 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
241 	    "---- SAS EXPANDER PAGE 1 ------------\n", ioc->name));
242 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Physical Port=0x%X\n",
243 	    ioc->name, pg1->PhysicalPort));
244 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PHY Identifier=0x%X\n",
245 	    ioc->name, pg1->PhyIdentifier));
246 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Negotiated Link Rate=0x%X\n",
247 	    ioc->name, pg1->NegotiatedLinkRate));
248 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Programmed Link Rate=0x%X\n",
249 	    ioc->name, pg1->ProgrammedLinkRate));
250 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hardware Link Rate=0x%X\n",
251 	    ioc->name, pg1->HwLinkRate));
252 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Owner Device Handle=0x%X\n",
253 	    ioc->name, le16_to_cpu(pg1->OwnerDevHandle)));
254 	dsasprintk(ioc, printk(MYIOC_s_DEBUG_FMT
255 	    "Attached Device Handle=0x%X\n\n", ioc->name,
256 	    le16_to_cpu(pg1->AttachedDevHandle)));
257 }
258 
259 /* inhibit sas firmware event handling */
260 static void
261 mptsas_fw_event_off(MPT_ADAPTER *ioc)
262 {
263 	unsigned long flags;
264 
265 	spin_lock_irqsave(&ioc->fw_event_lock, flags);
266 	ioc->fw_events_off = 1;
267 	ioc->sas_discovery_quiesce_io = 0;
268 	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
269 
270 }
271 
272 /* enable sas firmware event handling */
273 static void
274 mptsas_fw_event_on(MPT_ADAPTER *ioc)
275 {
276 	unsigned long flags;
277 
278 	spin_lock_irqsave(&ioc->fw_event_lock, flags);
279 	ioc->fw_events_off = 0;
280 	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
281 }
282 
283 /* queue a sas firmware event */
284 static void
285 mptsas_add_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
286     unsigned long delay)
287 {
288 	unsigned long flags;
289 
290 	spin_lock_irqsave(&ioc->fw_event_lock, flags);
291 	list_add_tail(&fw_event->list, &ioc->fw_event_list);
292 	INIT_DELAYED_WORK(&fw_event->work, mptsas_firmware_event_work);
293 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: add (fw_event=0x%p)"
294 		"on cpuid %d\n", ioc->name, __func__,
295 		fw_event, smp_processor_id()));
296 	queue_delayed_work_on(smp_processor_id(), ioc->fw_event_q,
297 	    &fw_event->work, delay);
298 	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
299 }
300 
301 /* requeue a sas firmware event */
302 static void
303 mptsas_requeue_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
304     unsigned long delay)
305 {
306 	unsigned long flags;
307 	spin_lock_irqsave(&ioc->fw_event_lock, flags);
308 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: reschedule task "
309 	    "(fw_event=0x%p)on cpuid %d\n", ioc->name, __func__,
310 		fw_event, smp_processor_id()));
311 	fw_event->retries++;
312 	queue_delayed_work_on(smp_processor_id(), ioc->fw_event_q,
313 	    &fw_event->work, msecs_to_jiffies(delay));
314 	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
315 }
316 
317 /* free memory associated to a sas firmware event */
318 static void
319 mptsas_free_fw_event(MPT_ADAPTER *ioc, struct fw_event_work *fw_event)
320 {
321 	unsigned long flags;
322 
323 	spin_lock_irqsave(&ioc->fw_event_lock, flags);
324 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: kfree (fw_event=0x%p)\n",
325 	    ioc->name, __func__, fw_event));
326 	list_del(&fw_event->list);
327 	kfree(fw_event);
328 	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
329 }
330 
331 /* walk the firmware event queue, and either stop or wait for
332  * outstanding events to complete */
333 static void
334 mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
335 {
336 	struct fw_event_work *fw_event, *next;
337 	struct mptsas_target_reset_event *target_reset_list, *n;
338 	MPT_SCSI_HOST	*hd = shost_priv(ioc->sh);
339 
340 	/* flush the target_reset_list */
341 	if (!list_empty(&hd->target_reset_list)) {
342 		list_for_each_entry_safe(target_reset_list, n,
343 		    &hd->target_reset_list, list) {
344 			dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
345 			    "%s: removing target reset for id=%d\n",
346 			    ioc->name, __func__,
347 			   target_reset_list->sas_event_data.TargetID));
348 			list_del(&target_reset_list->list);
349 			kfree(target_reset_list);
350 		}
351 	}
352 
353 	if (list_empty(&ioc->fw_event_list) ||
354 	     !ioc->fw_event_q || in_interrupt())
355 		return;
356 
357 	list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
358 		if (cancel_delayed_work(&fw_event->work))
359 			mptsas_free_fw_event(ioc, fw_event);
360 	}
361 }
362 
363 
364 static inline MPT_ADAPTER *phy_to_ioc(struct sas_phy *phy)
365 {
366 	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
367 	return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
368 }
369 
370 static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
371 {
372 	struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
373 	return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
374 }
375 
376 /*
377  * mptsas_find_portinfo_by_handle
378  *
379  * This function should be called with the sas_topology_mutex already held
380  */
381 static struct mptsas_portinfo *
382 mptsas_find_portinfo_by_handle(MPT_ADAPTER *ioc, u16 handle)
383 {
384 	struct mptsas_portinfo *port_info, *rc=NULL;
385 	int i;
386 
387 	list_for_each_entry(port_info, &ioc->sas_topology, list)
388 		for (i = 0; i < port_info->num_phys; i++)
389 			if (port_info->phy_info[i].identify.handle == handle) {
390 				rc = port_info;
391 				goto out;
392 			}
393  out:
394 	return rc;
395 }
396 
397 /**
398  *	mptsas_find_portinfo_by_sas_address -
399  *	@ioc: Pointer to MPT_ADAPTER structure
400  *	@handle:
401  *
402  *	This function should be called with the sas_topology_mutex already held
403  *
404  **/
405 static struct mptsas_portinfo *
406 mptsas_find_portinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
407 {
408 	struct mptsas_portinfo *port_info, *rc = NULL;
409 	int i;
410 
411 	if (sas_address >= ioc->hba_port_sas_addr &&
412 	    sas_address < (ioc->hba_port_sas_addr +
413 	    ioc->hba_port_num_phy))
414 		return ioc->hba_port_info;
415 
416 	mutex_lock(&ioc->sas_topology_mutex);
417 	list_for_each_entry(port_info, &ioc->sas_topology, list)
418 		for (i = 0; i < port_info->num_phys; i++)
419 			if (port_info->phy_info[i].identify.sas_address ==
420 			    sas_address) {
421 				rc = port_info;
422 				goto out;
423 			}
424  out:
425 	mutex_unlock(&ioc->sas_topology_mutex);
426 	return rc;
427 }
428 
429 /*
430  * Returns true if there is a scsi end device
431  */
432 static inline int
433 mptsas_is_end_device(struct mptsas_devinfo * attached)
434 {
435 	if ((attached->sas_address) &&
436 	    (attached->device_info &
437 	    MPI_SAS_DEVICE_INFO_END_DEVICE) &&
438 	    ((attached->device_info &
439 	    MPI_SAS_DEVICE_INFO_SSP_TARGET) |
440 	    (attached->device_info &
441 	    MPI_SAS_DEVICE_INFO_STP_TARGET) |
442 	    (attached->device_info &
443 	    MPI_SAS_DEVICE_INFO_SATA_DEVICE)))
444 		return 1;
445 	else
446 		return 0;
447 }
448 
449 /* no mutex */
450 static void
451 mptsas_port_delete(MPT_ADAPTER *ioc, struct mptsas_portinfo_details * port_details)
452 {
453 	struct mptsas_portinfo *port_info;
454 	struct mptsas_phyinfo *phy_info;
455 	u8	i;
456 
457 	if (!port_details)
458 		return;
459 
460 	port_info = port_details->port_info;
461 	phy_info = port_info->phy_info;
462 
463 	dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: [%p]: num_phys=%02d "
464 	    "bitmask=0x%016llX\n", ioc->name, __func__, port_details,
465 	    port_details->num_phys, (unsigned long long)
466 	    port_details->phy_bitmask));
467 
468 	for (i = 0; i < port_info->num_phys; i++, phy_info++) {
469 		if(phy_info->port_details != port_details)
470 			continue;
471 		memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
472 		mptsas_set_rphy(ioc, phy_info, NULL);
473 		phy_info->port_details = NULL;
474 	}
475 	kfree(port_details);
476 }
477 
478 static inline struct sas_rphy *
479 mptsas_get_rphy(struct mptsas_phyinfo *phy_info)
480 {
481 	if (phy_info->port_details)
482 		return phy_info->port_details->rphy;
483 	else
484 		return NULL;
485 }
486 
487 static inline void
488 mptsas_set_rphy(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_rphy *rphy)
489 {
490 	if (phy_info->port_details) {
491 		phy_info->port_details->rphy = rphy;
492 		dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sas_rphy_add: rphy=%p\n",
493 		    ioc->name, rphy));
494 	}
495 
496 	if (rphy) {
497 		dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
498 		    &rphy->dev, MYIOC_s_FMT "add:", ioc->name));
499 		dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rphy=%p release=%p\n",
500 		    ioc->name, rphy, rphy->dev.release));
501 	}
502 }
503 
504 static inline struct sas_port *
505 mptsas_get_port(struct mptsas_phyinfo *phy_info)
506 {
507 	if (phy_info->port_details)
508 		return phy_info->port_details->port;
509 	else
510 		return NULL;
511 }
512 
513 static inline void
514 mptsas_set_port(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, struct sas_port *port)
515 {
516 	if (phy_info->port_details)
517 		phy_info->port_details->port = port;
518 
519 	if (port) {
520 		dsaswideprintk(ioc, dev_printk(KERN_DEBUG,
521 		    &port->dev, MYIOC_s_FMT "add:", ioc->name));
522 		dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "port=%p release=%p\n",
523 		    ioc->name, port, port->dev.release));
524 	}
525 }
526 
527 static inline struct scsi_target *
528 mptsas_get_starget(struct mptsas_phyinfo *phy_info)
529 {
530 	if (phy_info->port_details)
531 		return phy_info->port_details->starget;
532 	else
533 		return NULL;
534 }
535 
536 static inline void
537 mptsas_set_starget(struct mptsas_phyinfo *phy_info, struct scsi_target *
538 starget)
539 {
540 	if (phy_info->port_details)
541 		phy_info->port_details->starget = starget;
542 }
543 
544 /**
545  *	mptsas_add_device_component -
546  *	@ioc: Pointer to MPT_ADAPTER structure
547  *	@channel: fw mapped id's
548  *	@id:
549  *	@sas_address:
550  *	@device_info:
551  *
552  **/
553 static void
554 mptsas_add_device_component(MPT_ADAPTER *ioc, u8 channel, u8 id,
555 	u64 sas_address, u32 device_info, u16 slot, u64 enclosure_logical_id)
556 {
557 	struct mptsas_device_info	*sas_info, *next;
558 	struct scsi_device	*sdev;
559 	struct scsi_target	*starget;
560 	struct sas_rphy	*rphy;
561 
562 	/*
563 	 * Delete all matching devices out of the list
564 	 */
565 	mutex_lock(&ioc->sas_device_info_mutex);
566 	list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
567 	    list) {
568 		if (!sas_info->is_logical_volume &&
569 		    (sas_info->sas_address == sas_address ||
570 		    (sas_info->fw.channel == channel &&
571 		     sas_info->fw.id == id))) {
572 			list_del(&sas_info->list);
573 			kfree(sas_info);
574 		}
575 	}
576 
577 	sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
578 	if (!sas_info)
579 		goto out;
580 
581 	/*
582 	 * Set Firmware mapping
583 	 */
584 	sas_info->fw.id = id;
585 	sas_info->fw.channel = channel;
586 
587 	sas_info->sas_address = sas_address;
588 	sas_info->device_info = device_info;
589 	sas_info->slot = slot;
590 	sas_info->enclosure_logical_id = enclosure_logical_id;
591 	INIT_LIST_HEAD(&sas_info->list);
592 	list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
593 
594 	/*
595 	 * Set OS mapping
596 	 */
597 	shost_for_each_device(sdev, ioc->sh) {
598 		starget = scsi_target(sdev);
599 		rphy = dev_to_rphy(starget->dev.parent);
600 		if (rphy->identify.sas_address == sas_address) {
601 			sas_info->os.id = starget->id;
602 			sas_info->os.channel = starget->channel;
603 		}
604 	}
605 
606  out:
607 	mutex_unlock(&ioc->sas_device_info_mutex);
608 	return;
609 }
610 
611 /**
612  *	mptsas_add_device_component_by_fw -
613  *	@ioc: Pointer to MPT_ADAPTER structure
614  *	@channel:  fw mapped id's
615  *	@id:
616  *
617  **/
618 static void
619 mptsas_add_device_component_by_fw(MPT_ADAPTER *ioc, u8 channel, u8 id)
620 {
621 	struct mptsas_devinfo sas_device;
622 	struct mptsas_enclosure enclosure_info;
623 	int rc;
624 
625 	rc = mptsas_sas_device_pg0(ioc, &sas_device,
626 	    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
627 	     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
628 	    (channel << 8) + id);
629 	if (rc)
630 		return;
631 
632 	memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
633 	mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
634 	    (MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
635 	     MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
636 	     sas_device.handle_enclosure);
637 
638 	mptsas_add_device_component(ioc, sas_device.channel,
639 	    sas_device.id, sas_device.sas_address, sas_device.device_info,
640 	    sas_device.slot, enclosure_info.enclosure_logical_id);
641 }
642 
643 /**
644  *	mptsas_add_device_component_starget_ir - Handle Integrated RAID, adding each individual device to list
645  *	@ioc: Pointer to MPT_ADAPTER structure
646  *	@channel: fw mapped id's
647  *	@id:
648  *
649  **/
650 static void
651 mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
652 		struct scsi_target *starget)
653 {
654 	CONFIGPARMS			cfg;
655 	ConfigPageHeader_t		hdr;
656 	dma_addr_t			dma_handle;
657 	pRaidVolumePage0_t		buffer = NULL;
658 	int				i;
659 	RaidPhysDiskPage0_t 		phys_disk;
660 	struct mptsas_device_info	*sas_info, *next;
661 
662 	memset(&cfg, 0 , sizeof(CONFIGPARMS));
663 	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
664 	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
665 	/* assumption that all volumes on channel = 0 */
666 	cfg.pageAddr = starget->id;
667 	cfg.cfghdr.hdr = &hdr;
668 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
669 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
670 
671 	if (mpt_config(ioc, &cfg) != 0)
672 		goto out;
673 
674 	if (!hdr.PageLength)
675 		goto out;
676 
677 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
678 	    &dma_handle);
679 
680 	if (!buffer)
681 		goto out;
682 
683 	cfg.physAddr = dma_handle;
684 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
685 
686 	if (mpt_config(ioc, &cfg) != 0)
687 		goto out;
688 
689 	if (!buffer->NumPhysDisks)
690 		goto out;
691 
692 	/*
693 	 * Adding entry for hidden components
694 	 */
695 	for (i = 0; i < buffer->NumPhysDisks; i++) {
696 
697 		if (mpt_raid_phys_disk_pg0(ioc,
698 		    buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
699 			continue;
700 
701 		mptsas_add_device_component_by_fw(ioc, phys_disk.PhysDiskBus,
702 		    phys_disk.PhysDiskID);
703 
704 		mutex_lock(&ioc->sas_device_info_mutex);
705 		list_for_each_entry(sas_info, &ioc->sas_device_info_list,
706 		    list) {
707 			if (!sas_info->is_logical_volume &&
708 			    (sas_info->fw.channel == phys_disk.PhysDiskBus &&
709 			    sas_info->fw.id == phys_disk.PhysDiskID)) {
710 				sas_info->is_hidden_raid_component = 1;
711 				sas_info->volume_id = starget->id;
712 			}
713 		}
714 		mutex_unlock(&ioc->sas_device_info_mutex);
715 
716 	}
717 
718 	/*
719 	 * Delete all matching devices out of the list
720 	 */
721 	mutex_lock(&ioc->sas_device_info_mutex);
722 	list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
723 	    list) {
724 		if (sas_info->is_logical_volume && sas_info->fw.id ==
725 		    starget->id) {
726 			list_del(&sas_info->list);
727 			kfree(sas_info);
728 		}
729 	}
730 
731 	sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL);
732 	if (sas_info) {
733 		sas_info->fw.id = starget->id;
734 		sas_info->os.id = starget->id;
735 		sas_info->os.channel = starget->channel;
736 		sas_info->is_logical_volume = 1;
737 		INIT_LIST_HEAD(&sas_info->list);
738 		list_add_tail(&sas_info->list, &ioc->sas_device_info_list);
739 	}
740 	mutex_unlock(&ioc->sas_device_info_mutex);
741 
742  out:
743 	if (buffer)
744 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
745 		    dma_handle);
746 }
747 
748 /**
749  *	mptsas_add_device_component_starget -
750  *	@ioc: Pointer to MPT_ADAPTER structure
751  *	@starget:
752  *
753  **/
754 static void
755 mptsas_add_device_component_starget(MPT_ADAPTER *ioc,
756 	struct scsi_target *starget)
757 {
758 	VirtTarget	*vtarget;
759 	struct sas_rphy	*rphy;
760 	struct mptsas_phyinfo	*phy_info = NULL;
761 	struct mptsas_enclosure	enclosure_info;
762 
763 	rphy = dev_to_rphy(starget->dev.parent);
764 	vtarget = starget->hostdata;
765 	phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
766 			rphy->identify.sas_address);
767 	if (!phy_info)
768 		return;
769 
770 	memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
771 	mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
772 		(MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
773 		MPI_SAS_ENCLOS_PGAD_FORM_SHIFT),
774 		phy_info->attached.handle_enclosure);
775 
776 	mptsas_add_device_component(ioc, phy_info->attached.channel,
777 		phy_info->attached.id, phy_info->attached.sas_address,
778 		phy_info->attached.device_info,
779 		phy_info->attached.slot, enclosure_info.enclosure_logical_id);
780 }
781 
782 /**
783  *	mptsas_del_device_component_by_os - Once a device has been removed, we mark the entry in the list as being cached
784  *	@ioc: Pointer to MPT_ADAPTER structure
785  *	@channel: os mapped id's
786  *	@id:
787  *
788  **/
789 static void
790 mptsas_del_device_component_by_os(MPT_ADAPTER *ioc, u8 channel, u8 id)
791 {
792 	struct mptsas_device_info	*sas_info, *next;
793 
794 	/*
795 	 * Set is_cached flag
796 	 */
797 	list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
798 		list) {
799 		if (sas_info->os.channel == channel && sas_info->os.id == id)
800 			sas_info->is_cached = 1;
801 	}
802 }
803 
804 /**
805  *	mptsas_del_device_components - Cleaning the list
806  *	@ioc: Pointer to MPT_ADAPTER structure
807  *
808  **/
809 static void
810 mptsas_del_device_components(MPT_ADAPTER *ioc)
811 {
812 	struct mptsas_device_info	*sas_info, *next;
813 
814 	mutex_lock(&ioc->sas_device_info_mutex);
815 	list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list,
816 		list) {
817 		list_del(&sas_info->list);
818 		kfree(sas_info);
819 	}
820 	mutex_unlock(&ioc->sas_device_info_mutex);
821 }
822 
823 
824 /*
825  * mptsas_setup_wide_ports
826  *
827  * Updates for new and existing narrow/wide port configuration
828  * in the sas_topology
829  */
830 static void
831 mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
832 {
833 	struct mptsas_portinfo_details * port_details;
834 	struct mptsas_phyinfo *phy_info, *phy_info_cmp;
835 	u64	sas_address;
836 	int	i, j;
837 
838 	mutex_lock(&ioc->sas_topology_mutex);
839 
840 	phy_info = port_info->phy_info;
841 	for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
842 		if (phy_info->attached.handle)
843 			continue;
844 		port_details = phy_info->port_details;
845 		if (!port_details)
846 			continue;
847 		if (port_details->num_phys < 2)
848 			continue;
849 		/*
850 		 * Removing a phy from a port, letting the last
851 		 * phy be removed by firmware events.
852 		 */
853 		dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
854 		    "%s: [%p]: deleting phy = %d\n",
855 		    ioc->name, __func__, port_details, i));
856 		port_details->num_phys--;
857 		port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
858 		memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
859 		if (phy_info->phy) {
860 			devtprintk(ioc, dev_printk(KERN_DEBUG,
861 				&phy_info->phy->dev, MYIOC_s_FMT
862 				"delete phy %d, phy-obj (0x%p)\n", ioc->name,
863 				phy_info->phy_id, phy_info->phy));
864 			sas_port_delete_phy(port_details->port, phy_info->phy);
865 		}
866 		phy_info->port_details = NULL;
867 	}
868 
869 	/*
870 	 * Populate and refresh the tree
871 	 */
872 	phy_info = port_info->phy_info;
873 	for (i = 0 ; i < port_info->num_phys ; i++, phy_info++) {
874 		sas_address = phy_info->attached.sas_address;
875 		dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "phy_id=%d sas_address=0x%018llX\n",
876 		    ioc->name, i, (unsigned long long)sas_address));
877 		if (!sas_address)
878 			continue;
879 		port_details = phy_info->port_details;
880 		/*
881 		 * Forming a port
882 		 */
883 		if (!port_details) {
884 			port_details = kzalloc(sizeof(struct
885 				mptsas_portinfo_details), GFP_KERNEL);
886 			if (!port_details)
887 				goto out;
888 			port_details->num_phys = 1;
889 			port_details->port_info = port_info;
890 			if (phy_info->phy_id < 64 )
891 				port_details->phy_bitmask |=
892 				    (1 << phy_info->phy_id);
893 			phy_info->sas_port_add_phy=1;
894 			dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tForming port\n\t\t"
895 			    "phy_id=%d sas_address=0x%018llX\n",
896 			    ioc->name, i, (unsigned long long)sas_address));
897 			phy_info->port_details = port_details;
898 		}
899 
900 		if (i == port_info->num_phys - 1)
901 			continue;
902 		phy_info_cmp = &port_info->phy_info[i + 1];
903 		for (j = i + 1 ; j < port_info->num_phys ; j++,
904 		    phy_info_cmp++) {
905 			if (!phy_info_cmp->attached.sas_address)
906 				continue;
907 			if (sas_address != phy_info_cmp->attached.sas_address)
908 				continue;
909 			if (phy_info_cmp->port_details == port_details )
910 				continue;
911 			dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
912 			    "\t\tphy_id=%d sas_address=0x%018llX\n",
913 			    ioc->name, j, (unsigned long long)
914 			    phy_info_cmp->attached.sas_address));
915 			if (phy_info_cmp->port_details) {
916 				port_details->rphy =
917 				    mptsas_get_rphy(phy_info_cmp);
918 				port_details->port =
919 				    mptsas_get_port(phy_info_cmp);
920 				port_details->starget =
921 				    mptsas_get_starget(phy_info_cmp);
922 				port_details->num_phys =
923 					phy_info_cmp->port_details->num_phys;
924 				if (!phy_info_cmp->port_details->num_phys)
925 					kfree(phy_info_cmp->port_details);
926 			} else
927 				phy_info_cmp->sas_port_add_phy=1;
928 			/*
929 			 * Adding a phy to a port
930 			 */
931 			phy_info_cmp->port_details = port_details;
932 			if (phy_info_cmp->phy_id < 64 )
933 				port_details->phy_bitmask |=
934 				(1 << phy_info_cmp->phy_id);
935 			port_details->num_phys++;
936 		}
937 	}
938 
939  out:
940 
941 	for (i = 0; i < port_info->num_phys; i++) {
942 		port_details = port_info->phy_info[i].port_details;
943 		if (!port_details)
944 			continue;
945 		dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
946 		    "%s: [%p]: phy_id=%02d num_phys=%02d "
947 		    "bitmask=0x%016llX\n", ioc->name, __func__,
948 		    port_details, i, port_details->num_phys,
949 		    (unsigned long long)port_details->phy_bitmask));
950 		dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",
951 		    ioc->name, port_details->port, port_details->rphy));
952 	}
953 	dsaswideprintk(ioc, printk("\n"));
954 	mutex_unlock(&ioc->sas_topology_mutex);
955 }
956 
957 /**
958  * csmisas_find_vtarget
959  *
960  * @ioc
961  * @volume_id
962  * @volume_bus
963  *
964  **/
965 static VirtTarget *
966 mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
967 {
968 	struct scsi_device 		*sdev;
969 	VirtDevice			*vdevice;
970 	VirtTarget 			*vtarget = NULL;
971 
972 	shost_for_each_device(sdev, ioc->sh) {
973 		vdevice = sdev->hostdata;
974 		if ((vdevice == NULL) ||
975 			(vdevice->vtarget == NULL))
976 			continue;
977 		if ((vdevice->vtarget->tflags &
978 		    MPT_TARGET_FLAGS_RAID_COMPONENT ||
979 		    vdevice->vtarget->raidVolume))
980 			continue;
981 		if (vdevice->vtarget->id == id &&
982 			vdevice->vtarget->channel == channel)
983 			vtarget = vdevice->vtarget;
984 	}
985 	return vtarget;
986 }
987 
988 static void
989 mptsas_queue_device_delete(MPT_ADAPTER *ioc,
990 	MpiEventDataSasDeviceStatusChange_t *sas_event_data)
991 {
992 	struct fw_event_work *fw_event;
993 	int sz;
994 
995 	sz = offsetof(struct fw_event_work, event_data) +
996 	    sizeof(MpiEventDataSasDeviceStatusChange_t);
997 	fw_event = kzalloc(sz, GFP_ATOMIC);
998 	if (!fw_event) {
999 		printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
1000 		    ioc->name, __func__, __LINE__);
1001 		return;
1002 	}
1003 	memcpy(fw_event->event_data, sas_event_data,
1004 	    sizeof(MpiEventDataSasDeviceStatusChange_t));
1005 	fw_event->event = MPI_EVENT_SAS_DEVICE_STATUS_CHANGE;
1006 	fw_event->ioc = ioc;
1007 	mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1008 }
1009 
1010 static void
1011 mptsas_queue_rescan(MPT_ADAPTER *ioc)
1012 {
1013 	struct fw_event_work *fw_event;
1014 	int sz;
1015 
1016 	sz = offsetof(struct fw_event_work, event_data);
1017 	fw_event = kzalloc(sz, GFP_ATOMIC);
1018 	if (!fw_event) {
1019 		printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n",
1020 		    ioc->name, __func__, __LINE__);
1021 		return;
1022 	}
1023 	fw_event->event = -1;
1024 	fw_event->ioc = ioc;
1025 	mptsas_add_fw_event(ioc, fw_event, msecs_to_jiffies(1));
1026 }
1027 
1028 
1029 /**
1030  * mptsas_target_reset
1031  *
1032  * Issues TARGET_RESET to end device using handshaking method
1033  *
1034  * @ioc
1035  * @channel
1036  * @id
1037  *
1038  * Returns (1) success
1039  *         (0) failure
1040  *
1041  **/
1042 static int
1043 mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
1044 {
1045 	MPT_FRAME_HDR	*mf;
1046 	SCSITaskMgmt_t	*pScsiTm;
1047 	if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0)
1048 		return 0;
1049 
1050 
1051 	mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
1052 	if (mf == NULL) {
1053 		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1054 			"%s, no msg frames @%d!!\n", ioc->name,
1055 			__func__, __LINE__));
1056 		goto out_fail;
1057 	}
1058 
1059 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
1060 		ioc->name, mf));
1061 
1062 	/* Format the Request
1063 	 */
1064 	pScsiTm = (SCSITaskMgmt_t *) mf;
1065 	memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
1066 	pScsiTm->TargetID = id;
1067 	pScsiTm->Bus = channel;
1068 	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1069 	pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
1070 	pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
1071 
1072 	DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
1073 
1074 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1075 	   "TaskMgmt type=%d (sas device delete) fw_channel = %d fw_id = %d)\n",
1076 	   ioc->name, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, channel, id));
1077 
1078 	mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
1079 
1080 	return 1;
1081 
1082  out_fail:
1083 
1084 	mpt_clear_taskmgmt_in_progress_flag(ioc);
1085 	return 0;
1086 }
1087 
1088 static void
1089 mptsas_block_io_sdev(struct scsi_device *sdev, void *data)
1090 {
1091 	scsi_device_set_state(sdev, SDEV_BLOCK);
1092 }
1093 
1094 static void
1095 mptsas_block_io_starget(struct scsi_target *starget)
1096 {
1097 	if (starget)
1098 		starget_for_each_device(starget, NULL, mptsas_block_io_sdev);
1099 }
1100 
1101 /**
1102  * mptsas_target_reset_queue
1103  *
1104  * Receive request for TARGET_RESET after receiving an firmware
1105  * event NOT_RESPONDING_EVENT, then put command in link list
1106  * and queue if task_queue already in use.
1107  *
1108  * @ioc
1109  * @sas_event_data
1110  *
1111  **/
1112 static void
1113 mptsas_target_reset_queue(MPT_ADAPTER *ioc,
1114     EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
1115 {
1116 	MPT_SCSI_HOST	*hd = shost_priv(ioc->sh);
1117 	VirtTarget *vtarget = NULL;
1118 	struct mptsas_target_reset_event *target_reset_list;
1119 	u8		id, channel;
1120 
1121 	id = sas_event_data->TargetID;
1122 	channel = sas_event_data->Bus;
1123 
1124 	vtarget = mptsas_find_vtarget(ioc, channel, id);
1125 	if (vtarget) {
1126 		mptsas_block_io_starget(vtarget->starget);
1127 		vtarget->deleted = 1; /* block IO */
1128 	}
1129 
1130 	target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event),
1131 	    GFP_ATOMIC);
1132 	if (!target_reset_list) {
1133 		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
1134 			"%s, failed to allocate mem @%d..!!\n",
1135 			ioc->name, __func__, __LINE__));
1136 		return;
1137 	}
1138 
1139 	memcpy(&target_reset_list->sas_event_data, sas_event_data,
1140 		sizeof(*sas_event_data));
1141 	list_add_tail(&target_reset_list->list, &hd->target_reset_list);
1142 
1143 	target_reset_list->time_count = jiffies;
1144 
1145 	if (mptsas_target_reset(ioc, channel, id)) {
1146 		target_reset_list->target_reset_issued = 1;
1147 	}
1148 }
1149 
1150 /**
1151  * mptsas_schedule_target_reset- send pending target reset
1152  * @iocp: per adapter object
1153  *
1154  * This function will delete scheduled target reset from the list and
1155  * try to send next target reset. This will be called from completion
1156  * context of any Task management command.
1157  */
1158 
1159 void
1160 mptsas_schedule_target_reset(void *iocp)
1161 {
1162 	MPT_ADAPTER *ioc = (MPT_ADAPTER *)(iocp);
1163 	MPT_SCSI_HOST	*hd = shost_priv(ioc->sh);
1164 	struct list_head *head = &hd->target_reset_list;
1165 	struct mptsas_target_reset_event	*target_reset_list;
1166 	u8		id, channel;
1167 	/*
1168 	 * issue target reset to next device in the queue
1169 	 */
1170 
1171 	head = &hd->target_reset_list;
1172 	if (list_empty(head))
1173 		return;
1174 
1175 	target_reset_list = list_entry(head->next,
1176 		struct mptsas_target_reset_event, list);
1177 
1178 	id = target_reset_list->sas_event_data.TargetID;
1179 	channel = target_reset_list->sas_event_data.Bus;
1180 	target_reset_list->time_count = jiffies;
1181 
1182 	if (mptsas_target_reset(ioc, channel, id))
1183 		target_reset_list->target_reset_issued = 1;
1184 	return;
1185 }
1186 
1187 
1188 /**
1189  *	mptsas_taskmgmt_complete - complete SAS task management function
1190  *	@ioc: Pointer to MPT_ADAPTER structure
1191  *
1192  *	Completion for TARGET_RESET after NOT_RESPONDING_EVENT, enable work
1193  *	queue to finish off removing device from upper layers. then send next
1194  *	TARGET_RESET in the queue.
1195  **/
1196 static int
1197 mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
1198 {
1199 	MPT_SCSI_HOST	*hd = shost_priv(ioc->sh);
1200         struct list_head *head = &hd->target_reset_list;
1201 	u8		id, channel;
1202 	struct mptsas_target_reset_event	*target_reset_list;
1203 	SCSITaskMgmtReply_t *pScsiTmReply;
1204 
1205 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed: "
1206 	    "(mf = %p, mr = %p)\n", ioc->name, mf, mr));
1207 
1208 	pScsiTmReply = (SCSITaskMgmtReply_t *)mr;
1209 	if (pScsiTmReply) {
1210 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1211 		    "\tTaskMgmt completed: fw_channel = %d, fw_id = %d,\n"
1212 		    "\ttask_type = 0x%02X, iocstatus = 0x%04X "
1213 		    "loginfo = 0x%08X,\n\tresponse_code = 0x%02X, "
1214 		    "term_cmnds = %d\n", ioc->name,
1215 		    pScsiTmReply->Bus, pScsiTmReply->TargetID,
1216 		    pScsiTmReply->TaskType,
1217 		    le16_to_cpu(pScsiTmReply->IOCStatus),
1218 		    le32_to_cpu(pScsiTmReply->IOCLogInfo),
1219 		    pScsiTmReply->ResponseCode,
1220 		    le32_to_cpu(pScsiTmReply->TerminationCount)));
1221 
1222 		if (pScsiTmReply->ResponseCode)
1223 			mptscsih_taskmgmt_response_code(ioc,
1224 			pScsiTmReply->ResponseCode);
1225 	}
1226 
1227 	if (pScsiTmReply && (pScsiTmReply->TaskType ==
1228 	    MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK || pScsiTmReply->TaskType ==
1229 	     MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET)) {
1230 		ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
1231 		ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
1232 		memcpy(ioc->taskmgmt_cmds.reply, mr,
1233 		    min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
1234 		if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
1235 			ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
1236 			complete(&ioc->taskmgmt_cmds.done);
1237 			return 1;
1238 		}
1239 		return 0;
1240 	}
1241 
1242 	mpt_clear_taskmgmt_in_progress_flag(ioc);
1243 
1244 	if (list_empty(head))
1245 		return 1;
1246 
1247 	target_reset_list = list_entry(head->next,
1248 	    struct mptsas_target_reset_event, list);
1249 
1250 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1251 	    "TaskMgmt: completed (%d seconds)\n",
1252 	    ioc->name, jiffies_to_msecs(jiffies -
1253 	    target_reset_list->time_count)/1000));
1254 
1255 	id = pScsiTmReply->TargetID;
1256 	channel = pScsiTmReply->Bus;
1257 	target_reset_list->time_count = jiffies;
1258 
1259 	/*
1260 	 * retry target reset
1261 	 */
1262 	if (!target_reset_list->target_reset_issued) {
1263 		if (mptsas_target_reset(ioc, channel, id))
1264 			target_reset_list->target_reset_issued = 1;
1265 		return 1;
1266 	}
1267 
1268 	/*
1269 	 * enable work queue to remove device from upper layers
1270 	 */
1271 	list_del(&target_reset_list->list);
1272 	if (!ioc->fw_events_off)
1273 		mptsas_queue_device_delete(ioc,
1274 			&target_reset_list->sas_event_data);
1275 
1276 
1277 	ioc->schedule_target_reset(ioc);
1278 
1279 	return 1;
1280 }
1281 
1282 /**
1283  * mptscsih_ioc_reset
1284  *
1285  * @ioc
1286  * @reset_phase
1287  *
1288  **/
1289 static int
1290 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1291 {
1292 	MPT_SCSI_HOST	*hd;
1293 	int rc;
1294 
1295 	rc = mptscsih_ioc_reset(ioc, reset_phase);
1296 	if ((ioc->bus_type != SAS) || (!rc))
1297 		return rc;
1298 
1299 	hd = shost_priv(ioc->sh);
1300 	if (!hd->ioc)
1301 		goto out;
1302 
1303 	switch (reset_phase) {
1304 	case MPT_IOC_SETUP_RESET:
1305 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1306 		    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
1307 		mptsas_fw_event_off(ioc);
1308 		break;
1309 	case MPT_IOC_PRE_RESET:
1310 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1311 		    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
1312 		break;
1313 	case MPT_IOC_POST_RESET:
1314 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1315 		    "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
1316 		if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
1317 			ioc->sas_mgmt.status |= MPT_MGMT_STATUS_DID_IOCRESET;
1318 			complete(&ioc->sas_mgmt.done);
1319 		}
1320 		mptsas_cleanup_fw_event_q(ioc);
1321 		mptsas_queue_rescan(ioc);
1322 		break;
1323 	default:
1324 		break;
1325 	}
1326 
1327  out:
1328 	return rc;
1329 }
1330 
1331 
1332 /**
1333  * enum device_state -
1334  * @DEVICE_RETRY: need to retry the TUR
1335  * @DEVICE_ERROR: TUR return error, don't add device
1336  * @DEVICE_READY: device can be added
1337  *
1338  */
1339 enum device_state{
1340 	DEVICE_RETRY,
1341 	DEVICE_ERROR,
1342 	DEVICE_READY,
1343 };
1344 
1345 static int
1346 mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
1347 		u32 form, u32 form_specific)
1348 {
1349 	ConfigExtendedPageHeader_t hdr;
1350 	CONFIGPARMS cfg;
1351 	SasEnclosurePage0_t *buffer;
1352 	dma_addr_t dma_handle;
1353 	int error;
1354 	__le64 le_identifier;
1355 
1356 	memset(&hdr, 0, sizeof(hdr));
1357 	hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;
1358 	hdr.PageNumber = 0;
1359 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
1360 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;
1361 
1362 	cfg.cfghdr.ehdr = &hdr;
1363 	cfg.physAddr = -1;
1364 	cfg.pageAddr = form + form_specific;
1365 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
1366 	cfg.dir = 0;	/* read */
1367 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
1368 
1369 	error = mpt_config(ioc, &cfg);
1370 	if (error)
1371 		goto out;
1372 	if (!hdr.ExtPageLength) {
1373 		error = -ENXIO;
1374 		goto out;
1375 	}
1376 
1377 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1378 			&dma_handle);
1379 	if (!buffer) {
1380 		error = -ENOMEM;
1381 		goto out;
1382 	}
1383 
1384 	cfg.physAddr = dma_handle;
1385 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
1386 
1387 	error = mpt_config(ioc, &cfg);
1388 	if (error)
1389 		goto out_free_consistent;
1390 
1391 	/* save config data */
1392 	memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));
1393 	enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);
1394 	enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);
1395 	enclosure->flags = le16_to_cpu(buffer->Flags);
1396 	enclosure->num_slot = le16_to_cpu(buffer->NumSlots);
1397 	enclosure->start_slot = le16_to_cpu(buffer->StartSlot);
1398 	enclosure->start_id = buffer->StartTargetID;
1399 	enclosure->start_channel = buffer->StartBus;
1400 	enclosure->sep_id = buffer->SEPTargetID;
1401 	enclosure->sep_channel = buffer->SEPBus;
1402 
1403  out_free_consistent:
1404 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
1405 			    buffer, dma_handle);
1406  out:
1407 	return error;
1408 }
1409 
1410 /**
1411  *	mptsas_add_end_device - report a new end device to sas transport layer
1412  *	@ioc: Pointer to MPT_ADAPTER structure
1413  *	@phy_info: describes attached device
1414  *
1415  *	return (0) success (1) failure
1416  *
1417  **/
1418 static int
1419 mptsas_add_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1420 {
1421 	struct sas_rphy *rphy;
1422 	struct sas_port *port;
1423 	struct sas_identify identify;
1424 	char *ds = NULL;
1425 	u8 fw_id;
1426 
1427 	if (!phy_info) {
1428 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1429 			"%s: exit at line=%d\n", ioc->name,
1430 			 __func__, __LINE__));
1431 		return 1;
1432 	}
1433 
1434 	fw_id = phy_info->attached.id;
1435 
1436 	if (mptsas_get_rphy(phy_info)) {
1437 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1438 			"%s: fw_id=%d exit at line=%d\n", ioc->name,
1439 			 __func__, fw_id, __LINE__));
1440 		return 2;
1441 	}
1442 
1443 	port = mptsas_get_port(phy_info);
1444 	if (!port) {
1445 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1446 			"%s: fw_id=%d exit at line=%d\n", ioc->name,
1447 			 __func__, fw_id, __LINE__));
1448 		return 3;
1449 	}
1450 
1451 	if (phy_info->attached.device_info &
1452 	    MPI_SAS_DEVICE_INFO_SSP_TARGET)
1453 		ds = "ssp";
1454 	if (phy_info->attached.device_info &
1455 	    MPI_SAS_DEVICE_INFO_STP_TARGET)
1456 		ds = "stp";
1457 	if (phy_info->attached.device_info &
1458 	    MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1459 		ds = "sata";
1460 
1461 	printk(MYIOC_s_INFO_FMT "attaching %s device: fw_channel %d, fw_id %d,"
1462 	    " phy %d, sas_addr 0x%llx\n", ioc->name, ds,
1463 	    phy_info->attached.channel, phy_info->attached.id,
1464 	    phy_info->attached.phy_id, (unsigned long long)
1465 	    phy_info->attached.sas_address);
1466 
1467 	mptsas_parse_device_info(&identify, &phy_info->attached);
1468 	rphy = sas_end_device_alloc(port);
1469 	if (!rphy) {
1470 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1471 			"%s: fw_id=%d exit at line=%d\n", ioc->name,
1472 			 __func__, fw_id, __LINE__));
1473 		return 5; /* non-fatal: an rphy can be added later */
1474 	}
1475 
1476 	rphy->identify = identify;
1477 	if (sas_rphy_add(rphy)) {
1478 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1479 			"%s: fw_id=%d exit at line=%d\n", ioc->name,
1480 			 __func__, fw_id, __LINE__));
1481 		sas_rphy_free(rphy);
1482 		return 6;
1483 	}
1484 	mptsas_set_rphy(ioc, phy_info, rphy);
1485 	return 0;
1486 }
1487 
1488 /**
1489  *	mptsas_del_end_device - report a deleted end device to sas transport layer
1490  *	@ioc: Pointer to MPT_ADAPTER structure
1491  *	@phy_info: describes attached device
1492  *
1493  **/
1494 static void
1495 mptsas_del_end_device(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info)
1496 {
1497 	struct sas_rphy *rphy;
1498 	struct sas_port *port;
1499 	struct mptsas_portinfo *port_info;
1500 	struct mptsas_phyinfo *phy_info_parent;
1501 	int i;
1502 	char *ds = NULL;
1503 	u8 fw_id;
1504 	u64 sas_address;
1505 
1506 	if (!phy_info)
1507 		return;
1508 
1509 	fw_id = phy_info->attached.id;
1510 	sas_address = phy_info->attached.sas_address;
1511 
1512 	if (!phy_info->port_details) {
1513 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1514 			"%s: fw_id=%d exit at line=%d\n", ioc->name,
1515 			 __func__, fw_id, __LINE__));
1516 		return;
1517 	}
1518 	rphy = mptsas_get_rphy(phy_info);
1519 	if (!rphy) {
1520 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1521 			"%s: fw_id=%d exit at line=%d\n", ioc->name,
1522 			 __func__, fw_id, __LINE__));
1523 		return;
1524 	}
1525 
1526 	if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_INITIATOR
1527 		|| phy_info->attached.device_info
1528 			& MPI_SAS_DEVICE_INFO_SMP_INITIATOR
1529 		|| phy_info->attached.device_info
1530 			& MPI_SAS_DEVICE_INFO_STP_INITIATOR)
1531 		ds = "initiator";
1532 	if (phy_info->attached.device_info &
1533 	    MPI_SAS_DEVICE_INFO_SSP_TARGET)
1534 		ds = "ssp";
1535 	if (phy_info->attached.device_info &
1536 	    MPI_SAS_DEVICE_INFO_STP_TARGET)
1537 		ds = "stp";
1538 	if (phy_info->attached.device_info &
1539 	    MPI_SAS_DEVICE_INFO_SATA_DEVICE)
1540 		ds = "sata";
1541 
1542 	dev_printk(KERN_DEBUG, &rphy->dev, MYIOC_s_FMT
1543 	    "removing %s device: fw_channel %d, fw_id %d, phy %d,"
1544 	    "sas_addr 0x%llx\n", ioc->name, ds, phy_info->attached.channel,
1545 	    phy_info->attached.id, phy_info->attached.phy_id,
1546 	    (unsigned long long) sas_address);
1547 
1548 	port = mptsas_get_port(phy_info);
1549 	if (!port) {
1550 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
1551 			"%s: fw_id=%d exit at line=%d\n", ioc->name,
1552 			 __func__, fw_id, __LINE__));
1553 		return;
1554 	}
1555 	port_info = phy_info->portinfo;
1556 	phy_info_parent = port_info->phy_info;
1557 	for (i = 0; i < port_info->num_phys; i++, phy_info_parent++) {
1558 		if (!phy_info_parent->phy)
1559 			continue;
1560 		if (phy_info_parent->attached.sas_address !=
1561 		    sas_address)
1562 			continue;
1563 		dev_printk(KERN_DEBUG, &phy_info_parent->phy->dev,
1564 		    MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n",
1565 		    ioc->name, phy_info_parent->phy_id,
1566 		    phy_info_parent->phy);
1567 		sas_port_delete_phy(port, phy_info_parent->phy);
1568 	}
1569 
1570 	dev_printk(KERN_DEBUG, &port->dev, MYIOC_s_FMT
1571 	    "delete port %d, sas_addr (0x%llx)\n", ioc->name,
1572 	     port->port_identifier, (unsigned long long)sas_address);
1573 	sas_port_delete(port);
1574 	mptsas_set_port(ioc, phy_info, NULL);
1575 	mptsas_port_delete(ioc, phy_info->port_details);
1576 }
1577 
1578 struct mptsas_phyinfo *
1579 mptsas_refreshing_device_handles(MPT_ADAPTER *ioc,
1580 	struct mptsas_devinfo *sas_device)
1581 {
1582 	struct mptsas_phyinfo *phy_info;
1583 	struct mptsas_portinfo *port_info;
1584 	int i;
1585 
1586 	phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
1587 	    sas_device->sas_address);
1588 	if (!phy_info)
1589 		goto out;
1590 	port_info = phy_info->portinfo;
1591 	if (!port_info)
1592 		goto out;
1593 	mutex_lock(&ioc->sas_topology_mutex);
1594 	for (i = 0; i < port_info->num_phys; i++) {
1595 		if (port_info->phy_info[i].attached.sas_address !=
1596 			sas_device->sas_address)
1597 			continue;
1598 		port_info->phy_info[i].attached.channel = sas_device->channel;
1599 		port_info->phy_info[i].attached.id = sas_device->id;
1600 		port_info->phy_info[i].attached.sas_address =
1601 		    sas_device->sas_address;
1602 		port_info->phy_info[i].attached.handle = sas_device->handle;
1603 		port_info->phy_info[i].attached.handle_parent =
1604 		    sas_device->handle_parent;
1605 		port_info->phy_info[i].attached.handle_enclosure =
1606 		    sas_device->handle_enclosure;
1607 	}
1608 	mutex_unlock(&ioc->sas_topology_mutex);
1609  out:
1610 	return phy_info;
1611 }
1612 
1613 /**
1614  * mptsas_firmware_event_work - work thread for processing fw events
1615  * @work: work queue payload containing info describing the event
1616  * Context: user
1617  *
1618  */
1619 static void
1620 mptsas_firmware_event_work(struct work_struct *work)
1621 {
1622 	struct fw_event_work *fw_event =
1623 		container_of(work, struct fw_event_work, work.work);
1624 	MPT_ADAPTER *ioc = fw_event->ioc;
1625 
1626 	/* special rescan topology handling */
1627 	if (fw_event->event == -1) {
1628 		if (ioc->in_rescan) {
1629 			devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1630 				"%s: rescan ignored as it is in progress\n",
1631 				ioc->name, __func__));
1632 			return;
1633 		}
1634 		devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: rescan after "
1635 		    "reset\n", ioc->name, __func__));
1636 		ioc->in_rescan = 1;
1637 		mptsas_not_responding_devices(ioc);
1638 		mptsas_scan_sas_topology(ioc);
1639 		ioc->in_rescan = 0;
1640 		mptsas_free_fw_event(ioc, fw_event);
1641 		mptsas_fw_event_on(ioc);
1642 		return;
1643 	}
1644 
1645 	/* events handling turned off during host reset */
1646 	if (ioc->fw_events_off) {
1647 		mptsas_free_fw_event(ioc, fw_event);
1648 		return;
1649 	}
1650 
1651 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: fw_event=(0x%p), "
1652 	    "event = (0x%02x)\n", ioc->name, __func__, fw_event,
1653 	    (fw_event->event & 0xFF)));
1654 
1655 	switch (fw_event->event) {
1656 	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
1657 		mptsas_send_sas_event(fw_event);
1658 		break;
1659 	case MPI_EVENT_INTEGRATED_RAID:
1660 		mptsas_send_raid_event(fw_event);
1661 		break;
1662 	case MPI_EVENT_IR2:
1663 		mptsas_send_ir2_event(fw_event);
1664 		break;
1665 	case MPI_EVENT_PERSISTENT_TABLE_FULL:
1666 		mptbase_sas_persist_operation(ioc,
1667 		    MPI_SAS_OP_CLEAR_NOT_PRESENT);
1668 		mptsas_free_fw_event(ioc, fw_event);
1669 		break;
1670 	case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
1671 		mptsas_broadcast_primative_work(fw_event);
1672 		break;
1673 	case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
1674 		mptsas_send_expander_event(fw_event);
1675 		break;
1676 	case MPI_EVENT_SAS_PHY_LINK_STATUS:
1677 		mptsas_send_link_status_event(fw_event);
1678 		break;
1679 	case MPI_EVENT_QUEUE_FULL:
1680 		mptsas_handle_queue_full_event(fw_event);
1681 		break;
1682 	}
1683 }
1684 
1685 
1686 
1687 static int
1688 mptsas_slave_configure(struct scsi_device *sdev)
1689 {
1690 	struct Scsi_Host	*host = sdev->host;
1691 	MPT_SCSI_HOST	*hd = shost_priv(host);
1692 	MPT_ADAPTER	*ioc = hd->ioc;
1693 	VirtDevice	*vdevice = sdev->hostdata;
1694 
1695 	if (vdevice->vtarget->deleted) {
1696 		sdev_printk(KERN_INFO, sdev, "clearing deleted flag\n");
1697 		vdevice->vtarget->deleted = 0;
1698 	}
1699 
1700 	/*
1701 	 * RAID volumes placed beyond the last expected port.
1702 	 * Ignore sending sas mode pages in that case..
1703 	 */
1704 	if (sdev->channel == MPTSAS_RAID_CHANNEL) {
1705 		mptsas_add_device_component_starget_ir(ioc, scsi_target(sdev));
1706 		goto out;
1707 	}
1708 
1709 	sas_read_port_mode_page(sdev);
1710 
1711 	mptsas_add_device_component_starget(ioc, scsi_target(sdev));
1712 
1713  out:
1714 	return mptscsih_slave_configure(sdev);
1715 }
1716 
1717 static int
1718 mptsas_target_alloc(struct scsi_target *starget)
1719 {
1720 	struct Scsi_Host *host = dev_to_shost(&starget->dev);
1721 	MPT_SCSI_HOST		*hd = shost_priv(host);
1722 	VirtTarget		*vtarget;
1723 	u8			id, channel;
1724 	struct sas_rphy		*rphy;
1725 	struct mptsas_portinfo	*p;
1726 	int 			 i;
1727 	MPT_ADAPTER		*ioc = hd->ioc;
1728 
1729 	vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
1730 	if (!vtarget)
1731 		return -ENOMEM;
1732 
1733 	vtarget->starget = starget;
1734 	vtarget->ioc_id = ioc->id;
1735 	vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
1736 	id = starget->id;
1737 	channel = 0;
1738 
1739 	/*
1740 	 * RAID volumes placed beyond the last expected port.
1741 	 */
1742 	if (starget->channel == MPTSAS_RAID_CHANNEL) {
1743 		if (!ioc->raid_data.pIocPg2) {
1744 			kfree(vtarget);
1745 			return -ENXIO;
1746 		}
1747 		for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
1748 			if (id == ioc->raid_data.pIocPg2->
1749 					RaidVolume[i].VolumeID) {
1750 				channel = ioc->raid_data.pIocPg2->
1751 					RaidVolume[i].VolumeBus;
1752 			}
1753 		}
1754 		vtarget->raidVolume = 1;
1755 		goto out;
1756 	}
1757 
1758 	rphy = dev_to_rphy(starget->dev.parent);
1759 	mutex_lock(&ioc->sas_topology_mutex);
1760 	list_for_each_entry(p, &ioc->sas_topology, list) {
1761 		for (i = 0; i < p->num_phys; i++) {
1762 			if (p->phy_info[i].attached.sas_address !=
1763 					rphy->identify.sas_address)
1764 				continue;
1765 			id = p->phy_info[i].attached.id;
1766 			channel = p->phy_info[i].attached.channel;
1767 			mptsas_set_starget(&p->phy_info[i], starget);
1768 
1769 			/*
1770 			 * Exposing hidden raid components
1771 			 */
1772 			if (mptscsih_is_phys_disk(ioc, channel, id)) {
1773 				id = mptscsih_raid_id_to_num(ioc,
1774 						channel, id);
1775 				vtarget->tflags |=
1776 				    MPT_TARGET_FLAGS_RAID_COMPONENT;
1777 				p->phy_info[i].attached.phys_disk_num = id;
1778 			}
1779 			mutex_unlock(&ioc->sas_topology_mutex);
1780 			goto out;
1781 		}
1782 	}
1783 	mutex_unlock(&ioc->sas_topology_mutex);
1784 
1785 	kfree(vtarget);
1786 	return -ENXIO;
1787 
1788  out:
1789 	vtarget->id = id;
1790 	vtarget->channel = channel;
1791 	starget->hostdata = vtarget;
1792 	return 0;
1793 }
1794 
1795 static void
1796 mptsas_target_destroy(struct scsi_target *starget)
1797 {
1798 	struct Scsi_Host *host = dev_to_shost(&starget->dev);
1799 	MPT_SCSI_HOST		*hd = shost_priv(host);
1800 	struct sas_rphy		*rphy;
1801 	struct mptsas_portinfo	*p;
1802 	int 			 i;
1803 	MPT_ADAPTER	*ioc = hd->ioc;
1804 	VirtTarget	*vtarget;
1805 
1806 	if (!starget->hostdata)
1807 		return;
1808 
1809 	vtarget = starget->hostdata;
1810 
1811 	mptsas_del_device_component_by_os(ioc, starget->channel,
1812 	    starget->id);
1813 
1814 
1815 	if (starget->channel == MPTSAS_RAID_CHANNEL)
1816 		goto out;
1817 
1818 	rphy = dev_to_rphy(starget->dev.parent);
1819 	list_for_each_entry(p, &ioc->sas_topology, list) {
1820 		for (i = 0; i < p->num_phys; i++) {
1821 			if (p->phy_info[i].attached.sas_address !=
1822 					rphy->identify.sas_address)
1823 				continue;
1824 
1825 			starget_printk(KERN_INFO, starget, MYIOC_s_FMT
1826 			"delete device: fw_channel %d, fw_id %d, phy %d, "
1827 			"sas_addr 0x%llx\n", ioc->name,
1828 			p->phy_info[i].attached.channel,
1829 			p->phy_info[i].attached.id,
1830 			p->phy_info[i].attached.phy_id, (unsigned long long)
1831 			p->phy_info[i].attached.sas_address);
1832 
1833 			mptsas_set_starget(&p->phy_info[i], NULL);
1834 		}
1835 	}
1836 
1837  out:
1838 	vtarget->starget = NULL;
1839 	kfree(starget->hostdata);
1840 	starget->hostdata = NULL;
1841 }
1842 
1843 
1844 static int
1845 mptsas_slave_alloc(struct scsi_device *sdev)
1846 {
1847 	struct Scsi_Host	*host = sdev->host;
1848 	MPT_SCSI_HOST		*hd = shost_priv(host);
1849 	struct sas_rphy		*rphy;
1850 	struct mptsas_portinfo	*p;
1851 	VirtDevice		*vdevice;
1852 	struct scsi_target 	*starget;
1853 	int 			i;
1854 	MPT_ADAPTER *ioc = hd->ioc;
1855 
1856 	vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
1857 	if (!vdevice) {
1858 		printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",
1859 				ioc->name, sizeof(VirtDevice));
1860 		return -ENOMEM;
1861 	}
1862 	starget = scsi_target(sdev);
1863 	vdevice->vtarget = starget->hostdata;
1864 
1865 	if (sdev->channel == MPTSAS_RAID_CHANNEL)
1866 		goto out;
1867 
1868 	rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
1869 	mutex_lock(&ioc->sas_topology_mutex);
1870 	list_for_each_entry(p, &ioc->sas_topology, list) {
1871 		for (i = 0; i < p->num_phys; i++) {
1872 			if (p->phy_info[i].attached.sas_address !=
1873 					rphy->identify.sas_address)
1874 				continue;
1875 			vdevice->lun = sdev->lun;
1876 			/*
1877 			 * Exposing hidden raid components
1878 			 */
1879 			if (mptscsih_is_phys_disk(ioc,
1880 			    p->phy_info[i].attached.channel,
1881 			    p->phy_info[i].attached.id))
1882 				sdev->no_uld_attach = 1;
1883 			mutex_unlock(&ioc->sas_topology_mutex);
1884 			goto out;
1885 		}
1886 	}
1887 	mutex_unlock(&ioc->sas_topology_mutex);
1888 
1889 	kfree(vdevice);
1890 	return -ENXIO;
1891 
1892  out:
1893 	vdevice->vtarget->num_luns++;
1894 	sdev->hostdata = vdevice;
1895 	return 0;
1896 }
1897 
1898 static int
1899 mptsas_qcmd_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1900 {
1901 	MPT_SCSI_HOST	*hd;
1902 	MPT_ADAPTER	*ioc;
1903 	VirtDevice	*vdevice = SCpnt->device->hostdata;
1904 
1905 	if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
1906 		SCpnt->result = DID_NO_CONNECT << 16;
1907 		done(SCpnt);
1908 		return 0;
1909 	}
1910 
1911 	hd = shost_priv(SCpnt->device->host);
1912 	ioc = hd->ioc;
1913 
1914 	if (ioc->sas_discovery_quiesce_io)
1915 		return SCSI_MLQUEUE_HOST_BUSY;
1916 
1917 	if (ioc->debug_level & MPT_DEBUG_SCSI)
1918 		scsi_print_command(SCpnt);
1919 
1920 	return mptscsih_qcmd(SCpnt,done);
1921 }
1922 
1923 static DEF_SCSI_QCMD(mptsas_qcmd)
1924 
1925 /**
1926  *	mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout
1927  *		if the device under question is currently in the
1928  *		device removal delay.
1929  *	@sc: scsi command that the midlayer is about to time out
1930  *
1931  **/
1932 static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
1933 {
1934 	MPT_SCSI_HOST *hd;
1935 	MPT_ADAPTER   *ioc;
1936 	VirtDevice    *vdevice;
1937 	enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
1938 
1939 	hd = shost_priv(sc->device->host);
1940 	if (hd == NULL) {
1941 		printk(KERN_ERR MYNAM ": %s: Can't locate host! (sc=%p)\n",
1942 		    __func__, sc);
1943 		goto done;
1944 	}
1945 
1946 	ioc = hd->ioc;
1947 	if (ioc->bus_type != SAS) {
1948 		printk(KERN_ERR MYNAM ": %s: Wrong bus type (sc=%p)\n",
1949 		    __func__, sc);
1950 		goto done;
1951 	}
1952 
1953 	/* In case if IOC is in reset from internal context.
1954 	*  Do not execute EEH for the same IOC. SML should to reset timer.
1955 	*/
1956 	if (ioc->ioc_reset_in_progress) {
1957 		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: ioc is in reset,"
1958 		    "SML need to reset the timer (sc=%p)\n",
1959 		    ioc->name, __func__, sc));
1960 		rc = BLK_EH_RESET_TIMER;
1961 	}
1962 	vdevice = sc->device->hostdata;
1963 	if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD
1964 		|| vdevice->vtarget->deleted)) {
1965 		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: target removed "
1966 		    "or in device removal delay (sc=%p)\n",
1967 		    ioc->name, __func__, sc));
1968 		rc = BLK_EH_RESET_TIMER;
1969 		goto done;
1970 	}
1971 
1972 done:
1973 	return rc;
1974 }
1975 
1976 
1977 static struct scsi_host_template mptsas_driver_template = {
1978 	.module				= THIS_MODULE,
1979 	.proc_name			= "mptsas",
1980 	.proc_info			= mptscsih_proc_info,
1981 	.name				= "MPT SAS Host",
1982 	.info				= mptscsih_info,
1983 	.queuecommand			= mptsas_qcmd,
1984 	.target_alloc			= mptsas_target_alloc,
1985 	.slave_alloc			= mptsas_slave_alloc,
1986 	.slave_configure		= mptsas_slave_configure,
1987 	.target_destroy			= mptsas_target_destroy,
1988 	.slave_destroy			= mptscsih_slave_destroy,
1989 	.change_queue_depth 		= mptscsih_change_queue_depth,
1990 	.eh_abort_handler		= mptscsih_abort,
1991 	.eh_device_reset_handler	= mptscsih_dev_reset,
1992 	.eh_host_reset_handler		= mptscsih_host_reset,
1993 	.bios_param			= mptscsih_bios_param,
1994 	.can_queue			= MPT_SAS_CAN_QUEUE,
1995 	.this_id			= -1,
1996 	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
1997 	.max_sectors			= 8192,
1998 	.cmd_per_lun			= 7,
1999 	.use_clustering			= ENABLE_CLUSTERING,
2000 	.shost_attrs			= mptscsih_host_attrs,
2001 };
2002 
2003 static int mptsas_get_linkerrors(struct sas_phy *phy)
2004 {
2005 	MPT_ADAPTER *ioc = phy_to_ioc(phy);
2006 	ConfigExtendedPageHeader_t hdr;
2007 	CONFIGPARMS cfg;
2008 	SasPhyPage1_t *buffer;
2009 	dma_addr_t dma_handle;
2010 	int error;
2011 
2012 	/* FIXME: only have link errors on local phys */
2013 	if (!scsi_is_sas_phy_local(phy))
2014 		return -EINVAL;
2015 
2016 	hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
2017 	hdr.ExtPageLength = 0;
2018 	hdr.PageNumber = 1 /* page number 1*/;
2019 	hdr.Reserved1 = 0;
2020 	hdr.Reserved2 = 0;
2021 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2022 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2023 
2024 	cfg.cfghdr.ehdr = &hdr;
2025 	cfg.physAddr = -1;
2026 	cfg.pageAddr = phy->identify.phy_identifier;
2027 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2028 	cfg.dir = 0;    /* read */
2029 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2030 
2031 	error = mpt_config(ioc, &cfg);
2032 	if (error)
2033 		return error;
2034 	if (!hdr.ExtPageLength)
2035 		return -ENXIO;
2036 
2037 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2038 				      &dma_handle);
2039 	if (!buffer)
2040 		return -ENOMEM;
2041 
2042 	cfg.physAddr = dma_handle;
2043 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2044 
2045 	error = mpt_config(ioc, &cfg);
2046 	if (error)
2047 		goto out_free_consistent;
2048 
2049 	mptsas_print_phy_pg1(ioc, buffer);
2050 
2051 	phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
2052 	phy->running_disparity_error_count =
2053 		le32_to_cpu(buffer->RunningDisparityErrorCount);
2054 	phy->loss_of_dword_sync_count =
2055 		le32_to_cpu(buffer->LossDwordSynchCount);
2056 	phy->phy_reset_problem_count =
2057 		le32_to_cpu(buffer->PhyResetProblemCount);
2058 
2059  out_free_consistent:
2060 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2061 			    buffer, dma_handle);
2062 	return error;
2063 }
2064 
2065 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2066 		MPT_FRAME_HDR *reply)
2067 {
2068 	ioc->sas_mgmt.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2069 	if (reply != NULL) {
2070 		ioc->sas_mgmt.status |= MPT_MGMT_STATUS_RF_VALID;
2071 		memcpy(ioc->sas_mgmt.reply, reply,
2072 		    min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
2073 	}
2074 
2075 	if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
2076 		ioc->sas_mgmt.status &= ~MPT_MGMT_STATUS_PENDING;
2077 		complete(&ioc->sas_mgmt.done);
2078 		return 1;
2079 	}
2080 	return 0;
2081 }
2082 
2083 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
2084 {
2085 	MPT_ADAPTER *ioc = phy_to_ioc(phy);
2086 	SasIoUnitControlRequest_t *req;
2087 	SasIoUnitControlReply_t *reply;
2088 	MPT_FRAME_HDR *mf;
2089 	MPIHeader_t *hdr;
2090 	unsigned long timeleft;
2091 	int error = -ERESTARTSYS;
2092 
2093 	/* FIXME: fusion doesn't allow non-local phy reset */
2094 	if (!scsi_is_sas_phy_local(phy))
2095 		return -EINVAL;
2096 
2097 	/* not implemented for expanders */
2098 	if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
2099 		return -ENXIO;
2100 
2101 	if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
2102 		goto out;
2103 
2104 	mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2105 	if (!mf) {
2106 		error = -ENOMEM;
2107 		goto out_unlock;
2108 	}
2109 
2110 	hdr = (MPIHeader_t *) mf;
2111 	req = (SasIoUnitControlRequest_t *)mf;
2112 	memset(req, 0, sizeof(SasIoUnitControlRequest_t));
2113 	req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
2114 	req->MsgContext = hdr->MsgContext;
2115 	req->Operation = hard_reset ?
2116 		MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
2117 	req->PhyNum = phy->identify.phy_identifier;
2118 
2119 	INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2120 	mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2121 
2122 	timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
2123 			10 * HZ);
2124 	if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2125 		error = -ETIME;
2126 		mpt_free_msg_frame(ioc, mf);
2127 		if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2128 			goto out_unlock;
2129 		if (!timeleft)
2130 			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2131 		goto out_unlock;
2132 	}
2133 
2134 	/* a reply frame is expected */
2135 	if ((ioc->sas_mgmt.status &
2136 	    MPT_MGMT_STATUS_RF_VALID) == 0) {
2137 		error = -ENXIO;
2138 		goto out_unlock;
2139 	}
2140 
2141 	/* process the completed Reply Message Frame */
2142 	reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
2143 	if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
2144 		printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
2145 		    ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
2146 		error = -ENXIO;
2147 		goto out_unlock;
2148 	}
2149 
2150 	error = 0;
2151 
2152  out_unlock:
2153 	CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2154 	mutex_unlock(&ioc->sas_mgmt.mutex);
2155  out:
2156 	return error;
2157 }
2158 
2159 static int
2160 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
2161 {
2162 	MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2163 	int i, error;
2164 	struct mptsas_portinfo *p;
2165 	struct mptsas_enclosure enclosure_info;
2166 	u64 enclosure_handle;
2167 
2168 	mutex_lock(&ioc->sas_topology_mutex);
2169 	list_for_each_entry(p, &ioc->sas_topology, list) {
2170 		for (i = 0; i < p->num_phys; i++) {
2171 			if (p->phy_info[i].attached.sas_address ==
2172 			    rphy->identify.sas_address) {
2173 				enclosure_handle = p->phy_info[i].
2174 					attached.handle_enclosure;
2175 				goto found_info;
2176 			}
2177 		}
2178 	}
2179 	mutex_unlock(&ioc->sas_topology_mutex);
2180 	return -ENXIO;
2181 
2182  found_info:
2183 	mutex_unlock(&ioc->sas_topology_mutex);
2184 	memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
2185 	error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
2186 			(MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
2187 			 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
2188 	if (!error)
2189 		*identifier = enclosure_info.enclosure_logical_id;
2190 	return error;
2191 }
2192 
2193 static int
2194 mptsas_get_bay_identifier(struct sas_rphy *rphy)
2195 {
2196 	MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2197 	struct mptsas_portinfo *p;
2198 	int i, rc;
2199 
2200 	mutex_lock(&ioc->sas_topology_mutex);
2201 	list_for_each_entry(p, &ioc->sas_topology, list) {
2202 		for (i = 0; i < p->num_phys; i++) {
2203 			if (p->phy_info[i].attached.sas_address ==
2204 			    rphy->identify.sas_address) {
2205 				rc = p->phy_info[i].attached.slot;
2206 				goto out;
2207 			}
2208 		}
2209 	}
2210 	rc = -ENXIO;
2211  out:
2212 	mutex_unlock(&ioc->sas_topology_mutex);
2213 	return rc;
2214 }
2215 
2216 static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
2217 			      struct request *req)
2218 {
2219 	MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
2220 	MPT_FRAME_HDR *mf;
2221 	SmpPassthroughRequest_t *smpreq;
2222 	struct request *rsp = req->next_rq;
2223 	int ret;
2224 	int flagsLength;
2225 	unsigned long timeleft;
2226 	char *psge;
2227 	dma_addr_t dma_addr_in = 0;
2228 	dma_addr_t dma_addr_out = 0;
2229 	u64 sas_address = 0;
2230 
2231 	if (!rsp) {
2232 		printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
2233 		    ioc->name, __func__);
2234 		return -EINVAL;
2235 	}
2236 
2237 	/* do we need to support multiple segments? */
2238 	if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
2239 		printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
2240 		    ioc->name, __func__, req->bio->bi_vcnt, blk_rq_bytes(req),
2241 		    rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
2242 		return -EINVAL;
2243 	}
2244 
2245 	ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2246 	if (ret)
2247 		goto out;
2248 
2249 	mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2250 	if (!mf) {
2251 		ret = -ENOMEM;
2252 		goto out_unlock;
2253 	}
2254 
2255 	smpreq = (SmpPassthroughRequest_t *)mf;
2256 	memset(smpreq, 0, sizeof(*smpreq));
2257 
2258 	smpreq->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
2259 	smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2260 
2261 	if (rphy)
2262 		sas_address = rphy->identify.sas_address;
2263 	else {
2264 		struct mptsas_portinfo *port_info;
2265 
2266 		mutex_lock(&ioc->sas_topology_mutex);
2267 		port_info = ioc->hba_port_info;
2268 		if (port_info && port_info->phy_info)
2269 			sas_address =
2270 				port_info->phy_info[0].phy->identify.sas_address;
2271 		mutex_unlock(&ioc->sas_topology_mutex);
2272 	}
2273 
2274 	*((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2275 
2276 	psge = (char *)
2277 		(((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2278 
2279 	/* request */
2280 	flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2281 		       MPI_SGE_FLAGS_END_OF_BUFFER |
2282 		       MPI_SGE_FLAGS_DIRECTION)
2283 		       << MPI_SGE_FLAGS_SHIFT;
2284 	flagsLength |= (blk_rq_bytes(req) - 4);
2285 
2286 	dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
2287 				      blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
2288 	if (!dma_addr_out)
2289 		goto put_mf;
2290 	ioc->add_sge(psge, flagsLength, dma_addr_out);
2291 	psge += ioc->SGE_size;
2292 
2293 	/* response */
2294 	flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2295 		MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2296 		MPI_SGE_FLAGS_IOC_TO_HOST |
2297 		MPI_SGE_FLAGS_END_OF_BUFFER;
2298 
2299 	flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2300 	flagsLength |= blk_rq_bytes(rsp) + 4;
2301 	dma_addr_in =  pci_map_single(ioc->pcidev, bio_data(rsp->bio),
2302 				      blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
2303 	if (!dma_addr_in)
2304 		goto unmap;
2305 	ioc->add_sge(psge, flagsLength, dma_addr_in);
2306 
2307 	INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2308 	mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2309 
2310 	timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2311 	if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2312 		ret = -ETIME;
2313 		mpt_free_msg_frame(ioc, mf);
2314 		mf = NULL;
2315 		if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2316 			goto unmap;
2317 		if (!timeleft)
2318 			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2319 		goto unmap;
2320 	}
2321 	mf = NULL;
2322 
2323 	if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2324 		SmpPassthroughReply_t *smprep;
2325 
2326 		smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2327 		memcpy(req->sense, smprep, sizeof(*smprep));
2328 		req->sense_len = sizeof(*smprep);
2329 		req->resid_len = 0;
2330 		rsp->resid_len -= smprep->ResponseDataLength;
2331 	} else {
2332 		printk(MYIOC_s_ERR_FMT
2333 		    "%s: smp passthru reply failed to be returned\n",
2334 		    ioc->name, __func__);
2335 		ret = -ENXIO;
2336 	}
2337 unmap:
2338 	if (dma_addr_out)
2339 		pci_unmap_single(ioc->pcidev, dma_addr_out, blk_rq_bytes(req),
2340 				 PCI_DMA_BIDIRECTIONAL);
2341 	if (dma_addr_in)
2342 		pci_unmap_single(ioc->pcidev, dma_addr_in, blk_rq_bytes(rsp),
2343 				 PCI_DMA_BIDIRECTIONAL);
2344 put_mf:
2345 	if (mf)
2346 		mpt_free_msg_frame(ioc, mf);
2347 out_unlock:
2348 	CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2349 	mutex_unlock(&ioc->sas_mgmt.mutex);
2350 out:
2351 	return ret;
2352 }
2353 
2354 static struct sas_function_template mptsas_transport_functions = {
2355 	.get_linkerrors		= mptsas_get_linkerrors,
2356 	.get_enclosure_identifier = mptsas_get_enclosure_identifier,
2357 	.get_bay_identifier	= mptsas_get_bay_identifier,
2358 	.phy_reset		= mptsas_phy_reset,
2359 	.smp_handler		= mptsas_smp_handler,
2360 };
2361 
2362 static struct scsi_transport_template *mptsas_transport_template;
2363 
2364 static int
2365 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2366 {
2367 	ConfigExtendedPageHeader_t hdr;
2368 	CONFIGPARMS cfg;
2369 	SasIOUnitPage0_t *buffer;
2370 	dma_addr_t dma_handle;
2371 	int error, i;
2372 
2373 	hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
2374 	hdr.ExtPageLength = 0;
2375 	hdr.PageNumber = 0;
2376 	hdr.Reserved1 = 0;
2377 	hdr.Reserved2 = 0;
2378 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2379 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2380 
2381 	cfg.cfghdr.ehdr = &hdr;
2382 	cfg.physAddr = -1;
2383 	cfg.pageAddr = 0;
2384 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2385 	cfg.dir = 0;	/* read */
2386 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2387 
2388 	error = mpt_config(ioc, &cfg);
2389 	if (error)
2390 		goto out;
2391 	if (!hdr.ExtPageLength) {
2392 		error = -ENXIO;
2393 		goto out;
2394 	}
2395 
2396 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2397 					    &dma_handle);
2398 	if (!buffer) {
2399 		error = -ENOMEM;
2400 		goto out;
2401 	}
2402 
2403 	cfg.physAddr = dma_handle;
2404 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2405 
2406 	error = mpt_config(ioc, &cfg);
2407 	if (error)
2408 		goto out_free_consistent;
2409 
2410 	port_info->num_phys = buffer->NumPhys;
2411 	port_info->phy_info = kcalloc(port_info->num_phys,
2412 		sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2413 	if (!port_info->phy_info) {
2414 		error = -ENOMEM;
2415 		goto out_free_consistent;
2416 	}
2417 
2418 	ioc->nvdata_version_persistent =
2419 	    le16_to_cpu(buffer->NvdataVersionPersistent);
2420 	ioc->nvdata_version_default =
2421 	    le16_to_cpu(buffer->NvdataVersionDefault);
2422 
2423 	for (i = 0; i < port_info->num_phys; i++) {
2424 		mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
2425 		port_info->phy_info[i].phy_id = i;
2426 		port_info->phy_info[i].port_id =
2427 		    buffer->PhyData[i].Port;
2428 		port_info->phy_info[i].negotiated_link_rate =
2429 		    buffer->PhyData[i].NegotiatedLinkRate;
2430 		port_info->phy_info[i].portinfo = port_info;
2431 		port_info->phy_info[i].handle =
2432 		    le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
2433 	}
2434 
2435  out_free_consistent:
2436 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2437 			    buffer, dma_handle);
2438  out:
2439 	return error;
2440 }
2441 
2442 static int
2443 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
2444 {
2445 	ConfigExtendedPageHeader_t hdr;
2446 	CONFIGPARMS cfg;
2447 	SasIOUnitPage1_t *buffer;
2448 	dma_addr_t dma_handle;
2449 	int error;
2450 	u8 device_missing_delay;
2451 
2452 	memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
2453 	memset(&cfg, 0, sizeof(CONFIGPARMS));
2454 
2455 	cfg.cfghdr.ehdr = &hdr;
2456 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2457 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2458 	cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2459 	cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2460 	cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
2461 	cfg.cfghdr.ehdr->PageNumber = 1;
2462 
2463 	error = mpt_config(ioc, &cfg);
2464 	if (error)
2465 		goto out;
2466 	if (!hdr.ExtPageLength) {
2467 		error = -ENXIO;
2468 		goto out;
2469 	}
2470 
2471 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2472 					    &dma_handle);
2473 	if (!buffer) {
2474 		error = -ENOMEM;
2475 		goto out;
2476 	}
2477 
2478 	cfg.physAddr = dma_handle;
2479 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2480 
2481 	error = mpt_config(ioc, &cfg);
2482 	if (error)
2483 		goto out_free_consistent;
2484 
2485 	ioc->io_missing_delay  =
2486 	    le16_to_cpu(buffer->IODeviceMissingDelay);
2487 	device_missing_delay = buffer->ReportDeviceMissingDelay;
2488 	ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
2489 	    (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
2490 	    device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
2491 
2492  out_free_consistent:
2493 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2494 			    buffer, dma_handle);
2495  out:
2496 	return error;
2497 }
2498 
2499 static int
2500 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2501 		u32 form, u32 form_specific)
2502 {
2503 	ConfigExtendedPageHeader_t hdr;
2504 	CONFIGPARMS cfg;
2505 	SasPhyPage0_t *buffer;
2506 	dma_addr_t dma_handle;
2507 	int error;
2508 
2509 	hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
2510 	hdr.ExtPageLength = 0;
2511 	hdr.PageNumber = 0;
2512 	hdr.Reserved1 = 0;
2513 	hdr.Reserved2 = 0;
2514 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2515 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2516 
2517 	cfg.cfghdr.ehdr = &hdr;
2518 	cfg.dir = 0;	/* read */
2519 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2520 
2521 	/* Get Phy Pg 0 for each Phy. */
2522 	cfg.physAddr = -1;
2523 	cfg.pageAddr = form + form_specific;
2524 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2525 
2526 	error = mpt_config(ioc, &cfg);
2527 	if (error)
2528 		goto out;
2529 
2530 	if (!hdr.ExtPageLength) {
2531 		error = -ENXIO;
2532 		goto out;
2533 	}
2534 
2535 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2536 				      &dma_handle);
2537 	if (!buffer) {
2538 		error = -ENOMEM;
2539 		goto out;
2540 	}
2541 
2542 	cfg.physAddr = dma_handle;
2543 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2544 
2545 	error = mpt_config(ioc, &cfg);
2546 	if (error)
2547 		goto out_free_consistent;
2548 
2549 	mptsas_print_phy_pg0(ioc, buffer);
2550 
2551 	phy_info->hw_link_rate = buffer->HwLinkRate;
2552 	phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2553 	phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2554 	phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2555 
2556  out_free_consistent:
2557 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2558 			    buffer, dma_handle);
2559  out:
2560 	return error;
2561 }
2562 
2563 static int
2564 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2565 		u32 form, u32 form_specific)
2566 {
2567 	ConfigExtendedPageHeader_t hdr;
2568 	CONFIGPARMS cfg;
2569 	SasDevicePage0_t *buffer;
2570 	dma_addr_t dma_handle;
2571 	__le64 sas_address;
2572 	int error=0;
2573 
2574 	hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2575 	hdr.ExtPageLength = 0;
2576 	hdr.PageNumber = 0;
2577 	hdr.Reserved1 = 0;
2578 	hdr.Reserved2 = 0;
2579 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2580 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
2581 
2582 	cfg.cfghdr.ehdr = &hdr;
2583 	cfg.pageAddr = form + form_specific;
2584 	cfg.physAddr = -1;
2585 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2586 	cfg.dir = 0;	/* read */
2587 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2588 
2589 	memset(device_info, 0, sizeof(struct mptsas_devinfo));
2590 	error = mpt_config(ioc, &cfg);
2591 	if (error)
2592 		goto out;
2593 	if (!hdr.ExtPageLength) {
2594 		error = -ENXIO;
2595 		goto out;
2596 	}
2597 
2598 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2599 				      &dma_handle);
2600 	if (!buffer) {
2601 		error = -ENOMEM;
2602 		goto out;
2603 	}
2604 
2605 	cfg.physAddr = dma_handle;
2606 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2607 
2608 	error = mpt_config(ioc, &cfg);
2609 
2610 	if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2611 		error = -ENODEV;
2612 		goto out_free_consistent;
2613 	}
2614 
2615 	if (error)
2616 		goto out_free_consistent;
2617 
2618 	mptsas_print_device_pg0(ioc, buffer);
2619 
2620 	memset(device_info, 0, sizeof(struct mptsas_devinfo));
2621 	device_info->handle = le16_to_cpu(buffer->DevHandle);
2622 	device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2623 	device_info->handle_enclosure =
2624 	    le16_to_cpu(buffer->EnclosureHandle);
2625 	device_info->slot = le16_to_cpu(buffer->Slot);
2626 	device_info->phy_id = buffer->PhyNum;
2627 	device_info->port_id = buffer->PhysicalPort;
2628 	device_info->id = buffer->TargetID;
2629 	device_info->phys_disk_num = ~0;
2630 	device_info->channel = buffer->Bus;
2631 	memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2632 	device_info->sas_address = le64_to_cpu(sas_address);
2633 	device_info->device_info =
2634 	    le32_to_cpu(buffer->DeviceInfo);
2635 	device_info->flags = le16_to_cpu(buffer->Flags);
2636 
2637  out_free_consistent:
2638 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2639 			    buffer, dma_handle);
2640  out:
2641 	return error;
2642 }
2643 
2644 static int
2645 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2646 		u32 form, u32 form_specific)
2647 {
2648 	ConfigExtendedPageHeader_t hdr;
2649 	CONFIGPARMS cfg;
2650 	SasExpanderPage0_t *buffer;
2651 	dma_addr_t dma_handle;
2652 	int i, error;
2653 	__le64 sas_address;
2654 
2655 	memset(port_info, 0, sizeof(struct mptsas_portinfo));
2656 	hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2657 	hdr.ExtPageLength = 0;
2658 	hdr.PageNumber = 0;
2659 	hdr.Reserved1 = 0;
2660 	hdr.Reserved2 = 0;
2661 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2662 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2663 
2664 	cfg.cfghdr.ehdr = &hdr;
2665 	cfg.physAddr = -1;
2666 	cfg.pageAddr = form + form_specific;
2667 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2668 	cfg.dir = 0;	/* read */
2669 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2670 
2671 	memset(port_info, 0, sizeof(struct mptsas_portinfo));
2672 	error = mpt_config(ioc, &cfg);
2673 	if (error)
2674 		goto out;
2675 
2676 	if (!hdr.ExtPageLength) {
2677 		error = -ENXIO;
2678 		goto out;
2679 	}
2680 
2681 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2682 				      &dma_handle);
2683 	if (!buffer) {
2684 		error = -ENOMEM;
2685 		goto out;
2686 	}
2687 
2688 	cfg.physAddr = dma_handle;
2689 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2690 
2691 	error = mpt_config(ioc, &cfg);
2692 	if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2693 		error = -ENODEV;
2694 		goto out_free_consistent;
2695 	}
2696 
2697 	if (error)
2698 		goto out_free_consistent;
2699 
2700 	/* save config data */
2701 	port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
2702 	port_info->phy_info = kcalloc(port_info->num_phys,
2703 		sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2704 	if (!port_info->phy_info) {
2705 		error = -ENOMEM;
2706 		goto out_free_consistent;
2707 	}
2708 
2709 	memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2710 	for (i = 0; i < port_info->num_phys; i++) {
2711 		port_info->phy_info[i].portinfo = port_info;
2712 		port_info->phy_info[i].handle =
2713 		    le16_to_cpu(buffer->DevHandle);
2714 		port_info->phy_info[i].identify.sas_address =
2715 		    le64_to_cpu(sas_address);
2716 		port_info->phy_info[i].identify.handle_parent =
2717 		    le16_to_cpu(buffer->ParentDevHandle);
2718 	}
2719 
2720  out_free_consistent:
2721 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2722 			    buffer, dma_handle);
2723  out:
2724 	return error;
2725 }
2726 
2727 static int
2728 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2729 		u32 form, u32 form_specific)
2730 {
2731 	ConfigExtendedPageHeader_t hdr;
2732 	CONFIGPARMS cfg;
2733 	SasExpanderPage1_t *buffer;
2734 	dma_addr_t dma_handle;
2735 	int error=0;
2736 
2737 	hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
2738 	hdr.ExtPageLength = 0;
2739 	hdr.PageNumber = 1;
2740 	hdr.Reserved1 = 0;
2741 	hdr.Reserved2 = 0;
2742 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2743 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2744 
2745 	cfg.cfghdr.ehdr = &hdr;
2746 	cfg.physAddr = -1;
2747 	cfg.pageAddr = form + form_specific;
2748 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2749 	cfg.dir = 0;	/* read */
2750 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2751 
2752 	error = mpt_config(ioc, &cfg);
2753 	if (error)
2754 		goto out;
2755 
2756 	if (!hdr.ExtPageLength) {
2757 		error = -ENXIO;
2758 		goto out;
2759 	}
2760 
2761 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2762 				      &dma_handle);
2763 	if (!buffer) {
2764 		error = -ENOMEM;
2765 		goto out;
2766 	}
2767 
2768 	cfg.physAddr = dma_handle;
2769 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2770 
2771 	error = mpt_config(ioc, &cfg);
2772 
2773 	if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2774 		error = -ENODEV;
2775 		goto out_free_consistent;
2776 	}
2777 
2778 	if (error)
2779 		goto out_free_consistent;
2780 
2781 
2782 	mptsas_print_expander_pg1(ioc, buffer);
2783 
2784 	/* save config data */
2785 	phy_info->phy_id = buffer->PhyIdentifier;
2786 	phy_info->port_id = buffer->PhysicalPort;
2787 	phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
2788 	phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2789 	phy_info->hw_link_rate = buffer->HwLinkRate;
2790 	phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2791 	phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2792 
2793  out_free_consistent:
2794 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2795 			    buffer, dma_handle);
2796  out:
2797 	return error;
2798 }
2799 
2800 struct rep_manu_request{
2801 	u8 smp_frame_type;
2802 	u8 function;
2803 	u8 reserved;
2804 	u8 request_length;
2805 };
2806 
2807 struct rep_manu_reply{
2808 	u8 smp_frame_type; /* 0x41 */
2809 	u8 function; /* 0x01 */
2810 	u8 function_result;
2811 	u8 response_length;
2812 	u16 expander_change_count;
2813 	u8 reserved0[2];
2814 	u8 sas_format:1;
2815 	u8 reserved1:7;
2816 	u8 reserved2[3];
2817 	u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
2818 	u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
2819 	u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
2820 	u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
2821 	u16 component_id;
2822 	u8 component_revision_id;
2823 	u8 reserved3;
2824 	u8 vendor_specific[8];
2825 };
2826 
2827 /**
2828   * mptsas_exp_repmanufacture_info -
2829   * @ioc: per adapter object
2830   * @sas_address: expander sas address
2831   * @edev: the sas_expander_device object
2832   *
2833   * Fills in the sas_expander_device object when SMP port is created.
2834   *
2835   * Returns 0 for success, non-zero for failure.
2836   */
2837 static int
2838 mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
2839 	u64 sas_address, struct sas_expander_device *edev)
2840 {
2841 	MPT_FRAME_HDR *mf;
2842 	SmpPassthroughRequest_t *smpreq;
2843 	SmpPassthroughReply_t *smprep;
2844 	struct rep_manu_reply *manufacture_reply;
2845 	struct rep_manu_request *manufacture_request;
2846 	int ret;
2847 	int flagsLength;
2848 	unsigned long timeleft;
2849 	char *psge;
2850 	unsigned long flags;
2851 	void *data_out = NULL;
2852 	dma_addr_t data_out_dma = 0;
2853 	u32 sz;
2854 
2855 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2856 	if (ioc->ioc_reset_in_progress) {
2857 		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2858 		printk(MYIOC_s_INFO_FMT "%s: host reset in progress!\n",
2859 			__func__, ioc->name);
2860 		return -EFAULT;
2861 	}
2862 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2863 
2864 	ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2865 	if (ret)
2866 		goto out;
2867 
2868 	mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2869 	if (!mf) {
2870 		ret = -ENOMEM;
2871 		goto out_unlock;
2872 	}
2873 
2874 	smpreq = (SmpPassthroughRequest_t *)mf;
2875 	memset(smpreq, 0, sizeof(*smpreq));
2876 
2877 	sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
2878 
2879 	data_out = pci_alloc_consistent(ioc->pcidev, sz, &data_out_dma);
2880 	if (!data_out) {
2881 		printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
2882 			__FILE__, __LINE__, __func__);
2883 		ret = -ENOMEM;
2884 		goto put_mf;
2885 	}
2886 
2887 	manufacture_request = data_out;
2888 	manufacture_request->smp_frame_type = 0x40;
2889 	manufacture_request->function = 1;
2890 	manufacture_request->reserved = 0;
2891 	manufacture_request->request_length = 0;
2892 
2893 	smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2894 	smpreq->PhysicalPort = 0xFF;
2895 	*((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2896 	smpreq->RequestDataLength = sizeof(struct rep_manu_request);
2897 
2898 	psge = (char *)
2899 		(((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2900 
2901 	flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2902 		MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2903 		MPI_SGE_FLAGS_HOST_TO_IOC |
2904 		MPI_SGE_FLAGS_END_OF_BUFFER;
2905 	flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2906 	flagsLength |= sizeof(struct rep_manu_request);
2907 
2908 	ioc->add_sge(psge, flagsLength, data_out_dma);
2909 	psge += ioc->SGE_size;
2910 
2911 	flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2912 		MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2913 		MPI_SGE_FLAGS_IOC_TO_HOST |
2914 		MPI_SGE_FLAGS_END_OF_BUFFER;
2915 	flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2916 	flagsLength |= sizeof(struct rep_manu_reply);
2917 	ioc->add_sge(psge, flagsLength, data_out_dma +
2918 	sizeof(struct rep_manu_request));
2919 
2920 	INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2921 	mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2922 
2923 	timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2924 	if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2925 		ret = -ETIME;
2926 		mpt_free_msg_frame(ioc, mf);
2927 		mf = NULL;
2928 		if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2929 			goto out_free;
2930 		if (!timeleft)
2931 			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2932 		goto out_free;
2933 	}
2934 
2935 	mf = NULL;
2936 
2937 	if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2938 		u8 *tmp;
2939 
2940 	smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2941 	if (le16_to_cpu(smprep->ResponseDataLength) !=
2942 		sizeof(struct rep_manu_reply))
2943 			goto out_free;
2944 
2945 	manufacture_reply = data_out + sizeof(struct rep_manu_request);
2946 	strncpy(edev->vendor_id, manufacture_reply->vendor_id,
2947 		SAS_EXPANDER_VENDOR_ID_LEN);
2948 	strncpy(edev->product_id, manufacture_reply->product_id,
2949 		SAS_EXPANDER_PRODUCT_ID_LEN);
2950 	strncpy(edev->product_rev, manufacture_reply->product_rev,
2951 		SAS_EXPANDER_PRODUCT_REV_LEN);
2952 	edev->level = manufacture_reply->sas_format;
2953 	if (manufacture_reply->sas_format) {
2954 		strncpy(edev->component_vendor_id,
2955 			manufacture_reply->component_vendor_id,
2956 				SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
2957 		tmp = (u8 *)&manufacture_reply->component_id;
2958 		edev->component_id = tmp[0] << 8 | tmp[1];
2959 		edev->component_revision_id =
2960 			manufacture_reply->component_revision_id;
2961 		}
2962 	} else {
2963 		printk(MYIOC_s_ERR_FMT
2964 			"%s: smp passthru reply failed to be returned\n",
2965 			ioc->name, __func__);
2966 		ret = -ENXIO;
2967 	}
2968 out_free:
2969 	if (data_out_dma)
2970 		pci_free_consistent(ioc->pcidev, sz, data_out, data_out_dma);
2971 put_mf:
2972 	if (mf)
2973 		mpt_free_msg_frame(ioc, mf);
2974 out_unlock:
2975 	CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2976 	mutex_unlock(&ioc->sas_mgmt.mutex);
2977 out:
2978 	return ret;
2979  }
2980 
2981 static void
2982 mptsas_parse_device_info(struct sas_identify *identify,
2983 		struct mptsas_devinfo *device_info)
2984 {
2985 	u16 protocols;
2986 
2987 	identify->sas_address = device_info->sas_address;
2988 	identify->phy_identifier = device_info->phy_id;
2989 
2990 	/*
2991 	 * Fill in Phy Initiator Port Protocol.
2992 	 * Bits 6:3, more than one bit can be set, fall through cases.
2993 	 */
2994 	protocols = device_info->device_info & 0x78;
2995 	identify->initiator_port_protocols = 0;
2996 	if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
2997 		identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
2998 	if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
2999 		identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
3000 	if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
3001 		identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
3002 	if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
3003 		identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
3004 
3005 	/*
3006 	 * Fill in Phy Target Port Protocol.
3007 	 * Bits 10:7, more than one bit can be set, fall through cases.
3008 	 */
3009 	protocols = device_info->device_info & 0x780;
3010 	identify->target_port_protocols = 0;
3011 	if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
3012 		identify->target_port_protocols |= SAS_PROTOCOL_SSP;
3013 	if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
3014 		identify->target_port_protocols |= SAS_PROTOCOL_STP;
3015 	if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
3016 		identify->target_port_protocols |= SAS_PROTOCOL_SMP;
3017 	if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
3018 		identify->target_port_protocols |= SAS_PROTOCOL_SATA;
3019 
3020 	/*
3021 	 * Fill in Attached device type.
3022 	 */
3023 	switch (device_info->device_info &
3024 			MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
3025 	case MPI_SAS_DEVICE_INFO_NO_DEVICE:
3026 		identify->device_type = SAS_PHY_UNUSED;
3027 		break;
3028 	case MPI_SAS_DEVICE_INFO_END_DEVICE:
3029 		identify->device_type = SAS_END_DEVICE;
3030 		break;
3031 	case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
3032 		identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
3033 		break;
3034 	case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
3035 		identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
3036 		break;
3037 	}
3038 }
3039 
3040 static int mptsas_probe_one_phy(struct device *dev,
3041 		struct mptsas_phyinfo *phy_info, int index, int local)
3042 {
3043 	MPT_ADAPTER *ioc;
3044 	struct sas_phy *phy;
3045 	struct sas_port *port;
3046 	int error = 0;
3047 	VirtTarget *vtarget;
3048 
3049 	if (!dev) {
3050 		error = -ENODEV;
3051 		goto out;
3052 	}
3053 
3054 	if (!phy_info->phy) {
3055 		phy = sas_phy_alloc(dev, index);
3056 		if (!phy) {
3057 			error = -ENOMEM;
3058 			goto out;
3059 		}
3060 	} else
3061 		phy = phy_info->phy;
3062 
3063 	mptsas_parse_device_info(&phy->identify, &phy_info->identify);
3064 
3065 	/*
3066 	 * Set Negotiated link rate.
3067 	 */
3068 	switch (phy_info->negotiated_link_rate) {
3069 	case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
3070 		phy->negotiated_linkrate = SAS_PHY_DISABLED;
3071 		break;
3072 	case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
3073 		phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
3074 		break;
3075 	case MPI_SAS_IOUNIT0_RATE_1_5:
3076 		phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
3077 		break;
3078 	case MPI_SAS_IOUNIT0_RATE_3_0:
3079 		phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
3080 		break;
3081 	case MPI_SAS_IOUNIT0_RATE_6_0:
3082 		phy->negotiated_linkrate = SAS_LINK_RATE_6_0_GBPS;
3083 		break;
3084 	case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
3085 	case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
3086 	default:
3087 		phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
3088 		break;
3089 	}
3090 
3091 	/*
3092 	 * Set Max hardware link rate.
3093 	 */
3094 	switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3095 	case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
3096 		phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3097 		break;
3098 	case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3099 		phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3100 		break;
3101 	default:
3102 		break;
3103 	}
3104 
3105 	/*
3106 	 * Set Max programmed link rate.
3107 	 */
3108 	switch (phy_info->programmed_link_rate &
3109 			MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3110 	case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
3111 		phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3112 		break;
3113 	case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3114 		phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3115 		break;
3116 	default:
3117 		break;
3118 	}
3119 
3120 	/*
3121 	 * Set Min hardware link rate.
3122 	 */
3123 	switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
3124 	case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
3125 		phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3126 		break;
3127 	case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3128 		phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3129 		break;
3130 	default:
3131 		break;
3132 	}
3133 
3134 	/*
3135 	 * Set Min programmed link rate.
3136 	 */
3137 	switch (phy_info->programmed_link_rate &
3138 			MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
3139 	case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
3140 		phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3141 		break;
3142 	case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3143 		phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3144 		break;
3145 	default:
3146 		break;
3147 	}
3148 
3149 	if (!phy_info->phy) {
3150 
3151 		error = sas_phy_add(phy);
3152 		if (error) {
3153 			sas_phy_free(phy);
3154 			goto out;
3155 		}
3156 		phy_info->phy = phy;
3157 	}
3158 
3159 	if (!phy_info->attached.handle ||
3160 			!phy_info->port_details)
3161 		goto out;
3162 
3163 	port = mptsas_get_port(phy_info);
3164 	ioc = phy_to_ioc(phy_info->phy);
3165 
3166 	if (phy_info->sas_port_add_phy) {
3167 
3168 		if (!port) {
3169 			port = sas_port_alloc_num(dev);
3170 			if (!port) {
3171 				error = -ENOMEM;
3172 				goto out;
3173 			}
3174 			error = sas_port_add(port);
3175 			if (error) {
3176 				dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3177 					"%s: exit at line=%d\n", ioc->name,
3178 					__func__, __LINE__));
3179 				goto out;
3180 			}
3181 			mptsas_set_port(ioc, phy_info, port);
3182 			devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
3183 			    MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
3184 			    ioc->name, port->port_identifier,
3185 			    (unsigned long long)phy_info->
3186 			    attached.sas_address));
3187 		}
3188 		dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3189 			"sas_port_add_phy: phy_id=%d\n",
3190 			ioc->name, phy_info->phy_id));
3191 		sas_port_add_phy(port, phy_info->phy);
3192 		phy_info->sas_port_add_phy = 0;
3193 		devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3194 		    MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
3195 		     phy_info->phy_id, phy_info->phy));
3196 	}
3197 	if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
3198 
3199 		struct sas_rphy *rphy;
3200 		struct device *parent;
3201 		struct sas_identify identify;
3202 
3203 		parent = dev->parent->parent;
3204 		/*
3205 		 * Let the hotplug_work thread handle processing
3206 		 * the adding/removing of devices that occur
3207 		 * after start of day.
3208 		 */
3209 		if (mptsas_is_end_device(&phy_info->attached) &&
3210 		    phy_info->attached.handle_parent) {
3211 			goto out;
3212 		}
3213 
3214 		mptsas_parse_device_info(&identify, &phy_info->attached);
3215 		if (scsi_is_host_device(parent)) {
3216 			struct mptsas_portinfo *port_info;
3217 			int i;
3218 
3219 			port_info = ioc->hba_port_info;
3220 
3221 			for (i = 0; i < port_info->num_phys; i++)
3222 				if (port_info->phy_info[i].identify.sas_address ==
3223 				    identify.sas_address) {
3224 					sas_port_mark_backlink(port);
3225 					goto out;
3226 				}
3227 
3228 		} else if (scsi_is_sas_rphy(parent)) {
3229 			struct sas_rphy *parent_rphy = dev_to_rphy(parent);
3230 			if (identify.sas_address ==
3231 			    parent_rphy->identify.sas_address) {
3232 				sas_port_mark_backlink(port);
3233 				goto out;
3234 			}
3235 		}
3236 
3237 		switch (identify.device_type) {
3238 		case SAS_END_DEVICE:
3239 			rphy = sas_end_device_alloc(port);
3240 			break;
3241 		case SAS_EDGE_EXPANDER_DEVICE:
3242 		case SAS_FANOUT_EXPANDER_DEVICE:
3243 			rphy = sas_expander_alloc(port, identify.device_type);
3244 			break;
3245 		default:
3246 			rphy = NULL;
3247 			break;
3248 		}
3249 		if (!rphy) {
3250 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3251 				"%s: exit at line=%d\n", ioc->name,
3252 				__func__, __LINE__));
3253 			goto out;
3254 		}
3255 
3256 		rphy->identify = identify;
3257 		error = sas_rphy_add(rphy);
3258 		if (error) {
3259 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3260 				"%s: exit at line=%d\n", ioc->name,
3261 				__func__, __LINE__));
3262 			sas_rphy_free(rphy);
3263 			goto out;
3264 		}
3265 		mptsas_set_rphy(ioc, phy_info, rphy);
3266 		if (identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
3267 			identify.device_type == SAS_FANOUT_EXPANDER_DEVICE)
3268 				mptsas_exp_repmanufacture_info(ioc,
3269 					identify.sas_address,
3270 					rphy_to_expander_device(rphy));
3271 	}
3272 
3273 	/* If the device exists,verify it wasn't previously flagged
3274 	as a missing device.  If so, clear it */
3275 	vtarget = mptsas_find_vtarget(ioc,
3276 	    phy_info->attached.channel,
3277 	    phy_info->attached.id);
3278 	if (vtarget && vtarget->inDMD) {
3279 		printk(KERN_INFO "Device returned, unsetting inDMD\n");
3280 		vtarget->inDMD = 0;
3281 	}
3282 
3283  out:
3284 	return error;
3285 }
3286 
3287 static int
3288 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
3289 {
3290 	struct mptsas_portinfo *port_info, *hba;
3291 	int error = -ENOMEM, i;
3292 
3293 	hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3294 	if (! hba)
3295 		goto out;
3296 
3297 	error = mptsas_sas_io_unit_pg0(ioc, hba);
3298 	if (error)
3299 		goto out_free_port_info;
3300 
3301 	mptsas_sas_io_unit_pg1(ioc);
3302 	mutex_lock(&ioc->sas_topology_mutex);
3303 	port_info = ioc->hba_port_info;
3304 	if (!port_info) {
3305 		ioc->hba_port_info = port_info = hba;
3306 		ioc->hba_port_num_phy = port_info->num_phys;
3307 		list_add_tail(&port_info->list, &ioc->sas_topology);
3308 	} else {
3309 		for (i = 0; i < hba->num_phys; i++) {
3310 			port_info->phy_info[i].negotiated_link_rate =
3311 				hba->phy_info[i].negotiated_link_rate;
3312 			port_info->phy_info[i].handle =
3313 				hba->phy_info[i].handle;
3314 			port_info->phy_info[i].port_id =
3315 				hba->phy_info[i].port_id;
3316 		}
3317 		kfree(hba->phy_info);
3318 		kfree(hba);
3319 		hba = NULL;
3320 	}
3321 	mutex_unlock(&ioc->sas_topology_mutex);
3322 #if defined(CPQ_CIM)
3323 	ioc->num_ports = port_info->num_phys;
3324 #endif
3325 	for (i = 0; i < port_info->num_phys; i++) {
3326 		mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
3327 			(MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
3328 			 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
3329 		port_info->phy_info[i].identify.handle =
3330 		    port_info->phy_info[i].handle;
3331 		mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
3332 			(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3333 			 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3334 			 port_info->phy_info[i].identify.handle);
3335 		if (!ioc->hba_port_sas_addr)
3336 			ioc->hba_port_sas_addr =
3337 			    port_info->phy_info[i].identify.sas_address;
3338 		port_info->phy_info[i].identify.phy_id =
3339 		    port_info->phy_info[i].phy_id = i;
3340 		if (port_info->phy_info[i].attached.handle)
3341 			mptsas_sas_device_pg0(ioc,
3342 				&port_info->phy_info[i].attached,
3343 				(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3344 				 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3345 				port_info->phy_info[i].attached.handle);
3346 	}
3347 
3348 	mptsas_setup_wide_ports(ioc, port_info);
3349 
3350 	for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3351 		mptsas_probe_one_phy(&ioc->sh->shost_gendev,
3352 		    &port_info->phy_info[i], ioc->sas_index, 1);
3353 
3354 	return 0;
3355 
3356  out_free_port_info:
3357 	kfree(hba);
3358  out:
3359 	return error;
3360 }
3361 
3362 static void
3363 mptsas_expander_refresh(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
3364 {
3365 	struct mptsas_portinfo *parent;
3366 	struct device *parent_dev;
3367 	struct sas_rphy	*rphy;
3368 	int		i;
3369 	u64		sas_address; /* expander sas address */
3370 	u32		handle;
3371 
3372 	handle = port_info->phy_info[0].handle;
3373 	sas_address = port_info->phy_info[0].identify.sas_address;
3374 	for (i = 0; i < port_info->num_phys; i++) {
3375 		mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
3376 		    (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
3377 		    MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + handle);
3378 
3379 		mptsas_sas_device_pg0(ioc,
3380 		    &port_info->phy_info[i].identify,
3381 		    (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3382 		    MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3383 		    port_info->phy_info[i].identify.handle);
3384 		port_info->phy_info[i].identify.phy_id =
3385 		    port_info->phy_info[i].phy_id;
3386 
3387 		if (port_info->phy_info[i].attached.handle) {
3388 			mptsas_sas_device_pg0(ioc,
3389 			    &port_info->phy_info[i].attached,
3390 			    (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3391 			     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3392 			    port_info->phy_info[i].attached.handle);
3393 			port_info->phy_info[i].attached.phy_id =
3394 			    port_info->phy_info[i].phy_id;
3395 		}
3396 	}
3397 
3398 	mutex_lock(&ioc->sas_topology_mutex);
3399 	parent = mptsas_find_portinfo_by_handle(ioc,
3400 	    port_info->phy_info[0].identify.handle_parent);
3401 	if (!parent) {
3402 		mutex_unlock(&ioc->sas_topology_mutex);
3403 		return;
3404 	}
3405 	for (i = 0, parent_dev = NULL; i < parent->num_phys && !parent_dev;
3406 	    i++) {
3407 		if (parent->phy_info[i].attached.sas_address == sas_address) {
3408 			rphy = mptsas_get_rphy(&parent->phy_info[i]);
3409 			parent_dev = &rphy->dev;
3410 		}
3411 	}
3412 	mutex_unlock(&ioc->sas_topology_mutex);
3413 
3414 	mptsas_setup_wide_ports(ioc, port_info);
3415 	for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3416 		mptsas_probe_one_phy(parent_dev, &port_info->phy_info[i],
3417 		    ioc->sas_index, 0);
3418 }
3419 
3420 static void
3421 mptsas_expander_event_add(MPT_ADAPTER *ioc,
3422     MpiEventDataSasExpanderStatusChange_t *expander_data)
3423 {
3424 	struct mptsas_portinfo *port_info;
3425 	int i;
3426 	__le64 sas_address;
3427 
3428 	port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3429 	if (!port_info)
3430 		BUG();
3431 	port_info->num_phys = (expander_data->NumPhys) ?
3432 	    expander_data->NumPhys : 1;
3433 	port_info->phy_info = kcalloc(port_info->num_phys,
3434 	    sizeof(struct mptsas_phyinfo), GFP_KERNEL);
3435 	if (!port_info->phy_info)
3436 		BUG();
3437 	memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3438 	for (i = 0; i < port_info->num_phys; i++) {
3439 		port_info->phy_info[i].portinfo = port_info;
3440 		port_info->phy_info[i].handle =
3441 		    le16_to_cpu(expander_data->DevHandle);
3442 		port_info->phy_info[i].identify.sas_address =
3443 		    le64_to_cpu(sas_address);
3444 		port_info->phy_info[i].identify.handle_parent =
3445 		    le16_to_cpu(expander_data->ParentDevHandle);
3446 	}
3447 
3448 	mutex_lock(&ioc->sas_topology_mutex);
3449 	list_add_tail(&port_info->list, &ioc->sas_topology);
3450 	mutex_unlock(&ioc->sas_topology_mutex);
3451 
3452 	printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3453 	    "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3454 	    (unsigned long long)sas_address);
3455 
3456 	mptsas_expander_refresh(ioc, port_info);
3457 }
3458 
3459 /**
3460  * mptsas_delete_expander_siblings - remove siblings attached to expander
3461  * @ioc: Pointer to MPT_ADAPTER structure
3462  * @parent: the parent port_info object
3463  * @expander: the expander port_info object
3464  **/
3465 static void
3466 mptsas_delete_expander_siblings(MPT_ADAPTER *ioc, struct mptsas_portinfo
3467     *parent, struct mptsas_portinfo *expander)
3468 {
3469 	struct mptsas_phyinfo *phy_info;
3470 	struct mptsas_portinfo *port_info;
3471 	struct sas_rphy *rphy;
3472 	int i;
3473 
3474 	phy_info = expander->phy_info;
3475 	for (i = 0; i < expander->num_phys; i++, phy_info++) {
3476 		rphy = mptsas_get_rphy(phy_info);
3477 		if (!rphy)
3478 			continue;
3479 		if (rphy->identify.device_type == SAS_END_DEVICE)
3480 			mptsas_del_end_device(ioc, phy_info);
3481 	}
3482 
3483 	phy_info = expander->phy_info;
3484 	for (i = 0; i < expander->num_phys; i++, phy_info++) {
3485 		rphy = mptsas_get_rphy(phy_info);
3486 		if (!rphy)
3487 			continue;
3488 		if (rphy->identify.device_type ==
3489 		    MPI_SAS_DEVICE_INFO_EDGE_EXPANDER ||
3490 		    rphy->identify.device_type ==
3491 		    MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
3492 			port_info = mptsas_find_portinfo_by_sas_address(ioc,
3493 			    rphy->identify.sas_address);
3494 			if (!port_info)
3495 				continue;
3496 			if (port_info == parent) /* backlink rphy */
3497 				continue;
3498 			/*
3499 			Delete this expander even if the expdevpage is exists
3500 			because the parent expander is already deleted
3501 			*/
3502 			mptsas_expander_delete(ioc, port_info, 1);
3503 		}
3504 	}
3505 }
3506 
3507 
3508 /**
3509  *	mptsas_expander_delete - remove this expander
3510  *	@ioc: Pointer to MPT_ADAPTER structure
3511  *	@port_info: expander port_info struct
3512  *	@force: Flag to forcefully delete the expander
3513  *
3514  **/
3515 
3516 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
3517 		struct mptsas_portinfo *port_info, u8 force)
3518 {
3519 
3520 	struct mptsas_portinfo *parent;
3521 	int		i;
3522 	u64		expander_sas_address;
3523 	struct mptsas_phyinfo *phy_info;
3524 	struct mptsas_portinfo buffer;
3525 	struct mptsas_portinfo_details *port_details;
3526 	struct sas_port *port;
3527 
3528 	if (!port_info)
3529 		return;
3530 
3531 	/* see if expander is still there before deleting */
3532 	mptsas_sas_expander_pg0(ioc, &buffer,
3533 	    (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3534 	    MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
3535 	    port_info->phy_info[0].identify.handle);
3536 
3537 	if (buffer.num_phys) {
3538 		kfree(buffer.phy_info);
3539 		if (!force)
3540 			return;
3541 	}
3542 
3543 
3544 	/*
3545 	 * Obtain the port_info instance to the parent port
3546 	 */
3547 	port_details = NULL;
3548 	expander_sas_address =
3549 	    port_info->phy_info[0].identify.sas_address;
3550 	parent = mptsas_find_portinfo_by_handle(ioc,
3551 	    port_info->phy_info[0].identify.handle_parent);
3552 	mptsas_delete_expander_siblings(ioc, parent, port_info);
3553 	if (!parent)
3554 		goto out;
3555 
3556 	/*
3557 	 * Delete rphys in the parent that point
3558 	 * to this expander.
3559 	 */
3560 	phy_info = parent->phy_info;
3561 	port = NULL;
3562 	for (i = 0; i < parent->num_phys; i++, phy_info++) {
3563 		if (!phy_info->phy)
3564 			continue;
3565 		if (phy_info->attached.sas_address !=
3566 		    expander_sas_address)
3567 			continue;
3568 		if (!port) {
3569 			port = mptsas_get_port(phy_info);
3570 			port_details = phy_info->port_details;
3571 		}
3572 		dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3573 		    MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n", ioc->name,
3574 		    phy_info->phy_id, phy_info->phy);
3575 		sas_port_delete_phy(port, phy_info->phy);
3576 	}
3577 	if (port) {
3578 		dev_printk(KERN_DEBUG, &port->dev,
3579 		    MYIOC_s_FMT "delete port %d, sas_addr (0x%llx)\n",
3580 		    ioc->name, port->port_identifier,
3581 		    (unsigned long long)expander_sas_address);
3582 		sas_port_delete(port);
3583 		mptsas_port_delete(ioc, port_details);
3584 	}
3585  out:
3586 
3587 	printk(MYIOC_s_INFO_FMT "delete expander: num_phys %d, "
3588 	    "sas_addr (0x%llx)\n",  ioc->name, port_info->num_phys,
3589 	    (unsigned long long)expander_sas_address);
3590 
3591 	/*
3592 	 * free link
3593 	 */
3594 	list_del(&port_info->list);
3595 	kfree(port_info->phy_info);
3596 	kfree(port_info);
3597 }
3598 
3599 
3600 /**
3601  * mptsas_send_expander_event - expanders events
3602  * @ioc: Pointer to MPT_ADAPTER structure
3603  * @expander_data: event data
3604  *
3605  *
3606  * This function handles adding, removing, and refreshing
3607  * device handles within the expander objects.
3608  */
3609 static void
3610 mptsas_send_expander_event(struct fw_event_work *fw_event)
3611 {
3612 	MPT_ADAPTER *ioc;
3613 	MpiEventDataSasExpanderStatusChange_t *expander_data;
3614 	struct mptsas_portinfo *port_info;
3615 	__le64 sas_address;
3616 	int i;
3617 
3618 	ioc = fw_event->ioc;
3619 	expander_data = (MpiEventDataSasExpanderStatusChange_t *)
3620 	    fw_event->event_data;
3621 	memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3622 	sas_address = le64_to_cpu(sas_address);
3623 	port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3624 
3625 	if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
3626 		if (port_info) {
3627 			for (i = 0; i < port_info->num_phys; i++) {
3628 				port_info->phy_info[i].portinfo = port_info;
3629 				port_info->phy_info[i].handle =
3630 				    le16_to_cpu(expander_data->DevHandle);
3631 				port_info->phy_info[i].identify.sas_address =
3632 				    le64_to_cpu(sas_address);
3633 				port_info->phy_info[i].identify.handle_parent =
3634 				    le16_to_cpu(expander_data->ParentDevHandle);
3635 			}
3636 			mptsas_expander_refresh(ioc, port_info);
3637 		} else if (!port_info && expander_data->NumPhys)
3638 			mptsas_expander_event_add(ioc, expander_data);
3639 	} else if (expander_data->ReasonCode ==
3640 	    MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING)
3641 		mptsas_expander_delete(ioc, port_info, 0);
3642 
3643 	mptsas_free_fw_event(ioc, fw_event);
3644 }
3645 
3646 
3647 /**
3648  * mptsas_expander_add -
3649  * @ioc: Pointer to MPT_ADAPTER structure
3650  * @handle:
3651  *
3652  */
3653 struct mptsas_portinfo *
3654 mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
3655 {
3656 	struct mptsas_portinfo buffer, *port_info;
3657 	int i;
3658 
3659 	if ((mptsas_sas_expander_pg0(ioc, &buffer,
3660 	    (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3661 	    MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
3662 		return NULL;
3663 
3664 	port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_ATOMIC);
3665 	if (!port_info) {
3666 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3667 		"%s: exit at line=%d\n", ioc->name,
3668 		__func__, __LINE__));
3669 		return NULL;
3670 	}
3671 	port_info->num_phys = buffer.num_phys;
3672 	port_info->phy_info = buffer.phy_info;
3673 	for (i = 0; i < port_info->num_phys; i++)
3674 		port_info->phy_info[i].portinfo = port_info;
3675 	mutex_lock(&ioc->sas_topology_mutex);
3676 	list_add_tail(&port_info->list, &ioc->sas_topology);
3677 	mutex_unlock(&ioc->sas_topology_mutex);
3678 	printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3679 	    "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3680 	    (unsigned long long)buffer.phy_info[0].identify.sas_address);
3681 	mptsas_expander_refresh(ioc, port_info);
3682 	return port_info;
3683 }
3684 
3685 static void
3686 mptsas_send_link_status_event(struct fw_event_work *fw_event)
3687 {
3688 	MPT_ADAPTER *ioc;
3689 	MpiEventDataSasPhyLinkStatus_t *link_data;
3690 	struct mptsas_portinfo *port_info;
3691 	struct mptsas_phyinfo *phy_info = NULL;
3692 	__le64 sas_address;
3693 	u8 phy_num;
3694 	u8 link_rate;
3695 
3696 	ioc = fw_event->ioc;
3697 	link_data = (MpiEventDataSasPhyLinkStatus_t *)fw_event->event_data;
3698 
3699 	memcpy(&sas_address, &link_data->SASAddress, sizeof(__le64));
3700 	sas_address = le64_to_cpu(sas_address);
3701 	link_rate = link_data->LinkRates >> 4;
3702 	phy_num = link_data->PhyNum;
3703 
3704 	port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3705 	if (port_info) {
3706 		phy_info = &port_info->phy_info[phy_num];
3707 		if (phy_info)
3708 			phy_info->negotiated_link_rate = link_rate;
3709 	}
3710 
3711 	if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
3712 	    link_rate == MPI_SAS_IOUNIT0_RATE_3_0 ||
3713 	    link_rate == MPI_SAS_IOUNIT0_RATE_6_0) {
3714 
3715 		if (!port_info) {
3716 			if (ioc->old_sas_discovery_protocal) {
3717 				port_info = mptsas_expander_add(ioc,
3718 					le16_to_cpu(link_data->DevHandle));
3719 				if (port_info)
3720 					goto out;
3721 			}
3722 			goto out;
3723 		}
3724 
3725 		if (port_info == ioc->hba_port_info)
3726 			mptsas_probe_hba_phys(ioc);
3727 		else
3728 			mptsas_expander_refresh(ioc, port_info);
3729 	} else if (phy_info && phy_info->phy) {
3730 		if (link_rate ==  MPI_SAS_IOUNIT0_RATE_PHY_DISABLED)
3731 			phy_info->phy->negotiated_linkrate =
3732 			    SAS_PHY_DISABLED;
3733 		else if (link_rate ==
3734 		    MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
3735 			phy_info->phy->negotiated_linkrate =
3736 			    SAS_LINK_RATE_FAILED;
3737 		else {
3738 			phy_info->phy->negotiated_linkrate =
3739 			    SAS_LINK_RATE_UNKNOWN;
3740 			if (ioc->device_missing_delay &&
3741 			    mptsas_is_end_device(&phy_info->attached)) {
3742 				struct scsi_device		*sdev;
3743 				VirtDevice			*vdevice;
3744 				u8	channel, id;
3745 				id = phy_info->attached.id;
3746 				channel = phy_info->attached.channel;
3747 				devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3748 				"Link down for fw_id %d:fw_channel %d\n",
3749 				    ioc->name, phy_info->attached.id,
3750 				    phy_info->attached.channel));
3751 
3752 				shost_for_each_device(sdev, ioc->sh) {
3753 					vdevice = sdev->hostdata;
3754 					if ((vdevice == NULL) ||
3755 						(vdevice->vtarget == NULL))
3756 						continue;
3757 					if ((vdevice->vtarget->tflags &
3758 					    MPT_TARGET_FLAGS_RAID_COMPONENT ||
3759 					    vdevice->vtarget->raidVolume))
3760 						continue;
3761 					if (vdevice->vtarget->id == id &&
3762 						vdevice->vtarget->channel ==
3763 						channel)
3764 						devtprintk(ioc,
3765 						printk(MYIOC_s_DEBUG_FMT
3766 						"SDEV OUTSTANDING CMDS"
3767 						"%d\n", ioc->name,
3768 						sdev->device_busy));
3769 				}
3770 
3771 			}
3772 		}
3773 	}
3774  out:
3775 	mptsas_free_fw_event(ioc, fw_event);
3776 }
3777 
3778 static void
3779 mptsas_not_responding_devices(MPT_ADAPTER *ioc)
3780 {
3781 	struct mptsas_portinfo buffer, *port_info;
3782 	struct mptsas_device_info	*sas_info;
3783 	struct mptsas_devinfo sas_device;
3784 	u32	handle;
3785 	VirtTarget *vtarget = NULL;
3786 	struct mptsas_phyinfo *phy_info;
3787 	u8 found_expander;
3788 	int retval, retry_count;
3789 	unsigned long flags;
3790 
3791 	mpt_findImVolumes(ioc);
3792 
3793 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3794 	if (ioc->ioc_reset_in_progress) {
3795 		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3796 		   "%s: exiting due to a parallel reset \n", ioc->name,
3797 		    __func__));
3798 		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3799 		return;
3800 	}
3801 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3802 
3803 	/* devices, logical volumes */
3804 	mutex_lock(&ioc->sas_device_info_mutex);
3805  redo_device_scan:
3806 	list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
3807 		if (sas_info->is_cached)
3808 			continue;
3809 		if (!sas_info->is_logical_volume) {
3810 			sas_device.handle = 0;
3811 			retry_count = 0;
3812 retry_page:
3813 			retval = mptsas_sas_device_pg0(ioc, &sas_device,
3814 				(MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
3815 				<< MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3816 				(sas_info->fw.channel << 8) +
3817 				sas_info->fw.id);
3818 
3819 			if (sas_device.handle)
3820 				continue;
3821 			if (retval == -EBUSY) {
3822 				spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3823 				if (ioc->ioc_reset_in_progress) {
3824 					dfailprintk(ioc,
3825 					printk(MYIOC_s_DEBUG_FMT
3826 					"%s: exiting due to reset\n",
3827 					ioc->name, __func__));
3828 					spin_unlock_irqrestore
3829 					(&ioc->taskmgmt_lock, flags);
3830 					mutex_unlock(&ioc->
3831 					sas_device_info_mutex);
3832 					return;
3833 				}
3834 				spin_unlock_irqrestore(&ioc->taskmgmt_lock,
3835 				flags);
3836 			}
3837 
3838 			if (retval && (retval != -ENODEV)) {
3839 				if (retry_count < 10) {
3840 					retry_count++;
3841 					goto retry_page;
3842 				} else {
3843 					devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3844 					"%s: Config page retry exceeded retry "
3845 					"count deleting device 0x%llx\n",
3846 					ioc->name, __func__,
3847 					sas_info->sas_address));
3848 				}
3849 			}
3850 
3851 			/* delete device */
3852 			vtarget = mptsas_find_vtarget(ioc,
3853 				sas_info->fw.channel, sas_info->fw.id);
3854 
3855 			if (vtarget)
3856 				vtarget->deleted = 1;
3857 
3858 			phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3859 					sas_info->sas_address);
3860 
3861 			if (phy_info) {
3862 				mptsas_del_end_device(ioc, phy_info);
3863 				goto redo_device_scan;
3864 			}
3865 		} else
3866 			mptsas_volume_delete(ioc, sas_info->fw.id);
3867 	}
3868 	mutex_unlock(&ioc->sas_device_info_mutex);
3869 
3870 	/* expanders */
3871 	mutex_lock(&ioc->sas_topology_mutex);
3872  redo_expander_scan:
3873 	list_for_each_entry(port_info, &ioc->sas_topology, list) {
3874 
3875 		if (port_info->phy_info &&
3876 		    (!(port_info->phy_info[0].identify.device_info &
3877 		    MPI_SAS_DEVICE_INFO_SMP_TARGET)))
3878 			continue;
3879 		found_expander = 0;
3880 		handle = 0xFFFF;
3881 		while (!mptsas_sas_expander_pg0(ioc, &buffer,
3882 		    (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3883 		     MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
3884 		    !found_expander) {
3885 
3886 			handle = buffer.phy_info[0].handle;
3887 			if (buffer.phy_info[0].identify.sas_address ==
3888 			    port_info->phy_info[0].identify.sas_address) {
3889 				found_expander = 1;
3890 			}
3891 			kfree(buffer.phy_info);
3892 		}
3893 
3894 		if (!found_expander) {
3895 			mptsas_expander_delete(ioc, port_info, 0);
3896 			goto redo_expander_scan;
3897 		}
3898 	}
3899 	mutex_unlock(&ioc->sas_topology_mutex);
3900 }
3901 
3902 /**
3903  *	mptsas_probe_expanders - adding expanders
3904  *	@ioc: Pointer to MPT_ADAPTER structure
3905  *
3906  **/
3907 static void
3908 mptsas_probe_expanders(MPT_ADAPTER *ioc)
3909 {
3910 	struct mptsas_portinfo buffer, *port_info;
3911 	u32 			handle;
3912 	int i;
3913 
3914 	handle = 0xFFFF;
3915 	while (!mptsas_sas_expander_pg0(ioc, &buffer,
3916 	    (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3917 	     MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)) {
3918 
3919 		handle = buffer.phy_info[0].handle;
3920 		port_info = mptsas_find_portinfo_by_sas_address(ioc,
3921 		    buffer.phy_info[0].identify.sas_address);
3922 
3923 		if (port_info) {
3924 			/* refreshing handles */
3925 			for (i = 0; i < buffer.num_phys; i++) {
3926 				port_info->phy_info[i].handle = handle;
3927 				port_info->phy_info[i].identify.handle_parent =
3928 				    buffer.phy_info[0].identify.handle_parent;
3929 			}
3930 			mptsas_expander_refresh(ioc, port_info);
3931 			kfree(buffer.phy_info);
3932 			continue;
3933 		}
3934 
3935 		port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3936 		if (!port_info) {
3937 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3938 			"%s: exit at line=%d\n", ioc->name,
3939 			__func__, __LINE__));
3940 			return;
3941 		}
3942 		port_info->num_phys = buffer.num_phys;
3943 		port_info->phy_info = buffer.phy_info;
3944 		for (i = 0; i < port_info->num_phys; i++)
3945 			port_info->phy_info[i].portinfo = port_info;
3946 		mutex_lock(&ioc->sas_topology_mutex);
3947 		list_add_tail(&port_info->list, &ioc->sas_topology);
3948 		mutex_unlock(&ioc->sas_topology_mutex);
3949 		printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3950 		    "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3951 	    (unsigned long long)buffer.phy_info[0].identify.sas_address);
3952 		mptsas_expander_refresh(ioc, port_info);
3953 	}
3954 }
3955 
3956 static void
3957 mptsas_probe_devices(MPT_ADAPTER *ioc)
3958 {
3959 	u16 handle;
3960 	struct mptsas_devinfo sas_device;
3961 	struct mptsas_phyinfo *phy_info;
3962 
3963 	handle = 0xFFFF;
3964 	while (!(mptsas_sas_device_pg0(ioc, &sas_device,
3965 	    MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
3966 
3967 		handle = sas_device.handle;
3968 
3969 		if ((sas_device.device_info &
3970 		     (MPI_SAS_DEVICE_INFO_SSP_TARGET |
3971 		      MPI_SAS_DEVICE_INFO_STP_TARGET |
3972 		      MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
3973 			continue;
3974 
3975 		/* If there is no FW B_T mapping for this device then continue
3976 		 * */
3977 		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
3978 			|| !(sas_device.flags &
3979 			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
3980 			continue;
3981 
3982 		phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3983 		if (!phy_info)
3984 			continue;
3985 
3986 		if (mptsas_get_rphy(phy_info))
3987 			continue;
3988 
3989 		mptsas_add_end_device(ioc, phy_info);
3990 	}
3991 }
3992 
3993 /**
3994  *	mptsas_scan_sas_topology -
3995  *	@ioc: Pointer to MPT_ADAPTER structure
3996  *	@sas_address:
3997  *
3998  **/
3999 static void
4000 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
4001 {
4002 	struct scsi_device *sdev;
4003 	int i;
4004 
4005 	mptsas_probe_hba_phys(ioc);
4006 	mptsas_probe_expanders(ioc);
4007 	mptsas_probe_devices(ioc);
4008 
4009 	/*
4010 	  Reporting RAID volumes.
4011 	*/
4012 	if (!ioc->ir_firmware || !ioc->raid_data.pIocPg2 ||
4013 	    !ioc->raid_data.pIocPg2->NumActiveVolumes)
4014 		return;
4015 	for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
4016 		sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4017 		    ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
4018 		if (sdev) {
4019 			scsi_device_put(sdev);
4020 			continue;
4021 		}
4022 		printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4023 		    "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4024 		    ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID);
4025 		scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4026 		    ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
4027 	}
4028 }
4029 
4030 
4031 static void
4032 mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
4033 {
4034 	MPT_ADAPTER *ioc;
4035 	EventDataQueueFull_t *qfull_data;
4036 	struct mptsas_device_info *sas_info;
4037 	struct scsi_device	*sdev;
4038 	int depth;
4039 	int id = -1;
4040 	int channel = -1;
4041 	int fw_id, fw_channel;
4042 	u16 current_depth;
4043 
4044 
4045 	ioc = fw_event->ioc;
4046 	qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
4047 	fw_id = qfull_data->TargetID;
4048 	fw_channel = qfull_data->Bus;
4049 	current_depth = le16_to_cpu(qfull_data->CurrentDepth);
4050 
4051 	/* if hidden raid component, look for the volume id */
4052 	mutex_lock(&ioc->sas_device_info_mutex);
4053 	if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
4054 		list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4055 		    list) {
4056 			if (sas_info->is_cached ||
4057 			    sas_info->is_logical_volume)
4058 				continue;
4059 			if (sas_info->is_hidden_raid_component &&
4060 			    (sas_info->fw.channel == fw_channel &&
4061 			    sas_info->fw.id == fw_id)) {
4062 				id = sas_info->volume_id;
4063 				channel = MPTSAS_RAID_CHANNEL;
4064 				goto out;
4065 			}
4066 		}
4067 	} else {
4068 		list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4069 		    list) {
4070 			if (sas_info->is_cached ||
4071 			    sas_info->is_hidden_raid_component ||
4072 			    sas_info->is_logical_volume)
4073 				continue;
4074 			if (sas_info->fw.channel == fw_channel &&
4075 			    sas_info->fw.id == fw_id) {
4076 				id = sas_info->os.id;
4077 				channel = sas_info->os.channel;
4078 				goto out;
4079 			}
4080 		}
4081 
4082 	}
4083 
4084  out:
4085 	mutex_unlock(&ioc->sas_device_info_mutex);
4086 
4087 	if (id != -1) {
4088 		shost_for_each_device(sdev, ioc->sh) {
4089 			if (sdev->id == id && sdev->channel == channel) {
4090 				if (current_depth > sdev->queue_depth) {
4091 					sdev_printk(KERN_INFO, sdev,
4092 					    "strange observation, the queue "
4093 					    "depth is (%d) meanwhile fw queue "
4094 					    "depth (%d)\n", sdev->queue_depth,
4095 					    current_depth);
4096 					continue;
4097 				}
4098 				depth = scsi_track_queue_full(sdev,
4099 				    current_depth - 1);
4100 				if (depth > 0)
4101 					sdev_printk(KERN_INFO, sdev,
4102 					"Queue depth reduced to (%d)\n",
4103 					   depth);
4104 				else if (depth < 0)
4105 					sdev_printk(KERN_INFO, sdev,
4106 					"Tagged Command Queueing is being "
4107 					"disabled\n");
4108 				else if (depth == 0)
4109 					sdev_printk(KERN_INFO, sdev,
4110 					"Queue depth not changed yet\n");
4111 			}
4112 		}
4113 	}
4114 
4115 	mptsas_free_fw_event(ioc, fw_event);
4116 }
4117 
4118 
4119 static struct mptsas_phyinfo *
4120 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
4121 {
4122 	struct mptsas_portinfo *port_info;
4123 	struct mptsas_phyinfo *phy_info = NULL;
4124 	int i;
4125 
4126 	mutex_lock(&ioc->sas_topology_mutex);
4127 	list_for_each_entry(port_info, &ioc->sas_topology, list) {
4128 		for (i = 0; i < port_info->num_phys; i++) {
4129 			if (!mptsas_is_end_device(
4130 				&port_info->phy_info[i].attached))
4131 				continue;
4132 			if (port_info->phy_info[i].attached.sas_address
4133 			    != sas_address)
4134 				continue;
4135 			phy_info = &port_info->phy_info[i];
4136 			break;
4137 		}
4138 	}
4139 	mutex_unlock(&ioc->sas_topology_mutex);
4140 	return phy_info;
4141 }
4142 
4143 /**
4144  *	mptsas_find_phyinfo_by_phys_disk_num -
4145  *	@ioc: Pointer to MPT_ADAPTER structure
4146  *	@phys_disk_num:
4147  *	@channel:
4148  *	@id:
4149  *
4150  **/
4151 static struct mptsas_phyinfo *
4152 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
4153 	u8 channel, u8 id)
4154 {
4155 	struct mptsas_phyinfo *phy_info = NULL;
4156 	struct mptsas_portinfo *port_info;
4157 	RaidPhysDiskPage1_t *phys_disk = NULL;
4158 	int num_paths;
4159 	u64 sas_address = 0;
4160 	int i;
4161 
4162 	phy_info = NULL;
4163 	if (!ioc->raid_data.pIocPg3)
4164 		return NULL;
4165 	/* dual port support */
4166 	num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num);
4167 	if (!num_paths)
4168 		goto out;
4169 	phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
4170 	   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
4171 	if (!phys_disk)
4172 		goto out;
4173 	mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk);
4174 	for (i = 0; i < num_paths; i++) {
4175 		if ((phys_disk->Path[i].Flags & 1) != 0)
4176 			/* entry no longer valid */
4177 			continue;
4178 		if ((id == phys_disk->Path[i].PhysDiskID) &&
4179 		    (channel == phys_disk->Path[i].PhysDiskBus)) {
4180 			memcpy(&sas_address, &phys_disk->Path[i].WWID,
4181 				sizeof(u64));
4182 			phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4183 					sas_address);
4184 			goto out;
4185 		}
4186 	}
4187 
4188  out:
4189 	kfree(phys_disk);
4190 	if (phy_info)
4191 		return phy_info;
4192 
4193 	/*
4194 	 * Extra code to handle RAID0 case, where the sas_address is not updated
4195 	 * in phys_disk_page_1 when hotswapped
4196 	 */
4197 	mutex_lock(&ioc->sas_topology_mutex);
4198 	list_for_each_entry(port_info, &ioc->sas_topology, list) {
4199 		for (i = 0; i < port_info->num_phys && !phy_info; i++) {
4200 			if (!mptsas_is_end_device(
4201 				&port_info->phy_info[i].attached))
4202 				continue;
4203 			if (port_info->phy_info[i].attached.phys_disk_num == ~0)
4204 				continue;
4205 			if ((port_info->phy_info[i].attached.phys_disk_num ==
4206 			    phys_disk_num) &&
4207 			    (port_info->phy_info[i].attached.id == id) &&
4208 			    (port_info->phy_info[i].attached.channel ==
4209 			     channel))
4210 				phy_info = &port_info->phy_info[i];
4211 		}
4212 	}
4213 	mutex_unlock(&ioc->sas_topology_mutex);
4214 	return phy_info;
4215 }
4216 
4217 static void
4218 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
4219 {
4220 	int rc;
4221 
4222 	sdev->no_uld_attach = data ? 1 : 0;
4223 	rc = scsi_device_reprobe(sdev);
4224 }
4225 
4226 static void
4227 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
4228 {
4229 	starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
4230 			mptsas_reprobe_lun);
4231 }
4232 
4233 static void
4234 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
4235 {
4236 	CONFIGPARMS			cfg;
4237 	ConfigPageHeader_t		hdr;
4238 	dma_addr_t			dma_handle;
4239 	pRaidVolumePage0_t		buffer = NULL;
4240 	RaidPhysDiskPage0_t 		phys_disk;
4241 	int				i;
4242 	struct mptsas_phyinfo	*phy_info;
4243 	struct mptsas_devinfo		sas_device;
4244 
4245 	memset(&cfg, 0 , sizeof(CONFIGPARMS));
4246 	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4247 	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
4248 	cfg.pageAddr = (channel << 8) + id;
4249 	cfg.cfghdr.hdr = &hdr;
4250 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4251 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
4252 
4253 	if (mpt_config(ioc, &cfg) != 0)
4254 		goto out;
4255 
4256 	if (!hdr.PageLength)
4257 		goto out;
4258 
4259 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4260 	    &dma_handle);
4261 
4262 	if (!buffer)
4263 		goto out;
4264 
4265 	cfg.physAddr = dma_handle;
4266 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4267 
4268 	if (mpt_config(ioc, &cfg) != 0)
4269 		goto out;
4270 
4271 	if (!(buffer->VolumeStatus.Flags &
4272 	    MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
4273 		goto out;
4274 
4275 	if (!buffer->NumPhysDisks)
4276 		goto out;
4277 
4278 	for (i = 0; i < buffer->NumPhysDisks; i++) {
4279 
4280 		if (mpt_raid_phys_disk_pg0(ioc,
4281 		    buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
4282 			continue;
4283 
4284 		if (mptsas_sas_device_pg0(ioc, &sas_device,
4285 		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4286 		     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4287 			(phys_disk.PhysDiskBus << 8) +
4288 			phys_disk.PhysDiskID))
4289 			continue;
4290 
4291 		/* If there is no FW B_T mapping for this device then continue
4292 		 * */
4293 		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4294 			|| !(sas_device.flags &
4295 			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4296 			continue;
4297 
4298 
4299 		phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4300 		    sas_device.sas_address);
4301 		mptsas_add_end_device(ioc, phy_info);
4302 	}
4303 
4304  out:
4305 	if (buffer)
4306 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4307 		    dma_handle);
4308 }
4309 /*
4310  * Work queue thread to handle SAS hotplug events
4311  */
4312 static void
4313 mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
4314     struct mptsas_hotplug_event *hot_plug_info)
4315 {
4316 	struct mptsas_phyinfo *phy_info;
4317 	struct scsi_target * starget;
4318 	struct mptsas_devinfo sas_device;
4319 	VirtTarget *vtarget;
4320 	int i;
4321 	struct mptsas_portinfo *port_info;
4322 
4323 	switch (hot_plug_info->event_type) {
4324 
4325 	case MPTSAS_ADD_PHYSDISK:
4326 
4327 		if (!ioc->raid_data.pIocPg2)
4328 			break;
4329 
4330 		for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
4331 			if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
4332 			    hot_plug_info->id) {
4333 				printk(MYIOC_s_WARN_FMT "firmware bug: unable "
4334 				    "to add hidden disk - target_id matchs "
4335 				    "volume_id\n", ioc->name);
4336 				mptsas_free_fw_event(ioc, fw_event);
4337 				return;
4338 			}
4339 		}
4340 		mpt_findImVolumes(ioc);
4341 
4342 	case MPTSAS_ADD_DEVICE:
4343 		memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
4344 		mptsas_sas_device_pg0(ioc, &sas_device,
4345 		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4346 		    MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4347 		    (hot_plug_info->channel << 8) +
4348 		    hot_plug_info->id);
4349 
4350 		/* If there is no FW B_T mapping for this device then break
4351 		 * */
4352 		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4353 			|| !(sas_device.flags &
4354 			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4355 			break;
4356 
4357 		if (!sas_device.handle)
4358 			return;
4359 
4360 		phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
4361 		/* Only For SATA Device ADD */
4362 		if (!phy_info && (sas_device.device_info &
4363 				MPI_SAS_DEVICE_INFO_SATA_DEVICE)) {
4364 			devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4365 				"%s %d SATA HOT PLUG: "
4366 				"parent handle of device %x\n", ioc->name,
4367 				__func__, __LINE__, sas_device.handle_parent));
4368 			port_info = mptsas_find_portinfo_by_handle(ioc,
4369 				sas_device.handle_parent);
4370 
4371 			if (port_info == ioc->hba_port_info)
4372 				mptsas_probe_hba_phys(ioc);
4373 			else if (port_info)
4374 				mptsas_expander_refresh(ioc, port_info);
4375 			else {
4376 				dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4377 					"%s %d port info is NULL\n",
4378 					ioc->name, __func__, __LINE__));
4379 				break;
4380 			}
4381 			phy_info = mptsas_refreshing_device_handles
4382 				(ioc, &sas_device);
4383 		}
4384 
4385 		if (!phy_info) {
4386 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4387 				"%s %d phy info is NULL\n",
4388 				ioc->name, __func__, __LINE__));
4389 			break;
4390 		}
4391 
4392 		if (mptsas_get_rphy(phy_info))
4393 			break;
4394 
4395 		mptsas_add_end_device(ioc, phy_info);
4396 		break;
4397 
4398 	case MPTSAS_DEL_DEVICE:
4399 		phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4400 		    hot_plug_info->sas_address);
4401 		mptsas_del_end_device(ioc, phy_info);
4402 		break;
4403 
4404 	case MPTSAS_DEL_PHYSDISK:
4405 
4406 		mpt_findImVolumes(ioc);
4407 
4408 		phy_info = mptsas_find_phyinfo_by_phys_disk_num(
4409 				ioc, hot_plug_info->phys_disk_num,
4410 				hot_plug_info->channel,
4411 				hot_plug_info->id);
4412 		mptsas_del_end_device(ioc, phy_info);
4413 		break;
4414 
4415 	case MPTSAS_ADD_PHYSDISK_REPROBE:
4416 
4417 		if (mptsas_sas_device_pg0(ioc, &sas_device,
4418 		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4419 		     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4420 		    (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4421 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4422 			"%s: fw_id=%d exit at line=%d\n", ioc->name,
4423 				 __func__, hot_plug_info->id, __LINE__));
4424 			break;
4425 		}
4426 
4427 		/* If there is no FW B_T mapping for this device then break
4428 		 * */
4429 		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4430 			|| !(sas_device.flags &
4431 			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4432 			break;
4433 
4434 		phy_info = mptsas_find_phyinfo_by_sas_address(
4435 		    ioc, sas_device.sas_address);
4436 
4437 		if (!phy_info) {
4438 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4439 				"%s: fw_id=%d exit at line=%d\n", ioc->name,
4440 				 __func__, hot_plug_info->id, __LINE__));
4441 			break;
4442 		}
4443 
4444 		starget = mptsas_get_starget(phy_info);
4445 		if (!starget) {
4446 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4447 				"%s: fw_id=%d exit at line=%d\n", ioc->name,
4448 				 __func__, hot_plug_info->id, __LINE__));
4449 			break;
4450 		}
4451 
4452 		vtarget = starget->hostdata;
4453 		if (!vtarget) {
4454 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4455 				"%s: fw_id=%d exit at line=%d\n", ioc->name,
4456 				 __func__, hot_plug_info->id, __LINE__));
4457 			break;
4458 		}
4459 
4460 		mpt_findImVolumes(ioc);
4461 
4462 		starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
4463 		    "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4464 		    ioc->name, hot_plug_info->channel, hot_plug_info->id,
4465 		    hot_plug_info->phys_disk_num, (unsigned long long)
4466 		    sas_device.sas_address);
4467 
4468 		vtarget->id = hot_plug_info->phys_disk_num;
4469 		vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4470 		phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
4471 		mptsas_reprobe_target(starget, 1);
4472 		break;
4473 
4474 	case MPTSAS_DEL_PHYSDISK_REPROBE:
4475 
4476 		if (mptsas_sas_device_pg0(ioc, &sas_device,
4477 		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4478 		     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4479 			(hot_plug_info->channel << 8) + hot_plug_info->id)) {
4480 				dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4481 				    "%s: fw_id=%d exit at line=%d\n",
4482 				    ioc->name, __func__,
4483 				    hot_plug_info->id, __LINE__));
4484 			break;
4485 		}
4486 
4487 		/* If there is no FW B_T mapping for this device then break
4488 		 * */
4489 		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4490 			|| !(sas_device.flags &
4491 			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4492 			break;
4493 
4494 		phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4495 				sas_device.sas_address);
4496 		if (!phy_info) {
4497 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4498 			    "%s: fw_id=%d exit at line=%d\n", ioc->name,
4499 			 __func__, hot_plug_info->id, __LINE__));
4500 			break;
4501 		}
4502 
4503 		starget = mptsas_get_starget(phy_info);
4504 		if (!starget) {
4505 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4506 			    "%s: fw_id=%d exit at line=%d\n", ioc->name,
4507 			 __func__, hot_plug_info->id, __LINE__));
4508 			break;
4509 		}
4510 
4511 		vtarget = starget->hostdata;
4512 		if (!vtarget) {
4513 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4514 			    "%s: fw_id=%d exit at line=%d\n", ioc->name,
4515 			 __func__, hot_plug_info->id, __LINE__));
4516 			break;
4517 		}
4518 
4519 		if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
4520 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4521 			    "%s: fw_id=%d exit at line=%d\n", ioc->name,
4522 			 __func__, hot_plug_info->id, __LINE__));
4523 			break;
4524 		}
4525 
4526 		mpt_findImVolumes(ioc);
4527 
4528 		starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
4529 		    " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4530 		    ioc->name, hot_plug_info->channel, hot_plug_info->id,
4531 		    hot_plug_info->phys_disk_num, (unsigned long long)
4532 		    sas_device.sas_address);
4533 
4534 		vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4535 		vtarget->id = hot_plug_info->id;
4536 		phy_info->attached.phys_disk_num = ~0;
4537 		mptsas_reprobe_target(starget, 0);
4538 		mptsas_add_device_component_by_fw(ioc,
4539 		    hot_plug_info->channel, hot_plug_info->id);
4540 		break;
4541 
4542 	case MPTSAS_ADD_RAID:
4543 
4544 		mpt_findImVolumes(ioc);
4545 		printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4546 		    "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4547 		    hot_plug_info->id);
4548 		scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4549 		    hot_plug_info->id, 0);
4550 		break;
4551 
4552 	case MPTSAS_DEL_RAID:
4553 
4554 		mpt_findImVolumes(ioc);
4555 		printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4556 		    "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4557 		    hot_plug_info->id);
4558 		scsi_remove_device(hot_plug_info->sdev);
4559 		scsi_device_put(hot_plug_info->sdev);
4560 		break;
4561 
4562 	case MPTSAS_ADD_INACTIVE_VOLUME:
4563 
4564 		mpt_findImVolumes(ioc);
4565 		mptsas_adding_inactive_raid_components(ioc,
4566 		    hot_plug_info->channel, hot_plug_info->id);
4567 		break;
4568 
4569 	default:
4570 		break;
4571 	}
4572 
4573 	mptsas_free_fw_event(ioc, fw_event);
4574 }
4575 
4576 static void
4577 mptsas_send_sas_event(struct fw_event_work *fw_event)
4578 {
4579 	MPT_ADAPTER *ioc;
4580 	struct mptsas_hotplug_event hot_plug_info;
4581 	EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
4582 	u32 device_info;
4583 	u64 sas_address;
4584 
4585 	ioc = fw_event->ioc;
4586 	sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
4587 	    fw_event->event_data;
4588 	device_info = le32_to_cpu(sas_event_data->DeviceInfo);
4589 
4590 	if ((device_info &
4591 		(MPI_SAS_DEVICE_INFO_SSP_TARGET |
4592 		MPI_SAS_DEVICE_INFO_STP_TARGET |
4593 		MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
4594 		mptsas_free_fw_event(ioc, fw_event);
4595 		return;
4596 	}
4597 
4598 	if (sas_event_data->ReasonCode ==
4599 		MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
4600 		mptbase_sas_persist_operation(ioc,
4601 		MPI_SAS_OP_CLEAR_NOT_PRESENT);
4602 		mptsas_free_fw_event(ioc, fw_event);
4603 		return;
4604 	}
4605 
4606 	switch (sas_event_data->ReasonCode) {
4607 	case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
4608 	case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
4609 		memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4610 		hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
4611 		hot_plug_info.channel = sas_event_data->Bus;
4612 		hot_plug_info.id = sas_event_data->TargetID;
4613 		hot_plug_info.phy_id = sas_event_data->PhyNum;
4614 		memcpy(&sas_address, &sas_event_data->SASAddress,
4615 		    sizeof(u64));
4616 		hot_plug_info.sas_address = le64_to_cpu(sas_address);
4617 		hot_plug_info.device_info = device_info;
4618 		if (sas_event_data->ReasonCode &
4619 		    MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
4620 			hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
4621 		else
4622 			hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
4623 		mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4624 		break;
4625 
4626 	case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
4627 		mptbase_sas_persist_operation(ioc,
4628 		    MPI_SAS_OP_CLEAR_NOT_PRESENT);
4629 		mptsas_free_fw_event(ioc, fw_event);
4630 		break;
4631 
4632 	case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
4633 	/* TODO */
4634 	case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
4635 	/* TODO */
4636 	default:
4637 		mptsas_free_fw_event(ioc, fw_event);
4638 		break;
4639 	}
4640 }
4641 
4642 static void
4643 mptsas_send_raid_event(struct fw_event_work *fw_event)
4644 {
4645 	MPT_ADAPTER *ioc;
4646 	EVENT_DATA_RAID *raid_event_data;
4647 	struct mptsas_hotplug_event hot_plug_info;
4648 	int status;
4649 	int state;
4650 	struct scsi_device *sdev = NULL;
4651 	VirtDevice *vdevice = NULL;
4652 	RaidPhysDiskPage0_t phys_disk;
4653 
4654 	ioc = fw_event->ioc;
4655 	raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
4656 	status = le32_to_cpu(raid_event_data->SettingsStatus);
4657 	state = (status >> 8) & 0xff;
4658 
4659 	memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4660 	hot_plug_info.id = raid_event_data->VolumeID;
4661 	hot_plug_info.channel = raid_event_data->VolumeBus;
4662 	hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
4663 
4664 	if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
4665 	    raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
4666 	    raid_event_data->ReasonCode ==
4667 	    MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
4668 		sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4669 		    hot_plug_info.id, 0);
4670 		hot_plug_info.sdev = sdev;
4671 		if (sdev)
4672 			vdevice = sdev->hostdata;
4673 	}
4674 
4675 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4676 	    "ReasonCode=%02x\n", ioc->name, __func__,
4677 	    raid_event_data->ReasonCode));
4678 
4679 	switch (raid_event_data->ReasonCode) {
4680 	case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4681 		hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
4682 		break;
4683 	case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4684 		hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
4685 		break;
4686 	case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4687 		switch (state) {
4688 		case MPI_PD_STATE_ONLINE:
4689 		case MPI_PD_STATE_NOT_COMPATIBLE:
4690 			mpt_raid_phys_disk_pg0(ioc,
4691 			    raid_event_data->PhysDiskNum, &phys_disk);
4692 			hot_plug_info.id = phys_disk.PhysDiskID;
4693 			hot_plug_info.channel = phys_disk.PhysDiskBus;
4694 			hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4695 			break;
4696 		case MPI_PD_STATE_FAILED:
4697 		case MPI_PD_STATE_MISSING:
4698 		case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
4699 		case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
4700 		case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
4701 			hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4702 			break;
4703 		default:
4704 			break;
4705 		}
4706 		break;
4707 	case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4708 		if (!sdev)
4709 			break;
4710 		vdevice->vtarget->deleted = 1; /* block IO */
4711 		hot_plug_info.event_type = MPTSAS_DEL_RAID;
4712 		break;
4713 	case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4714 		if (sdev) {
4715 			scsi_device_put(sdev);
4716 			break;
4717 		}
4718 		hot_plug_info.event_type = MPTSAS_ADD_RAID;
4719 		break;
4720 	case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4721 		if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
4722 			if (!sdev)
4723 				break;
4724 			vdevice->vtarget->deleted = 1; /* block IO */
4725 			hot_plug_info.event_type = MPTSAS_DEL_RAID;
4726 			break;
4727 		}
4728 		switch (state) {
4729 		case MPI_RAIDVOL0_STATUS_STATE_FAILED:
4730 		case MPI_RAIDVOL0_STATUS_STATE_MISSING:
4731 			if (!sdev)
4732 				break;
4733 			vdevice->vtarget->deleted = 1; /* block IO */
4734 			hot_plug_info.event_type = MPTSAS_DEL_RAID;
4735 			break;
4736 		case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
4737 		case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
4738 			if (sdev) {
4739 				scsi_device_put(sdev);
4740 				break;
4741 			}
4742 			hot_plug_info.event_type = MPTSAS_ADD_RAID;
4743 			break;
4744 		default:
4745 			break;
4746 		}
4747 		break;
4748 	default:
4749 		break;
4750 	}
4751 
4752 	if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
4753 		mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4754 	else
4755 		mptsas_free_fw_event(ioc, fw_event);
4756 }
4757 
4758 /**
4759  *	mptsas_issue_tm - send mptsas internal tm request
4760  *	@ioc: Pointer to MPT_ADAPTER structure
4761  *	@type: Task Management type
4762  *	@channel: channel number for task management
4763  *	@id: Logical Target ID for reset (if appropriate)
4764  *	@lun: Logical unit for reset (if appropriate)
4765  *	@task_context: Context for the task to be aborted
4766  *	@timeout: timeout for task management control
4767  *
4768  *	return 0 on success and -1 on failure:
4769  *
4770  */
4771 static int
4772 mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
4773 	int task_context, ulong timeout, u8 *issue_reset)
4774 {
4775 	MPT_FRAME_HDR	*mf;
4776 	SCSITaskMgmt_t	*pScsiTm;
4777 	int		 retval;
4778 	unsigned long	 timeleft;
4779 
4780 	*issue_reset = 0;
4781 	mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
4782 	if (mf == NULL) {
4783 		retval = -1; /* return failure */
4784 		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt request: no "
4785 		    "msg frames!!\n", ioc->name));
4786 		goto out;
4787 	}
4788 
4789 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request: mr = %p, "
4790 	    "task_type = 0x%02X,\n\t timeout = %ld, fw_channel = %d, "
4791 	    "fw_id = %d, lun = %lld,\n\t task_context = 0x%x\n", ioc->name, mf,
4792 	     type, timeout, channel, id, (unsigned long long)lun,
4793 	     task_context));
4794 
4795 	pScsiTm = (SCSITaskMgmt_t *) mf;
4796 	memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
4797 	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
4798 	pScsiTm->TaskType = type;
4799 	pScsiTm->MsgFlags = 0;
4800 	pScsiTm->TargetID = id;
4801 	pScsiTm->Bus = channel;
4802 	pScsiTm->ChainOffset = 0;
4803 	pScsiTm->Reserved = 0;
4804 	pScsiTm->Reserved1 = 0;
4805 	pScsiTm->TaskMsgContext = task_context;
4806 	int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
4807 
4808 	INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4809 	CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
4810 	retval = 0;
4811 	mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
4812 
4813 	/* Now wait for the command to complete */
4814 	timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
4815 	    timeout*HZ);
4816 	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4817 		retval = -1; /* return failure */
4818 		dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
4819 		    "TaskMgmt request: TIMED OUT!(mr=%p)\n", ioc->name, mf));
4820 		mpt_free_msg_frame(ioc, mf);
4821 		if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4822 			goto out;
4823 		*issue_reset = 1;
4824 		goto out;
4825 	}
4826 
4827 	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
4828 		retval = -1; /* return failure */
4829 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4830 		    "TaskMgmt request: failed with no reply\n", ioc->name));
4831 		goto out;
4832 	}
4833 
4834  out:
4835 	CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4836 	return retval;
4837 }
4838 
4839 /**
4840  *	mptsas_broadcast_primative_work - Handle broadcast primitives
4841  *	@work: work queue payload containing info describing the event
4842  *
4843  *	this will be handled in workqueue context.
4844  */
4845 static void
4846 mptsas_broadcast_primative_work(struct fw_event_work *fw_event)
4847 {
4848 	MPT_ADAPTER *ioc = fw_event->ioc;
4849 	MPT_FRAME_HDR	*mf;
4850 	VirtDevice	*vdevice;
4851 	int			ii;
4852 	struct scsi_cmnd	*sc;
4853 	SCSITaskMgmtReply_t	*pScsiTmReply;
4854 	u8			issue_reset;
4855 	int			task_context;
4856 	u8			channel, id;
4857 	int			 lun;
4858 	u32			 termination_count;
4859 	u32			 query_count;
4860 
4861 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4862 	    "%s - enter\n", ioc->name, __func__));
4863 
4864 	mutex_lock(&ioc->taskmgmt_cmds.mutex);
4865 	if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
4866 		mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4867 		mptsas_requeue_fw_event(ioc, fw_event, 1000);
4868 		return;
4869 	}
4870 
4871 	issue_reset = 0;
4872 	termination_count = 0;
4873 	query_count = 0;
4874 	mpt_findImVolumes(ioc);
4875 	pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
4876 
4877 	for (ii = 0; ii < ioc->req_depth; ii++) {
4878 		if (ioc->fw_events_off)
4879 			goto out;
4880 		sc = mptscsih_get_scsi_lookup(ioc, ii);
4881 		if (!sc)
4882 			continue;
4883 		mf = MPT_INDEX_2_MFPTR(ioc, ii);
4884 		if (!mf)
4885 			continue;
4886 		task_context = mf->u.frame.hwhdr.msgctxu.MsgContext;
4887 		vdevice = sc->device->hostdata;
4888 		if (!vdevice || !vdevice->vtarget)
4889 			continue;
4890 		if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
4891 			continue; /* skip hidden raid components */
4892 		if (vdevice->vtarget->raidVolume)
4893 			continue; /* skip hidden raid components */
4894 		channel = vdevice->vtarget->channel;
4895 		id = vdevice->vtarget->id;
4896 		lun = vdevice->lun;
4897 		if (mptsas_issue_tm(ioc, MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK,
4898 		    channel, id, (u64)lun, task_context, 30, &issue_reset))
4899 			goto out;
4900 		query_count++;
4901 		termination_count +=
4902 		    le32_to_cpu(pScsiTmReply->TerminationCount);
4903 		if ((pScsiTmReply->IOCStatus == MPI_IOCSTATUS_SUCCESS) &&
4904 		    (pScsiTmReply->ResponseCode ==
4905 		    MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4906 		    pScsiTmReply->ResponseCode ==
4907 		    MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4908 			continue;
4909 		if (mptsas_issue_tm(ioc,
4910 		    MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET,
4911 		    channel, id, (u64)lun, 0, 30, &issue_reset))
4912 			goto out;
4913 		termination_count +=
4914 		    le32_to_cpu(pScsiTmReply->TerminationCount);
4915 	}
4916 
4917  out:
4918 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4919 	    "%s - exit, query_count = %d termination_count = %d\n",
4920 	    ioc->name, __func__, query_count, termination_count));
4921 
4922 	ioc->broadcast_aen_busy = 0;
4923 	mpt_clear_taskmgmt_in_progress_flag(ioc);
4924 	mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4925 
4926 	if (issue_reset) {
4927 		printk(MYIOC_s_WARN_FMT
4928 		       "Issuing Reset from %s!! doorbell=0x%08x\n",
4929 		       ioc->name, __func__, mpt_GetIocState(ioc, 0));
4930 		mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
4931 	}
4932 	mptsas_free_fw_event(ioc, fw_event);
4933 }
4934 
4935 /*
4936  * mptsas_send_ir2_event - handle exposing hidden disk when
4937  * an inactive raid volume is added
4938  *
4939  * @ioc: Pointer to MPT_ADAPTER structure
4940  * @ir2_data
4941  *
4942  */
4943 static void
4944 mptsas_send_ir2_event(struct fw_event_work *fw_event)
4945 {
4946 	MPT_ADAPTER	*ioc;
4947 	struct mptsas_hotplug_event hot_plug_info;
4948 	MPI_EVENT_DATA_IR2	*ir2_data;
4949 	u8 reasonCode;
4950 	RaidPhysDiskPage0_t phys_disk;
4951 
4952 	ioc = fw_event->ioc;
4953 	ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
4954 	reasonCode = ir2_data->ReasonCode;
4955 
4956 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4957 	    "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
4958 
4959 	memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4960 	hot_plug_info.id = ir2_data->TargetID;
4961 	hot_plug_info.channel = ir2_data->Bus;
4962 	switch (reasonCode) {
4963 	case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
4964 		hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
4965 		break;
4966 	case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
4967 		hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4968 		hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4969 		break;
4970 	case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
4971 		hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4972 		mpt_raid_phys_disk_pg0(ioc,
4973 		    ir2_data->PhysDiskNum, &phys_disk);
4974 		hot_plug_info.id = phys_disk.PhysDiskID;
4975 		hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4976 		break;
4977 	default:
4978 		mptsas_free_fw_event(ioc, fw_event);
4979 		return;
4980 	}
4981 	mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4982 }
4983 
4984 static int
4985 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
4986 {
4987 	u32 event = le32_to_cpu(reply->Event);
4988 	int sz, event_data_sz;
4989 	struct fw_event_work *fw_event;
4990 	unsigned long delay;
4991 
4992 	if (ioc->bus_type != SAS)
4993 		return 0;
4994 
4995 	/* events turned off due to host reset or driver unloading */
4996 	if (ioc->fw_events_off)
4997 		return 0;
4998 
4999 	delay = msecs_to_jiffies(1);
5000 	switch (event) {
5001 	case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
5002 	{
5003 		EVENT_DATA_SAS_BROADCAST_PRIMITIVE *broadcast_event_data =
5004 		    (EVENT_DATA_SAS_BROADCAST_PRIMITIVE *)reply->Data;
5005 		if (broadcast_event_data->Primitive !=
5006 		    MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
5007 			return 0;
5008 		if (ioc->broadcast_aen_busy)
5009 			return 0;
5010 		ioc->broadcast_aen_busy = 1;
5011 		break;
5012 	}
5013 	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5014 	{
5015 		EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
5016 		    (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
5017 		u16	ioc_stat;
5018 		ioc_stat = le16_to_cpu(reply->IOCStatus);
5019 
5020 		if (sas_event_data->ReasonCode ==
5021 		    MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
5022 			mptsas_target_reset_queue(ioc, sas_event_data);
5023 			return 0;
5024 		}
5025 		if (sas_event_data->ReasonCode ==
5026 			MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
5027 			ioc->device_missing_delay &&
5028 			(ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)) {
5029 			VirtTarget *vtarget = NULL;
5030 			u8		id, channel;
5031 
5032 			id = sas_event_data->TargetID;
5033 			channel = sas_event_data->Bus;
5034 
5035 			vtarget = mptsas_find_vtarget(ioc, channel, id);
5036 			if (vtarget) {
5037 				devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5038 				    "LogInfo (0x%x) available for "
5039 				   "INTERNAL_DEVICE_RESET"
5040 				   "fw_id %d fw_channel %d\n", ioc->name,
5041 				   le32_to_cpu(reply->IOCLogInfo),
5042 				   id, channel));
5043 				if (vtarget->raidVolume) {
5044 					devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5045 					"Skipping Raid Volume for inDMD\n",
5046 					ioc->name));
5047 				} else {
5048 					devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5049 					"Setting device flag inDMD\n",
5050 					ioc->name));
5051 					vtarget->inDMD = 1;
5052 				}
5053 
5054 			}
5055 
5056 		}
5057 
5058 		break;
5059 	}
5060 	case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
5061 	{
5062 		MpiEventDataSasExpanderStatusChange_t *expander_data =
5063 		    (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
5064 
5065 		if (ioc->old_sas_discovery_protocal)
5066 			return 0;
5067 
5068 		if (expander_data->ReasonCode ==
5069 		    MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
5070 		    ioc->device_missing_delay)
5071 			delay = HZ * ioc->device_missing_delay;
5072 		break;
5073 	}
5074 	case MPI_EVENT_SAS_DISCOVERY:
5075 	{
5076 		u32 discovery_status;
5077 		EventDataSasDiscovery_t *discovery_data =
5078 		    (EventDataSasDiscovery_t *)reply->Data;
5079 
5080 		discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
5081 		ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
5082 		if (ioc->old_sas_discovery_protocal && !discovery_status)
5083 			mptsas_queue_rescan(ioc);
5084 		return 0;
5085 	}
5086 	case MPI_EVENT_INTEGRATED_RAID:
5087 	case MPI_EVENT_PERSISTENT_TABLE_FULL:
5088 	case MPI_EVENT_IR2:
5089 	case MPI_EVENT_SAS_PHY_LINK_STATUS:
5090 	case MPI_EVENT_QUEUE_FULL:
5091 		break;
5092 	default:
5093 		return 0;
5094 	}
5095 
5096 	event_data_sz = ((reply->MsgLength * 4) -
5097 	    offsetof(EventNotificationReply_t, Data));
5098 	sz = offsetof(struct fw_event_work, event_data) + event_data_sz;
5099 	fw_event = kzalloc(sz, GFP_ATOMIC);
5100 	if (!fw_event) {
5101 		printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
5102 		 __func__, __LINE__);
5103 		return 0;
5104 	}
5105 	memcpy(fw_event->event_data, reply->Data, event_data_sz);
5106 	fw_event->event = event;
5107 	fw_event->ioc = ioc;
5108 	mptsas_add_fw_event(ioc, fw_event, delay);
5109 	return 0;
5110 }
5111 
5112 /* Delete a volume when no longer listed in ioc pg2
5113  */
5114 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id)
5115 {
5116 	struct scsi_device *sdev;
5117 	int i;
5118 
5119 	sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0);
5120 	if (!sdev)
5121 		return;
5122 	if (!ioc->raid_data.pIocPg2)
5123 		goto out;
5124 	if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
5125 		goto out;
5126 	for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
5127 		if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id)
5128 			goto release_sdev;
5129  out:
5130 	printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
5131 	    "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id);
5132 	scsi_remove_device(sdev);
5133  release_sdev:
5134 	scsi_device_put(sdev);
5135 }
5136 
5137 static int
5138 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5139 {
5140 	struct Scsi_Host	*sh;
5141 	MPT_SCSI_HOST		*hd;
5142 	MPT_ADAPTER 		*ioc;
5143 	unsigned long		 flags;
5144 	int			 ii;
5145 	int			 numSGE = 0;
5146 	int			 scale;
5147 	int			 ioc_cap;
5148 	int			error=0;
5149 	int			r;
5150 
5151 	r = mpt_attach(pdev,id);
5152 	if (r)
5153 		return r;
5154 
5155 	ioc = pci_get_drvdata(pdev);
5156 	mptsas_fw_event_off(ioc);
5157 	ioc->DoneCtx = mptsasDoneCtx;
5158 	ioc->TaskCtx = mptsasTaskCtx;
5159 	ioc->InternalCtx = mptsasInternalCtx;
5160 	ioc->schedule_target_reset = &mptsas_schedule_target_reset;
5161 	ioc->schedule_dead_ioc_flush_running_cmds =
5162 				&mptscsih_flush_running_cmds;
5163 	/*  Added sanity check on readiness of the MPT adapter.
5164 	 */
5165 	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
5166 		printk(MYIOC_s_WARN_FMT
5167 		  "Skipping because it's not operational!\n",
5168 		  ioc->name);
5169 		error = -ENODEV;
5170 		goto out_mptsas_probe;
5171 	}
5172 
5173 	if (!ioc->active) {
5174 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
5175 		  ioc->name);
5176 		error = -ENODEV;
5177 		goto out_mptsas_probe;
5178 	}
5179 
5180 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
5181 	 */
5182 	ioc_cap = 0;
5183 	for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
5184 		if (ioc->pfacts[ii].ProtocolFlags &
5185 				MPI_PORTFACTS_PROTOCOL_INITIATOR)
5186 			ioc_cap++;
5187 	}
5188 
5189 	if (!ioc_cap) {
5190 		printk(MYIOC_s_WARN_FMT
5191 			"Skipping ioc=%p because SCSI Initiator mode "
5192 			"is NOT enabled!\n", ioc->name, ioc);
5193 		return 0;
5194 	}
5195 
5196 	sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
5197 	if (!sh) {
5198 		printk(MYIOC_s_WARN_FMT
5199 			"Unable to register controller with SCSI subsystem\n",
5200 			ioc->name);
5201 		error = -1;
5202 		goto out_mptsas_probe;
5203         }
5204 
5205 	spin_lock_irqsave(&ioc->FreeQlock, flags);
5206 
5207 	/* Attach the SCSI Host to the IOC structure
5208 	 */
5209 	ioc->sh = sh;
5210 
5211 	sh->io_port = 0;
5212 	sh->n_io_port = 0;
5213 	sh->irq = 0;
5214 
5215 	/* set 16 byte cdb's */
5216 	sh->max_cmd_len = 16;
5217 	sh->can_queue = min_t(int, ioc->req_depth - 10, sh->can_queue);
5218 	sh->max_id = -1;
5219 	sh->max_lun = max_lun;
5220 	sh->transportt = mptsas_transport_template;
5221 
5222 	/* Required entry.
5223 	 */
5224 	sh->unique_id = ioc->id;
5225 
5226 	INIT_LIST_HEAD(&ioc->sas_topology);
5227 	mutex_init(&ioc->sas_topology_mutex);
5228 	mutex_init(&ioc->sas_discovery_mutex);
5229 	mutex_init(&ioc->sas_mgmt.mutex);
5230 	init_completion(&ioc->sas_mgmt.done);
5231 
5232 	/* Verify that we won't exceed the maximum
5233 	 * number of chain buffers
5234 	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
5235 	 * For 32bit SGE's:
5236 	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
5237 	 *               + (req_sz - 64)/sizeof(SGE)
5238 	 * A slightly different algorithm is required for
5239 	 * 64bit SGEs.
5240 	 */
5241 	scale = ioc->req_sz/ioc->SGE_size;
5242 	if (ioc->sg_addr_size == sizeof(u64)) {
5243 		numSGE = (scale - 1) *
5244 		  (ioc->facts.MaxChainDepth-1) + scale +
5245 		  (ioc->req_sz - 60) / ioc->SGE_size;
5246 	} else {
5247 		numSGE = 1 + (scale - 1) *
5248 		  (ioc->facts.MaxChainDepth-1) + scale +
5249 		  (ioc->req_sz - 64) / ioc->SGE_size;
5250 	}
5251 
5252 	if (numSGE < sh->sg_tablesize) {
5253 		/* Reset this value */
5254 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5255 		  "Resetting sg_tablesize to %d from %d\n",
5256 		  ioc->name, numSGE, sh->sg_tablesize));
5257 		sh->sg_tablesize = numSGE;
5258 	}
5259 
5260 	if (mpt_loadtime_max_sectors) {
5261 		if (mpt_loadtime_max_sectors < 64 ||
5262 			mpt_loadtime_max_sectors > 8192) {
5263 			printk(MYIOC_s_INFO_FMT "Invalid value passed for"
5264 				"mpt_loadtime_max_sectors %d."
5265 				"Range from 64 to 8192\n", ioc->name,
5266 				mpt_loadtime_max_sectors);
5267 		}
5268 		mpt_loadtime_max_sectors &=  0xFFFFFFFE;
5269 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5270 			"Resetting max sector to %d from %d\n",
5271 		  ioc->name, mpt_loadtime_max_sectors, sh->max_sectors));
5272 		sh->max_sectors = mpt_loadtime_max_sectors;
5273 	}
5274 
5275 	hd = shost_priv(sh);
5276 	hd->ioc = ioc;
5277 
5278 	/* SCSI needs scsi_cmnd lookup table!
5279 	 * (with size equal to req_depth*PtrSz!)
5280 	 */
5281 	ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
5282 	if (!ioc->ScsiLookup) {
5283 		error = -ENOMEM;
5284 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5285 		goto out_mptsas_probe;
5286 	}
5287 	spin_lock_init(&ioc->scsi_lookup_lock);
5288 
5289 	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
5290 		 ioc->name, ioc->ScsiLookup));
5291 
5292 	ioc->sas_data.ptClear = mpt_pt_clear;
5293 
5294 	hd->last_queue_full = 0;
5295 	INIT_LIST_HEAD(&hd->target_reset_list);
5296 	INIT_LIST_HEAD(&ioc->sas_device_info_list);
5297 	mutex_init(&ioc->sas_device_info_mutex);
5298 
5299 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5300 
5301 	if (ioc->sas_data.ptClear==1) {
5302 		mptbase_sas_persist_operation(
5303 		    ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
5304 	}
5305 
5306 	error = scsi_add_host(sh, &ioc->pcidev->dev);
5307 	if (error) {
5308 		dprintk(ioc, printk(MYIOC_s_ERR_FMT
5309 		  "scsi_add_host failed\n", ioc->name));
5310 		goto out_mptsas_probe;
5311 	}
5312 
5313 	/* older firmware doesn't support expander events */
5314 	if ((ioc->facts.HeaderVersion >> 8) < 0xE)
5315 		ioc->old_sas_discovery_protocal = 1;
5316 	mptsas_scan_sas_topology(ioc);
5317 	mptsas_fw_event_on(ioc);
5318 	return 0;
5319 
5320  out_mptsas_probe:
5321 
5322 	mptscsih_remove(pdev);
5323 	return error;
5324 }
5325 
5326 void
5327 mptsas_shutdown(struct pci_dev *pdev)
5328 {
5329 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5330 
5331 	mptsas_fw_event_off(ioc);
5332 	mptsas_cleanup_fw_event_q(ioc);
5333 }
5334 
5335 static void mptsas_remove(struct pci_dev *pdev)
5336 {
5337 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5338 	struct mptsas_portinfo *p, *n;
5339 	int i;
5340 
5341 	if (!ioc->sh) {
5342 		printk(MYIOC_s_INFO_FMT "IOC is in Target mode\n", ioc->name);
5343 		mpt_detach(pdev);
5344 		return;
5345 	}
5346 
5347 	mptsas_shutdown(pdev);
5348 
5349 	mptsas_del_device_components(ioc);
5350 
5351 	ioc->sas_discovery_ignore_events = 1;
5352 	sas_remove_host(ioc->sh);
5353 
5354 	mutex_lock(&ioc->sas_topology_mutex);
5355 	list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
5356 		list_del(&p->list);
5357 		for (i = 0 ; i < p->num_phys ; i++)
5358 			mptsas_port_delete(ioc, p->phy_info[i].port_details);
5359 
5360 		kfree(p->phy_info);
5361 		kfree(p);
5362 	}
5363 	mutex_unlock(&ioc->sas_topology_mutex);
5364 	ioc->hba_port_info = NULL;
5365 	mptscsih_remove(pdev);
5366 }
5367 
5368 static struct pci_device_id mptsas_pci_table[] = {
5369 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
5370 		PCI_ANY_ID, PCI_ANY_ID },
5371 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
5372 		PCI_ANY_ID, PCI_ANY_ID },
5373 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
5374 		PCI_ANY_ID, PCI_ANY_ID },
5375 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
5376 		PCI_ANY_ID, PCI_ANY_ID },
5377 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
5378 		PCI_ANY_ID, PCI_ANY_ID },
5379 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068_820XELP,
5380 		PCI_ANY_ID, PCI_ANY_ID },
5381 	{0}	/* Terminating entry */
5382 };
5383 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
5384 
5385 
5386 static struct pci_driver mptsas_driver = {
5387 	.name		= "mptsas",
5388 	.id_table	= mptsas_pci_table,
5389 	.probe		= mptsas_probe,
5390 	.remove		= mptsas_remove,
5391 	.shutdown	= mptsas_shutdown,
5392 #ifdef CONFIG_PM
5393 	.suspend	= mptscsih_suspend,
5394 	.resume		= mptscsih_resume,
5395 #endif
5396 };
5397 
5398 static int __init
5399 mptsas_init(void)
5400 {
5401 	int error;
5402 
5403 	show_mptmod_ver(my_NAME, my_VERSION);
5404 
5405 	mptsas_transport_template =
5406 	    sas_attach_transport(&mptsas_transport_functions);
5407 	if (!mptsas_transport_template)
5408 		return -ENODEV;
5409 	mptsas_transport_template->eh_timed_out = mptsas_eh_timed_out;
5410 
5411 	mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER,
5412 	    "mptscsih_io_done");
5413 	mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER,
5414 	    "mptscsih_taskmgmt_complete");
5415 	mptsasInternalCtx =
5416 		mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER,
5417 		    "mptscsih_scandv_complete");
5418 	mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER,
5419 	    "mptsas_mgmt_done");
5420 	mptsasDeviceResetCtx =
5421 		mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER,
5422 		    "mptsas_taskmgmt_complete");
5423 
5424 	mpt_event_register(mptsasDoneCtx, mptsas_event_process);
5425 	mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
5426 
5427 	error = pci_register_driver(&mptsas_driver);
5428 	if (error)
5429 		sas_release_transport(mptsas_transport_template);
5430 
5431 	return error;
5432 }
5433 
5434 static void __exit
5435 mptsas_exit(void)
5436 {
5437 	pci_unregister_driver(&mptsas_driver);
5438 	sas_release_transport(mptsas_transport_template);
5439 
5440 	mpt_reset_deregister(mptsasDoneCtx);
5441 	mpt_event_deregister(mptsasDoneCtx);
5442 
5443 	mpt_deregister(mptsasMgmtCtx);
5444 	mpt_deregister(mptsasInternalCtx);
5445 	mpt_deregister(mptsasTaskCtx);
5446 	mpt_deregister(mptsasDoneCtx);
5447 	mpt_deregister(mptsasDeviceResetCtx);
5448 }
5449 
5450 module_init(mptsas_init);
5451 module_exit(mptsas_exit);
5452