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