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