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