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