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