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