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