xref: /openbmc/linux/drivers/message/fusion/mptsas.c (revision df2634f43f5106947f3735a0b61a6527a4b278cd)
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 management 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_lck(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 static DEF_SCSI_QCMD(mptsas_qcmd)
1917 
1918 /**
1919  *	mptsas_mptsas_eh_timed_out - resets the scsi_cmnd timeout
1920  *		if the device under question is currently in the
1921  *		device removal delay.
1922  *	@sc: scsi command that the midlayer is about to time out
1923  *
1924  **/
1925 static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
1926 {
1927 	MPT_SCSI_HOST *hd;
1928 	MPT_ADAPTER   *ioc;
1929 	VirtDevice    *vdevice;
1930 	enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED;
1931 
1932 	hd = shost_priv(sc->device->host);
1933 	if (hd == NULL) {
1934 		printk(KERN_ERR MYNAM ": %s: Can't locate host! (sc=%p)\n",
1935 		    __func__, sc);
1936 		goto done;
1937 	}
1938 
1939 	ioc = hd->ioc;
1940 	if (ioc->bus_type != SAS) {
1941 		printk(KERN_ERR MYNAM ": %s: Wrong bus type (sc=%p)\n",
1942 		    __func__, sc);
1943 		goto done;
1944 	}
1945 
1946 	vdevice = sc->device->hostdata;
1947 	if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD
1948 		|| vdevice->vtarget->deleted)) {
1949 		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: target removed "
1950 		    "or in device removal delay (sc=%p)\n",
1951 		    ioc->name, __func__, sc));
1952 		rc = BLK_EH_RESET_TIMER;
1953 		goto done;
1954 	}
1955 
1956 done:
1957 	return rc;
1958 }
1959 
1960 
1961 static struct scsi_host_template mptsas_driver_template = {
1962 	.module				= THIS_MODULE,
1963 	.proc_name			= "mptsas",
1964 	.proc_info			= mptscsih_proc_info,
1965 	.name				= "MPT SAS Host",
1966 	.info				= mptscsih_info,
1967 	.queuecommand			= mptsas_qcmd,
1968 	.target_alloc			= mptsas_target_alloc,
1969 	.slave_alloc			= mptsas_slave_alloc,
1970 	.slave_configure		= mptsas_slave_configure,
1971 	.target_destroy			= mptsas_target_destroy,
1972 	.slave_destroy			= mptscsih_slave_destroy,
1973 	.change_queue_depth 		= mptscsih_change_queue_depth,
1974 	.eh_abort_handler		= mptscsih_abort,
1975 	.eh_device_reset_handler	= mptscsih_dev_reset,
1976 	.eh_bus_reset_handler		= mptscsih_bus_reset,
1977 	.eh_host_reset_handler		= mptscsih_host_reset,
1978 	.bios_param			= mptscsih_bios_param,
1979 	.can_queue			= MPT_SAS_CAN_QUEUE,
1980 	.this_id			= -1,
1981 	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
1982 	.max_sectors			= 8192,
1983 	.cmd_per_lun			= 7,
1984 	.use_clustering			= ENABLE_CLUSTERING,
1985 	.shost_attrs			= mptscsih_host_attrs,
1986 };
1987 
1988 static int mptsas_get_linkerrors(struct sas_phy *phy)
1989 {
1990 	MPT_ADAPTER *ioc = phy_to_ioc(phy);
1991 	ConfigExtendedPageHeader_t hdr;
1992 	CONFIGPARMS cfg;
1993 	SasPhyPage1_t *buffer;
1994 	dma_addr_t dma_handle;
1995 	int error;
1996 
1997 	/* FIXME: only have link errors on local phys */
1998 	if (!scsi_is_sas_phy_local(phy))
1999 		return -EINVAL;
2000 
2001 	hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
2002 	hdr.ExtPageLength = 0;
2003 	hdr.PageNumber = 1 /* page number 1*/;
2004 	hdr.Reserved1 = 0;
2005 	hdr.Reserved2 = 0;
2006 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2007 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2008 
2009 	cfg.cfghdr.ehdr = &hdr;
2010 	cfg.physAddr = -1;
2011 	cfg.pageAddr = phy->identify.phy_identifier;
2012 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2013 	cfg.dir = 0;    /* read */
2014 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2015 
2016 	error = mpt_config(ioc, &cfg);
2017 	if (error)
2018 		return error;
2019 	if (!hdr.ExtPageLength)
2020 		return -ENXIO;
2021 
2022 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2023 				      &dma_handle);
2024 	if (!buffer)
2025 		return -ENOMEM;
2026 
2027 	cfg.physAddr = dma_handle;
2028 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2029 
2030 	error = mpt_config(ioc, &cfg);
2031 	if (error)
2032 		goto out_free_consistent;
2033 
2034 	mptsas_print_phy_pg1(ioc, buffer);
2035 
2036 	phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
2037 	phy->running_disparity_error_count =
2038 		le32_to_cpu(buffer->RunningDisparityErrorCount);
2039 	phy->loss_of_dword_sync_count =
2040 		le32_to_cpu(buffer->LossDwordSynchCount);
2041 	phy->phy_reset_problem_count =
2042 		le32_to_cpu(buffer->PhyResetProblemCount);
2043 
2044  out_free_consistent:
2045 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2046 			    buffer, dma_handle);
2047 	return error;
2048 }
2049 
2050 static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
2051 		MPT_FRAME_HDR *reply)
2052 {
2053 	ioc->sas_mgmt.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
2054 	if (reply != NULL) {
2055 		ioc->sas_mgmt.status |= MPT_MGMT_STATUS_RF_VALID;
2056 		memcpy(ioc->sas_mgmt.reply, reply,
2057 		    min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
2058 	}
2059 
2060 	if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
2061 		ioc->sas_mgmt.status &= ~MPT_MGMT_STATUS_PENDING;
2062 		complete(&ioc->sas_mgmt.done);
2063 		return 1;
2064 	}
2065 	return 0;
2066 }
2067 
2068 static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
2069 {
2070 	MPT_ADAPTER *ioc = phy_to_ioc(phy);
2071 	SasIoUnitControlRequest_t *req;
2072 	SasIoUnitControlReply_t *reply;
2073 	MPT_FRAME_HDR *mf;
2074 	MPIHeader_t *hdr;
2075 	unsigned long timeleft;
2076 	int error = -ERESTARTSYS;
2077 
2078 	/* FIXME: fusion doesn't allow non-local phy reset */
2079 	if (!scsi_is_sas_phy_local(phy))
2080 		return -EINVAL;
2081 
2082 	/* not implemented for expanders */
2083 	if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
2084 		return -ENXIO;
2085 
2086 	if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
2087 		goto out;
2088 
2089 	mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2090 	if (!mf) {
2091 		error = -ENOMEM;
2092 		goto out_unlock;
2093 	}
2094 
2095 	hdr = (MPIHeader_t *) mf;
2096 	req = (SasIoUnitControlRequest_t *)mf;
2097 	memset(req, 0, sizeof(SasIoUnitControlRequest_t));
2098 	req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
2099 	req->MsgContext = hdr->MsgContext;
2100 	req->Operation = hard_reset ?
2101 		MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
2102 	req->PhyNum = phy->identify.phy_identifier;
2103 
2104 	INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2105 	mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2106 
2107 	timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
2108 			10 * HZ);
2109 	if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2110 		error = -ETIME;
2111 		mpt_free_msg_frame(ioc, mf);
2112 		if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2113 			goto out_unlock;
2114 		if (!timeleft)
2115 			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2116 		goto out_unlock;
2117 	}
2118 
2119 	/* a reply frame is expected */
2120 	if ((ioc->sas_mgmt.status &
2121 	    MPT_MGMT_STATUS_RF_VALID) == 0) {
2122 		error = -ENXIO;
2123 		goto out_unlock;
2124 	}
2125 
2126 	/* process the completed Reply Message Frame */
2127 	reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
2128 	if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
2129 		printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
2130 		    ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
2131 		error = -ENXIO;
2132 		goto out_unlock;
2133 	}
2134 
2135 	error = 0;
2136 
2137  out_unlock:
2138 	CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2139 	mutex_unlock(&ioc->sas_mgmt.mutex);
2140  out:
2141 	return error;
2142 }
2143 
2144 static int
2145 mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
2146 {
2147 	MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2148 	int i, error;
2149 	struct mptsas_portinfo *p;
2150 	struct mptsas_enclosure enclosure_info;
2151 	u64 enclosure_handle;
2152 
2153 	mutex_lock(&ioc->sas_topology_mutex);
2154 	list_for_each_entry(p, &ioc->sas_topology, list) {
2155 		for (i = 0; i < p->num_phys; i++) {
2156 			if (p->phy_info[i].attached.sas_address ==
2157 			    rphy->identify.sas_address) {
2158 				enclosure_handle = p->phy_info[i].
2159 					attached.handle_enclosure;
2160 				goto found_info;
2161 			}
2162 		}
2163 	}
2164 	mutex_unlock(&ioc->sas_topology_mutex);
2165 	return -ENXIO;
2166 
2167  found_info:
2168 	mutex_unlock(&ioc->sas_topology_mutex);
2169 	memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
2170 	error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
2171 			(MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
2172 			 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
2173 	if (!error)
2174 		*identifier = enclosure_info.enclosure_logical_id;
2175 	return error;
2176 }
2177 
2178 static int
2179 mptsas_get_bay_identifier(struct sas_rphy *rphy)
2180 {
2181 	MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
2182 	struct mptsas_portinfo *p;
2183 	int i, rc;
2184 
2185 	mutex_lock(&ioc->sas_topology_mutex);
2186 	list_for_each_entry(p, &ioc->sas_topology, list) {
2187 		for (i = 0; i < p->num_phys; i++) {
2188 			if (p->phy_info[i].attached.sas_address ==
2189 			    rphy->identify.sas_address) {
2190 				rc = p->phy_info[i].attached.slot;
2191 				goto out;
2192 			}
2193 		}
2194 	}
2195 	rc = -ENXIO;
2196  out:
2197 	mutex_unlock(&ioc->sas_topology_mutex);
2198 	return rc;
2199 }
2200 
2201 static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
2202 			      struct request *req)
2203 {
2204 	MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
2205 	MPT_FRAME_HDR *mf;
2206 	SmpPassthroughRequest_t *smpreq;
2207 	struct request *rsp = req->next_rq;
2208 	int ret;
2209 	int flagsLength;
2210 	unsigned long timeleft;
2211 	char *psge;
2212 	dma_addr_t dma_addr_in = 0;
2213 	dma_addr_t dma_addr_out = 0;
2214 	u64 sas_address = 0;
2215 
2216 	if (!rsp) {
2217 		printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n",
2218 		    ioc->name, __func__);
2219 		return -EINVAL;
2220 	}
2221 
2222 	/* do we need to support multiple segments? */
2223 	if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
2224 		printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u %u, rsp %u %u\n",
2225 		    ioc->name, __func__, req->bio->bi_vcnt, blk_rq_bytes(req),
2226 		    rsp->bio->bi_vcnt, blk_rq_bytes(rsp));
2227 		return -EINVAL;
2228 	}
2229 
2230 	ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2231 	if (ret)
2232 		goto out;
2233 
2234 	mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2235 	if (!mf) {
2236 		ret = -ENOMEM;
2237 		goto out_unlock;
2238 	}
2239 
2240 	smpreq = (SmpPassthroughRequest_t *)mf;
2241 	memset(smpreq, 0, sizeof(*smpreq));
2242 
2243 	smpreq->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4);
2244 	smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2245 
2246 	if (rphy)
2247 		sas_address = rphy->identify.sas_address;
2248 	else {
2249 		struct mptsas_portinfo *port_info;
2250 
2251 		mutex_lock(&ioc->sas_topology_mutex);
2252 		port_info = ioc->hba_port_info;
2253 		if (port_info && port_info->phy_info)
2254 			sas_address =
2255 				port_info->phy_info[0].phy->identify.sas_address;
2256 		mutex_unlock(&ioc->sas_topology_mutex);
2257 	}
2258 
2259 	*((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2260 
2261 	psge = (char *)
2262 		(((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2263 
2264 	/* request */
2265 	flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2266 		       MPI_SGE_FLAGS_END_OF_BUFFER |
2267 		       MPI_SGE_FLAGS_DIRECTION)
2268 		       << MPI_SGE_FLAGS_SHIFT;
2269 	flagsLength |= (blk_rq_bytes(req) - 4);
2270 
2271 	dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
2272 				      blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
2273 	if (!dma_addr_out)
2274 		goto put_mf;
2275 	ioc->add_sge(psge, flagsLength, dma_addr_out);
2276 	psge += ioc->SGE_size;
2277 
2278 	/* response */
2279 	flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2280 		MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2281 		MPI_SGE_FLAGS_IOC_TO_HOST |
2282 		MPI_SGE_FLAGS_END_OF_BUFFER;
2283 
2284 	flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2285 	flagsLength |= blk_rq_bytes(rsp) + 4;
2286 	dma_addr_in =  pci_map_single(ioc->pcidev, bio_data(rsp->bio),
2287 				      blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
2288 	if (!dma_addr_in)
2289 		goto unmap;
2290 	ioc->add_sge(psge, flagsLength, dma_addr_in);
2291 
2292 	INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2293 	mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2294 
2295 	timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2296 	if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2297 		ret = -ETIME;
2298 		mpt_free_msg_frame(ioc, mf);
2299 		mf = NULL;
2300 		if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2301 			goto unmap;
2302 		if (!timeleft)
2303 			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2304 		goto unmap;
2305 	}
2306 	mf = NULL;
2307 
2308 	if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2309 		SmpPassthroughReply_t *smprep;
2310 
2311 		smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2312 		memcpy(req->sense, smprep, sizeof(*smprep));
2313 		req->sense_len = sizeof(*smprep);
2314 		req->resid_len = 0;
2315 		rsp->resid_len -= smprep->ResponseDataLength;
2316 	} else {
2317 		printk(MYIOC_s_ERR_FMT
2318 		    "%s: smp passthru reply failed to be returned\n",
2319 		    ioc->name, __func__);
2320 		ret = -ENXIO;
2321 	}
2322 unmap:
2323 	if (dma_addr_out)
2324 		pci_unmap_single(ioc->pcidev, dma_addr_out, blk_rq_bytes(req),
2325 				 PCI_DMA_BIDIRECTIONAL);
2326 	if (dma_addr_in)
2327 		pci_unmap_single(ioc->pcidev, dma_addr_in, blk_rq_bytes(rsp),
2328 				 PCI_DMA_BIDIRECTIONAL);
2329 put_mf:
2330 	if (mf)
2331 		mpt_free_msg_frame(ioc, mf);
2332 out_unlock:
2333 	CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2334 	mutex_unlock(&ioc->sas_mgmt.mutex);
2335 out:
2336 	return ret;
2337 }
2338 
2339 static struct sas_function_template mptsas_transport_functions = {
2340 	.get_linkerrors		= mptsas_get_linkerrors,
2341 	.get_enclosure_identifier = mptsas_get_enclosure_identifier,
2342 	.get_bay_identifier	= mptsas_get_bay_identifier,
2343 	.phy_reset		= mptsas_phy_reset,
2344 	.smp_handler		= mptsas_smp_handler,
2345 };
2346 
2347 static struct scsi_transport_template *mptsas_transport_template;
2348 
2349 static int
2350 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
2351 {
2352 	ConfigExtendedPageHeader_t hdr;
2353 	CONFIGPARMS cfg;
2354 	SasIOUnitPage0_t *buffer;
2355 	dma_addr_t dma_handle;
2356 	int error, i;
2357 
2358 	hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
2359 	hdr.ExtPageLength = 0;
2360 	hdr.PageNumber = 0;
2361 	hdr.Reserved1 = 0;
2362 	hdr.Reserved2 = 0;
2363 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2364 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2365 
2366 	cfg.cfghdr.ehdr = &hdr;
2367 	cfg.physAddr = -1;
2368 	cfg.pageAddr = 0;
2369 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2370 	cfg.dir = 0;	/* read */
2371 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2372 
2373 	error = mpt_config(ioc, &cfg);
2374 	if (error)
2375 		goto out;
2376 	if (!hdr.ExtPageLength) {
2377 		error = -ENXIO;
2378 		goto out;
2379 	}
2380 
2381 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2382 					    &dma_handle);
2383 	if (!buffer) {
2384 		error = -ENOMEM;
2385 		goto out;
2386 	}
2387 
2388 	cfg.physAddr = dma_handle;
2389 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2390 
2391 	error = mpt_config(ioc, &cfg);
2392 	if (error)
2393 		goto out_free_consistent;
2394 
2395 	port_info->num_phys = buffer->NumPhys;
2396 	port_info->phy_info = kcalloc(port_info->num_phys,
2397 		sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2398 	if (!port_info->phy_info) {
2399 		error = -ENOMEM;
2400 		goto out_free_consistent;
2401 	}
2402 
2403 	ioc->nvdata_version_persistent =
2404 	    le16_to_cpu(buffer->NvdataVersionPersistent);
2405 	ioc->nvdata_version_default =
2406 	    le16_to_cpu(buffer->NvdataVersionDefault);
2407 
2408 	for (i = 0; i < port_info->num_phys; i++) {
2409 		mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
2410 		port_info->phy_info[i].phy_id = i;
2411 		port_info->phy_info[i].port_id =
2412 		    buffer->PhyData[i].Port;
2413 		port_info->phy_info[i].negotiated_link_rate =
2414 		    buffer->PhyData[i].NegotiatedLinkRate;
2415 		port_info->phy_info[i].portinfo = port_info;
2416 		port_info->phy_info[i].handle =
2417 		    le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
2418 	}
2419 
2420  out_free_consistent:
2421 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2422 			    buffer, dma_handle);
2423  out:
2424 	return error;
2425 }
2426 
2427 static int
2428 mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
2429 {
2430 	ConfigExtendedPageHeader_t hdr;
2431 	CONFIGPARMS cfg;
2432 	SasIOUnitPage1_t *buffer;
2433 	dma_addr_t dma_handle;
2434 	int error;
2435 	u8 device_missing_delay;
2436 
2437 	memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
2438 	memset(&cfg, 0, sizeof(CONFIGPARMS));
2439 
2440 	cfg.cfghdr.ehdr = &hdr;
2441 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2442 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2443 	cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2444 	cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
2445 	cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
2446 	cfg.cfghdr.ehdr->PageNumber = 1;
2447 
2448 	error = mpt_config(ioc, &cfg);
2449 	if (error)
2450 		goto out;
2451 	if (!hdr.ExtPageLength) {
2452 		error = -ENXIO;
2453 		goto out;
2454 	}
2455 
2456 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2457 					    &dma_handle);
2458 	if (!buffer) {
2459 		error = -ENOMEM;
2460 		goto out;
2461 	}
2462 
2463 	cfg.physAddr = dma_handle;
2464 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2465 
2466 	error = mpt_config(ioc, &cfg);
2467 	if (error)
2468 		goto out_free_consistent;
2469 
2470 	ioc->io_missing_delay  =
2471 	    le16_to_cpu(buffer->IODeviceMissingDelay);
2472 	device_missing_delay = buffer->ReportDeviceMissingDelay;
2473 	ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
2474 	    (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
2475 	    device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
2476 
2477  out_free_consistent:
2478 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2479 			    buffer, dma_handle);
2480  out:
2481 	return error;
2482 }
2483 
2484 static int
2485 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2486 		u32 form, u32 form_specific)
2487 {
2488 	ConfigExtendedPageHeader_t hdr;
2489 	CONFIGPARMS cfg;
2490 	SasPhyPage0_t *buffer;
2491 	dma_addr_t dma_handle;
2492 	int error;
2493 
2494 	hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
2495 	hdr.ExtPageLength = 0;
2496 	hdr.PageNumber = 0;
2497 	hdr.Reserved1 = 0;
2498 	hdr.Reserved2 = 0;
2499 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2500 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
2501 
2502 	cfg.cfghdr.ehdr = &hdr;
2503 	cfg.dir = 0;	/* read */
2504 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2505 
2506 	/* Get Phy Pg 0 for each Phy. */
2507 	cfg.physAddr = -1;
2508 	cfg.pageAddr = form + form_specific;
2509 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2510 
2511 	error = mpt_config(ioc, &cfg);
2512 	if (error)
2513 		goto out;
2514 
2515 	if (!hdr.ExtPageLength) {
2516 		error = -ENXIO;
2517 		goto out;
2518 	}
2519 
2520 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2521 				      &dma_handle);
2522 	if (!buffer) {
2523 		error = -ENOMEM;
2524 		goto out;
2525 	}
2526 
2527 	cfg.physAddr = dma_handle;
2528 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2529 
2530 	error = mpt_config(ioc, &cfg);
2531 	if (error)
2532 		goto out_free_consistent;
2533 
2534 	mptsas_print_phy_pg0(ioc, buffer);
2535 
2536 	phy_info->hw_link_rate = buffer->HwLinkRate;
2537 	phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2538 	phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2539 	phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2540 
2541  out_free_consistent:
2542 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2543 			    buffer, dma_handle);
2544  out:
2545 	return error;
2546 }
2547 
2548 static int
2549 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
2550 		u32 form, u32 form_specific)
2551 {
2552 	ConfigExtendedPageHeader_t hdr;
2553 	CONFIGPARMS cfg;
2554 	SasDevicePage0_t *buffer;
2555 	dma_addr_t dma_handle;
2556 	__le64 sas_address;
2557 	int error=0;
2558 
2559 	hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
2560 	hdr.ExtPageLength = 0;
2561 	hdr.PageNumber = 0;
2562 	hdr.Reserved1 = 0;
2563 	hdr.Reserved2 = 0;
2564 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2565 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
2566 
2567 	cfg.cfghdr.ehdr = &hdr;
2568 	cfg.pageAddr = form + form_specific;
2569 	cfg.physAddr = -1;
2570 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2571 	cfg.dir = 0;	/* read */
2572 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2573 
2574 	memset(device_info, 0, sizeof(struct mptsas_devinfo));
2575 	error = mpt_config(ioc, &cfg);
2576 	if (error)
2577 		goto out;
2578 	if (!hdr.ExtPageLength) {
2579 		error = -ENXIO;
2580 		goto out;
2581 	}
2582 
2583 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2584 				      &dma_handle);
2585 	if (!buffer) {
2586 		error = -ENOMEM;
2587 		goto out;
2588 	}
2589 
2590 	cfg.physAddr = dma_handle;
2591 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2592 
2593 	error = mpt_config(ioc, &cfg);
2594 
2595 	if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2596 		error = -ENODEV;
2597 		goto out_free_consistent;
2598 	}
2599 
2600 	if (error)
2601 		goto out_free_consistent;
2602 
2603 	mptsas_print_device_pg0(ioc, buffer);
2604 
2605 	memset(device_info, 0, sizeof(struct mptsas_devinfo));
2606 	device_info->handle = le16_to_cpu(buffer->DevHandle);
2607 	device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
2608 	device_info->handle_enclosure =
2609 	    le16_to_cpu(buffer->EnclosureHandle);
2610 	device_info->slot = le16_to_cpu(buffer->Slot);
2611 	device_info->phy_id = buffer->PhyNum;
2612 	device_info->port_id = buffer->PhysicalPort;
2613 	device_info->id = buffer->TargetID;
2614 	device_info->phys_disk_num = ~0;
2615 	device_info->channel = buffer->Bus;
2616 	memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2617 	device_info->sas_address = le64_to_cpu(sas_address);
2618 	device_info->device_info =
2619 	    le32_to_cpu(buffer->DeviceInfo);
2620 	device_info->flags = le16_to_cpu(buffer->Flags);
2621 
2622  out_free_consistent:
2623 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2624 			    buffer, dma_handle);
2625  out:
2626 	return error;
2627 }
2628 
2629 static int
2630 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
2631 		u32 form, u32 form_specific)
2632 {
2633 	ConfigExtendedPageHeader_t hdr;
2634 	CONFIGPARMS cfg;
2635 	SasExpanderPage0_t *buffer;
2636 	dma_addr_t dma_handle;
2637 	int i, error;
2638 	__le64 sas_address;
2639 
2640 	memset(port_info, 0, sizeof(struct mptsas_portinfo));
2641 	hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
2642 	hdr.ExtPageLength = 0;
2643 	hdr.PageNumber = 0;
2644 	hdr.Reserved1 = 0;
2645 	hdr.Reserved2 = 0;
2646 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2647 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2648 
2649 	cfg.cfghdr.ehdr = &hdr;
2650 	cfg.physAddr = -1;
2651 	cfg.pageAddr = form + form_specific;
2652 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2653 	cfg.dir = 0;	/* read */
2654 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2655 
2656 	memset(port_info, 0, sizeof(struct mptsas_portinfo));
2657 	error = mpt_config(ioc, &cfg);
2658 	if (error)
2659 		goto out;
2660 
2661 	if (!hdr.ExtPageLength) {
2662 		error = -ENXIO;
2663 		goto out;
2664 	}
2665 
2666 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2667 				      &dma_handle);
2668 	if (!buffer) {
2669 		error = -ENOMEM;
2670 		goto out;
2671 	}
2672 
2673 	cfg.physAddr = dma_handle;
2674 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2675 
2676 	error = mpt_config(ioc, &cfg);
2677 	if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2678 		error = -ENODEV;
2679 		goto out_free_consistent;
2680 	}
2681 
2682 	if (error)
2683 		goto out_free_consistent;
2684 
2685 	/* save config data */
2686 	port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
2687 	port_info->phy_info = kcalloc(port_info->num_phys,
2688 		sizeof(struct mptsas_phyinfo), GFP_KERNEL);
2689 	if (!port_info->phy_info) {
2690 		error = -ENOMEM;
2691 		goto out_free_consistent;
2692 	}
2693 
2694 	memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
2695 	for (i = 0; i < port_info->num_phys; i++) {
2696 		port_info->phy_info[i].portinfo = port_info;
2697 		port_info->phy_info[i].handle =
2698 		    le16_to_cpu(buffer->DevHandle);
2699 		port_info->phy_info[i].identify.sas_address =
2700 		    le64_to_cpu(sas_address);
2701 		port_info->phy_info[i].identify.handle_parent =
2702 		    le16_to_cpu(buffer->ParentDevHandle);
2703 	}
2704 
2705  out_free_consistent:
2706 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2707 			    buffer, dma_handle);
2708  out:
2709 	return error;
2710 }
2711 
2712 static int
2713 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
2714 		u32 form, u32 form_specific)
2715 {
2716 	ConfigExtendedPageHeader_t hdr;
2717 	CONFIGPARMS cfg;
2718 	SasExpanderPage1_t *buffer;
2719 	dma_addr_t dma_handle;
2720 	int error=0;
2721 
2722 	hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
2723 	hdr.ExtPageLength = 0;
2724 	hdr.PageNumber = 1;
2725 	hdr.Reserved1 = 0;
2726 	hdr.Reserved2 = 0;
2727 	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
2728 	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
2729 
2730 	cfg.cfghdr.ehdr = &hdr;
2731 	cfg.physAddr = -1;
2732 	cfg.pageAddr = form + form_specific;
2733 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2734 	cfg.dir = 0;	/* read */
2735 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
2736 
2737 	error = mpt_config(ioc, &cfg);
2738 	if (error)
2739 		goto out;
2740 
2741 	if (!hdr.ExtPageLength) {
2742 		error = -ENXIO;
2743 		goto out;
2744 	}
2745 
2746 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2747 				      &dma_handle);
2748 	if (!buffer) {
2749 		error = -ENOMEM;
2750 		goto out;
2751 	}
2752 
2753 	cfg.physAddr = dma_handle;
2754 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2755 
2756 	error = mpt_config(ioc, &cfg);
2757 
2758 	if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
2759 		error = -ENODEV;
2760 		goto out_free_consistent;
2761 	}
2762 
2763 	if (error)
2764 		goto out_free_consistent;
2765 
2766 
2767 	mptsas_print_expander_pg1(ioc, buffer);
2768 
2769 	/* save config data */
2770 	phy_info->phy_id = buffer->PhyIdentifier;
2771 	phy_info->port_id = buffer->PhysicalPort;
2772 	phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
2773 	phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
2774 	phy_info->hw_link_rate = buffer->HwLinkRate;
2775 	phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
2776 	phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
2777 
2778  out_free_consistent:
2779 	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
2780 			    buffer, dma_handle);
2781  out:
2782 	return error;
2783 }
2784 
2785 struct rep_manu_request{
2786 	u8 smp_frame_type;
2787 	u8 function;
2788 	u8 reserved;
2789 	u8 request_length;
2790 };
2791 
2792 struct rep_manu_reply{
2793 	u8 smp_frame_type; /* 0x41 */
2794 	u8 function; /* 0x01 */
2795 	u8 function_result;
2796 	u8 response_length;
2797 	u16 expander_change_count;
2798 	u8 reserved0[2];
2799 	u8 sas_format:1;
2800 	u8 reserved1:7;
2801 	u8 reserved2[3];
2802 	u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
2803 	u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
2804 	u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
2805 	u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
2806 	u16 component_id;
2807 	u8 component_revision_id;
2808 	u8 reserved3;
2809 	u8 vendor_specific[8];
2810 };
2811 
2812 /**
2813   * mptsas_exp_repmanufacture_info -
2814   * @ioc: per adapter object
2815   * @sas_address: expander sas address
2816   * @edev: the sas_expander_device object
2817   *
2818   * Fills in the sas_expander_device object when SMP port is created.
2819   *
2820   * Returns 0 for success, non-zero for failure.
2821   */
2822 static int
2823 mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
2824 	u64 sas_address, struct sas_expander_device *edev)
2825 {
2826 	MPT_FRAME_HDR *mf;
2827 	SmpPassthroughRequest_t *smpreq;
2828 	SmpPassthroughReply_t *smprep;
2829 	struct rep_manu_reply *manufacture_reply;
2830 	struct rep_manu_request *manufacture_request;
2831 	int ret;
2832 	int flagsLength;
2833 	unsigned long timeleft;
2834 	char *psge;
2835 	unsigned long flags;
2836 	void *data_out = NULL;
2837 	dma_addr_t data_out_dma = 0;
2838 	u32 sz;
2839 
2840 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2841 	if (ioc->ioc_reset_in_progress) {
2842 		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2843 		printk(MYIOC_s_INFO_FMT "%s: host reset in progress!\n",
2844 			__func__, ioc->name);
2845 		return -EFAULT;
2846 	}
2847 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2848 
2849 	ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
2850 	if (ret)
2851 		goto out;
2852 
2853 	mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
2854 	if (!mf) {
2855 		ret = -ENOMEM;
2856 		goto out_unlock;
2857 	}
2858 
2859 	smpreq = (SmpPassthroughRequest_t *)mf;
2860 	memset(smpreq, 0, sizeof(*smpreq));
2861 
2862 	sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
2863 
2864 	data_out = pci_alloc_consistent(ioc->pcidev, sz, &data_out_dma);
2865 	if (!data_out) {
2866 		printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
2867 			__FILE__, __LINE__, __func__);
2868 		ret = -ENOMEM;
2869 		goto put_mf;
2870 	}
2871 
2872 	manufacture_request = data_out;
2873 	manufacture_request->smp_frame_type = 0x40;
2874 	manufacture_request->function = 1;
2875 	manufacture_request->reserved = 0;
2876 	manufacture_request->request_length = 0;
2877 
2878 	smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
2879 	smpreq->PhysicalPort = 0xFF;
2880 	*((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
2881 	smpreq->RequestDataLength = sizeof(struct rep_manu_request);
2882 
2883 	psge = (char *)
2884 		(((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
2885 
2886 	flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2887 		MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2888 		MPI_SGE_FLAGS_HOST_TO_IOC |
2889 		MPI_SGE_FLAGS_END_OF_BUFFER;
2890 	flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2891 	flagsLength |= sizeof(struct rep_manu_request);
2892 
2893 	ioc->add_sge(psge, flagsLength, data_out_dma);
2894 	psge += ioc->SGE_size;
2895 
2896 	flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
2897 		MPI_SGE_FLAGS_SYSTEM_ADDRESS |
2898 		MPI_SGE_FLAGS_IOC_TO_HOST |
2899 		MPI_SGE_FLAGS_END_OF_BUFFER;
2900 	flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
2901 	flagsLength |= sizeof(struct rep_manu_reply);
2902 	ioc->add_sge(psge, flagsLength, data_out_dma +
2903 	sizeof(struct rep_manu_request));
2904 
2905 	INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
2906 	mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
2907 
2908 	timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
2909 	if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
2910 		ret = -ETIME;
2911 		mpt_free_msg_frame(ioc, mf);
2912 		mf = NULL;
2913 		if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2914 			goto out_free;
2915 		if (!timeleft)
2916 			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2917 		goto out_free;
2918 	}
2919 
2920 	mf = NULL;
2921 
2922 	if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
2923 		u8 *tmp;
2924 
2925 	smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
2926 	if (le16_to_cpu(smprep->ResponseDataLength) !=
2927 		sizeof(struct rep_manu_reply))
2928 			goto out_free;
2929 
2930 	manufacture_reply = data_out + sizeof(struct rep_manu_request);
2931 	strncpy(edev->vendor_id, manufacture_reply->vendor_id,
2932 		SAS_EXPANDER_VENDOR_ID_LEN);
2933 	strncpy(edev->product_id, manufacture_reply->product_id,
2934 		SAS_EXPANDER_PRODUCT_ID_LEN);
2935 	strncpy(edev->product_rev, manufacture_reply->product_rev,
2936 		SAS_EXPANDER_PRODUCT_REV_LEN);
2937 	edev->level = manufacture_reply->sas_format;
2938 	if (manufacture_reply->sas_format) {
2939 		strncpy(edev->component_vendor_id,
2940 			manufacture_reply->component_vendor_id,
2941 				SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
2942 		tmp = (u8 *)&manufacture_reply->component_id;
2943 		edev->component_id = tmp[0] << 8 | tmp[1];
2944 		edev->component_revision_id =
2945 			manufacture_reply->component_revision_id;
2946 		}
2947 	} else {
2948 		printk(MYIOC_s_ERR_FMT
2949 			"%s: smp passthru reply failed to be returned\n",
2950 			ioc->name, __func__);
2951 		ret = -ENXIO;
2952 	}
2953 out_free:
2954 	if (data_out_dma)
2955 		pci_free_consistent(ioc->pcidev, sz, data_out, data_out_dma);
2956 put_mf:
2957 	if (mf)
2958 		mpt_free_msg_frame(ioc, mf);
2959 out_unlock:
2960 	CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
2961 	mutex_unlock(&ioc->sas_mgmt.mutex);
2962 out:
2963 	return ret;
2964  }
2965 
2966 static void
2967 mptsas_parse_device_info(struct sas_identify *identify,
2968 		struct mptsas_devinfo *device_info)
2969 {
2970 	u16 protocols;
2971 
2972 	identify->sas_address = device_info->sas_address;
2973 	identify->phy_identifier = device_info->phy_id;
2974 
2975 	/*
2976 	 * Fill in Phy Initiator Port Protocol.
2977 	 * Bits 6:3, more than one bit can be set, fall through cases.
2978 	 */
2979 	protocols = device_info->device_info & 0x78;
2980 	identify->initiator_port_protocols = 0;
2981 	if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
2982 		identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
2983 	if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
2984 		identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
2985 	if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
2986 		identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
2987 	if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
2988 		identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
2989 
2990 	/*
2991 	 * Fill in Phy Target Port Protocol.
2992 	 * Bits 10:7, more than one bit can be set, fall through cases.
2993 	 */
2994 	protocols = device_info->device_info & 0x780;
2995 	identify->target_port_protocols = 0;
2996 	if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
2997 		identify->target_port_protocols |= SAS_PROTOCOL_SSP;
2998 	if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
2999 		identify->target_port_protocols |= SAS_PROTOCOL_STP;
3000 	if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
3001 		identify->target_port_protocols |= SAS_PROTOCOL_SMP;
3002 	if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
3003 		identify->target_port_protocols |= SAS_PROTOCOL_SATA;
3004 
3005 	/*
3006 	 * Fill in Attached device type.
3007 	 */
3008 	switch (device_info->device_info &
3009 			MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
3010 	case MPI_SAS_DEVICE_INFO_NO_DEVICE:
3011 		identify->device_type = SAS_PHY_UNUSED;
3012 		break;
3013 	case MPI_SAS_DEVICE_INFO_END_DEVICE:
3014 		identify->device_type = SAS_END_DEVICE;
3015 		break;
3016 	case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
3017 		identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
3018 		break;
3019 	case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
3020 		identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
3021 		break;
3022 	}
3023 }
3024 
3025 static int mptsas_probe_one_phy(struct device *dev,
3026 		struct mptsas_phyinfo *phy_info, int index, int local)
3027 {
3028 	MPT_ADAPTER *ioc;
3029 	struct sas_phy *phy;
3030 	struct sas_port *port;
3031 	int error = 0;
3032 	VirtTarget *vtarget;
3033 
3034 	if (!dev) {
3035 		error = -ENODEV;
3036 		goto out;
3037 	}
3038 
3039 	if (!phy_info->phy) {
3040 		phy = sas_phy_alloc(dev, index);
3041 		if (!phy) {
3042 			error = -ENOMEM;
3043 			goto out;
3044 		}
3045 	} else
3046 		phy = phy_info->phy;
3047 
3048 	mptsas_parse_device_info(&phy->identify, &phy_info->identify);
3049 
3050 	/*
3051 	 * Set Negotiated link rate.
3052 	 */
3053 	switch (phy_info->negotiated_link_rate) {
3054 	case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
3055 		phy->negotiated_linkrate = SAS_PHY_DISABLED;
3056 		break;
3057 	case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
3058 		phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
3059 		break;
3060 	case MPI_SAS_IOUNIT0_RATE_1_5:
3061 		phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
3062 		break;
3063 	case MPI_SAS_IOUNIT0_RATE_3_0:
3064 		phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
3065 		break;
3066 	case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
3067 	case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
3068 	default:
3069 		phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
3070 		break;
3071 	}
3072 
3073 	/*
3074 	 * Set Max hardware link rate.
3075 	 */
3076 	switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3077 	case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
3078 		phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3079 		break;
3080 	case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3081 		phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3082 		break;
3083 	default:
3084 		break;
3085 	}
3086 
3087 	/*
3088 	 * Set Max programmed link rate.
3089 	 */
3090 	switch (phy_info->programmed_link_rate &
3091 			MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
3092 	case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
3093 		phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3094 		break;
3095 	case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
3096 		phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3097 		break;
3098 	default:
3099 		break;
3100 	}
3101 
3102 	/*
3103 	 * Set Min hardware link rate.
3104 	 */
3105 	switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
3106 	case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
3107 		phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
3108 		break;
3109 	case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3110 		phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
3111 		break;
3112 	default:
3113 		break;
3114 	}
3115 
3116 	/*
3117 	 * Set Min programmed link rate.
3118 	 */
3119 	switch (phy_info->programmed_link_rate &
3120 			MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
3121 	case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
3122 		phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
3123 		break;
3124 	case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
3125 		phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
3126 		break;
3127 	default:
3128 		break;
3129 	}
3130 
3131 	if (!phy_info->phy) {
3132 
3133 		error = sas_phy_add(phy);
3134 		if (error) {
3135 			sas_phy_free(phy);
3136 			goto out;
3137 		}
3138 		phy_info->phy = phy;
3139 	}
3140 
3141 	if (!phy_info->attached.handle ||
3142 			!phy_info->port_details)
3143 		goto out;
3144 
3145 	port = mptsas_get_port(phy_info);
3146 	ioc = phy_to_ioc(phy_info->phy);
3147 
3148 	if (phy_info->sas_port_add_phy) {
3149 
3150 		if (!port) {
3151 			port = sas_port_alloc_num(dev);
3152 			if (!port) {
3153 				error = -ENOMEM;
3154 				goto out;
3155 			}
3156 			error = sas_port_add(port);
3157 			if (error) {
3158 				dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3159 					"%s: exit at line=%d\n", ioc->name,
3160 					__func__, __LINE__));
3161 				goto out;
3162 			}
3163 			mptsas_set_port(ioc, phy_info, port);
3164 			devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
3165 			    MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
3166 			    ioc->name, port->port_identifier,
3167 			    (unsigned long long)phy_info->
3168 			    attached.sas_address));
3169 		}
3170 		dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3171 			"sas_port_add_phy: phy_id=%d\n",
3172 			ioc->name, phy_info->phy_id));
3173 		sas_port_add_phy(port, phy_info->phy);
3174 		phy_info->sas_port_add_phy = 0;
3175 		devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3176 		    MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
3177 		     phy_info->phy_id, phy_info->phy));
3178 	}
3179 	if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
3180 
3181 		struct sas_rphy *rphy;
3182 		struct device *parent;
3183 		struct sas_identify identify;
3184 
3185 		parent = dev->parent->parent;
3186 		/*
3187 		 * Let the hotplug_work thread handle processing
3188 		 * the adding/removing of devices that occur
3189 		 * after start of day.
3190 		 */
3191 		if (mptsas_is_end_device(&phy_info->attached) &&
3192 		    phy_info->attached.handle_parent) {
3193 			goto out;
3194 		}
3195 
3196 		mptsas_parse_device_info(&identify, &phy_info->attached);
3197 		if (scsi_is_host_device(parent)) {
3198 			struct mptsas_portinfo *port_info;
3199 			int i;
3200 
3201 			port_info = ioc->hba_port_info;
3202 
3203 			for (i = 0; i < port_info->num_phys; i++)
3204 				if (port_info->phy_info[i].identify.sas_address ==
3205 				    identify.sas_address) {
3206 					sas_port_mark_backlink(port);
3207 					goto out;
3208 				}
3209 
3210 		} else if (scsi_is_sas_rphy(parent)) {
3211 			struct sas_rphy *parent_rphy = dev_to_rphy(parent);
3212 			if (identify.sas_address ==
3213 			    parent_rphy->identify.sas_address) {
3214 				sas_port_mark_backlink(port);
3215 				goto out;
3216 			}
3217 		}
3218 
3219 		switch (identify.device_type) {
3220 		case SAS_END_DEVICE:
3221 			rphy = sas_end_device_alloc(port);
3222 			break;
3223 		case SAS_EDGE_EXPANDER_DEVICE:
3224 		case SAS_FANOUT_EXPANDER_DEVICE:
3225 			rphy = sas_expander_alloc(port, identify.device_type);
3226 			break;
3227 		default:
3228 			rphy = NULL;
3229 			break;
3230 		}
3231 		if (!rphy) {
3232 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3233 				"%s: exit at line=%d\n", ioc->name,
3234 				__func__, __LINE__));
3235 			goto out;
3236 		}
3237 
3238 		rphy->identify = identify;
3239 		error = sas_rphy_add(rphy);
3240 		if (error) {
3241 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3242 				"%s: exit at line=%d\n", ioc->name,
3243 				__func__, __LINE__));
3244 			sas_rphy_free(rphy);
3245 			goto out;
3246 		}
3247 		mptsas_set_rphy(ioc, phy_info, rphy);
3248 		if (identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
3249 			identify.device_type == SAS_FANOUT_EXPANDER_DEVICE)
3250 				mptsas_exp_repmanufacture_info(ioc,
3251 					identify.sas_address,
3252 					rphy_to_expander_device(rphy));
3253 	}
3254 
3255 	/* If the device exists,verify it wasn't previously flagged
3256 	as a missing device.  If so, clear it */
3257 	vtarget = mptsas_find_vtarget(ioc,
3258 	    phy_info->attached.channel,
3259 	    phy_info->attached.id);
3260 	if (vtarget && vtarget->inDMD) {
3261 		printk(KERN_INFO "Device returned, unsetting inDMD\n");
3262 		vtarget->inDMD = 0;
3263 	}
3264 
3265  out:
3266 	return error;
3267 }
3268 
3269 static int
3270 mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
3271 {
3272 	struct mptsas_portinfo *port_info, *hba;
3273 	int error = -ENOMEM, i;
3274 
3275 	hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3276 	if (! hba)
3277 		goto out;
3278 
3279 	error = mptsas_sas_io_unit_pg0(ioc, hba);
3280 	if (error)
3281 		goto out_free_port_info;
3282 
3283 	mptsas_sas_io_unit_pg1(ioc);
3284 	mutex_lock(&ioc->sas_topology_mutex);
3285 	port_info = ioc->hba_port_info;
3286 	if (!port_info) {
3287 		ioc->hba_port_info = port_info = hba;
3288 		ioc->hba_port_num_phy = port_info->num_phys;
3289 		list_add_tail(&port_info->list, &ioc->sas_topology);
3290 	} else {
3291 		for (i = 0; i < hba->num_phys; i++) {
3292 			port_info->phy_info[i].negotiated_link_rate =
3293 				hba->phy_info[i].negotiated_link_rate;
3294 			port_info->phy_info[i].handle =
3295 				hba->phy_info[i].handle;
3296 			port_info->phy_info[i].port_id =
3297 				hba->phy_info[i].port_id;
3298 		}
3299 		kfree(hba->phy_info);
3300 		kfree(hba);
3301 		hba = NULL;
3302 	}
3303 	mutex_unlock(&ioc->sas_topology_mutex);
3304 #if defined(CPQ_CIM)
3305 	ioc->num_ports = port_info->num_phys;
3306 #endif
3307 	for (i = 0; i < port_info->num_phys; i++) {
3308 		mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
3309 			(MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
3310 			 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
3311 		port_info->phy_info[i].identify.handle =
3312 		    port_info->phy_info[i].handle;
3313 		mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
3314 			(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3315 			 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3316 			 port_info->phy_info[i].identify.handle);
3317 		if (!ioc->hba_port_sas_addr)
3318 			ioc->hba_port_sas_addr =
3319 			    port_info->phy_info[i].identify.sas_address;
3320 		port_info->phy_info[i].identify.phy_id =
3321 		    port_info->phy_info[i].phy_id = i;
3322 		if (port_info->phy_info[i].attached.handle)
3323 			mptsas_sas_device_pg0(ioc,
3324 				&port_info->phy_info[i].attached,
3325 				(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3326 				 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3327 				port_info->phy_info[i].attached.handle);
3328 	}
3329 
3330 	mptsas_setup_wide_ports(ioc, port_info);
3331 
3332 	for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3333 		mptsas_probe_one_phy(&ioc->sh->shost_gendev,
3334 		    &port_info->phy_info[i], ioc->sas_index, 1);
3335 
3336 	return 0;
3337 
3338  out_free_port_info:
3339 	kfree(hba);
3340  out:
3341 	return error;
3342 }
3343 
3344 static void
3345 mptsas_expander_refresh(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
3346 {
3347 	struct mptsas_portinfo *parent;
3348 	struct device *parent_dev;
3349 	struct sas_rphy	*rphy;
3350 	int		i;
3351 	u64		sas_address; /* expander sas address */
3352 	u32		handle;
3353 
3354 	handle = port_info->phy_info[0].handle;
3355 	sas_address = port_info->phy_info[0].identify.sas_address;
3356 	for (i = 0; i < port_info->num_phys; i++) {
3357 		mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
3358 		    (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
3359 		    MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + handle);
3360 
3361 		mptsas_sas_device_pg0(ioc,
3362 		    &port_info->phy_info[i].identify,
3363 		    (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3364 		    MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3365 		    port_info->phy_info[i].identify.handle);
3366 		port_info->phy_info[i].identify.phy_id =
3367 		    port_info->phy_info[i].phy_id;
3368 
3369 		if (port_info->phy_info[i].attached.handle) {
3370 			mptsas_sas_device_pg0(ioc,
3371 			    &port_info->phy_info[i].attached,
3372 			    (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
3373 			     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3374 			    port_info->phy_info[i].attached.handle);
3375 			port_info->phy_info[i].attached.phy_id =
3376 			    port_info->phy_info[i].phy_id;
3377 		}
3378 	}
3379 
3380 	mutex_lock(&ioc->sas_topology_mutex);
3381 	parent = mptsas_find_portinfo_by_handle(ioc,
3382 	    port_info->phy_info[0].identify.handle_parent);
3383 	if (!parent) {
3384 		mutex_unlock(&ioc->sas_topology_mutex);
3385 		return;
3386 	}
3387 	for (i = 0, parent_dev = NULL; i < parent->num_phys && !parent_dev;
3388 	    i++) {
3389 		if (parent->phy_info[i].attached.sas_address == sas_address) {
3390 			rphy = mptsas_get_rphy(&parent->phy_info[i]);
3391 			parent_dev = &rphy->dev;
3392 		}
3393 	}
3394 	mutex_unlock(&ioc->sas_topology_mutex);
3395 
3396 	mptsas_setup_wide_ports(ioc, port_info);
3397 	for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
3398 		mptsas_probe_one_phy(parent_dev, &port_info->phy_info[i],
3399 		    ioc->sas_index, 0);
3400 }
3401 
3402 static void
3403 mptsas_expander_event_add(MPT_ADAPTER *ioc,
3404     MpiEventDataSasExpanderStatusChange_t *expander_data)
3405 {
3406 	struct mptsas_portinfo *port_info;
3407 	int i;
3408 	__le64 sas_address;
3409 
3410 	port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3411 	if (!port_info)
3412 		BUG();
3413 	port_info->num_phys = (expander_data->NumPhys) ?
3414 	    expander_data->NumPhys : 1;
3415 	port_info->phy_info = kcalloc(port_info->num_phys,
3416 	    sizeof(struct mptsas_phyinfo), GFP_KERNEL);
3417 	if (!port_info->phy_info)
3418 		BUG();
3419 	memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3420 	for (i = 0; i < port_info->num_phys; i++) {
3421 		port_info->phy_info[i].portinfo = port_info;
3422 		port_info->phy_info[i].handle =
3423 		    le16_to_cpu(expander_data->DevHandle);
3424 		port_info->phy_info[i].identify.sas_address =
3425 		    le64_to_cpu(sas_address);
3426 		port_info->phy_info[i].identify.handle_parent =
3427 		    le16_to_cpu(expander_data->ParentDevHandle);
3428 	}
3429 
3430 	mutex_lock(&ioc->sas_topology_mutex);
3431 	list_add_tail(&port_info->list, &ioc->sas_topology);
3432 	mutex_unlock(&ioc->sas_topology_mutex);
3433 
3434 	printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3435 	    "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3436 	    (unsigned long long)sas_address);
3437 
3438 	mptsas_expander_refresh(ioc, port_info);
3439 }
3440 
3441 /**
3442  * mptsas_delete_expander_siblings - remove siblings attached to expander
3443  * @ioc: Pointer to MPT_ADAPTER structure
3444  * @parent: the parent port_info object
3445  * @expander: the expander port_info object
3446  **/
3447 static void
3448 mptsas_delete_expander_siblings(MPT_ADAPTER *ioc, struct mptsas_portinfo
3449     *parent, struct mptsas_portinfo *expander)
3450 {
3451 	struct mptsas_phyinfo *phy_info;
3452 	struct mptsas_portinfo *port_info;
3453 	struct sas_rphy *rphy;
3454 	int i;
3455 
3456 	phy_info = expander->phy_info;
3457 	for (i = 0; i < expander->num_phys; i++, phy_info++) {
3458 		rphy = mptsas_get_rphy(phy_info);
3459 		if (!rphy)
3460 			continue;
3461 		if (rphy->identify.device_type == SAS_END_DEVICE)
3462 			mptsas_del_end_device(ioc, phy_info);
3463 	}
3464 
3465 	phy_info = expander->phy_info;
3466 	for (i = 0; i < expander->num_phys; i++, phy_info++) {
3467 		rphy = mptsas_get_rphy(phy_info);
3468 		if (!rphy)
3469 			continue;
3470 		if (rphy->identify.device_type ==
3471 		    MPI_SAS_DEVICE_INFO_EDGE_EXPANDER ||
3472 		    rphy->identify.device_type ==
3473 		    MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
3474 			port_info = mptsas_find_portinfo_by_sas_address(ioc,
3475 			    rphy->identify.sas_address);
3476 			if (!port_info)
3477 				continue;
3478 			if (port_info == parent) /* backlink rphy */
3479 				continue;
3480 			/*
3481 			Delete this expander even if the expdevpage is exists
3482 			because the parent expander is already deleted
3483 			*/
3484 			mptsas_expander_delete(ioc, port_info, 1);
3485 		}
3486 	}
3487 }
3488 
3489 
3490 /**
3491  *	mptsas_expander_delete - remove this expander
3492  *	@ioc: Pointer to MPT_ADAPTER structure
3493  *	@port_info: expander port_info struct
3494  *	@force: Flag to forcefully delete the expander
3495  *
3496  **/
3497 
3498 static void mptsas_expander_delete(MPT_ADAPTER *ioc,
3499 		struct mptsas_portinfo *port_info, u8 force)
3500 {
3501 
3502 	struct mptsas_portinfo *parent;
3503 	int		i;
3504 	u64		expander_sas_address;
3505 	struct mptsas_phyinfo *phy_info;
3506 	struct mptsas_portinfo buffer;
3507 	struct mptsas_portinfo_details *port_details;
3508 	struct sas_port *port;
3509 
3510 	if (!port_info)
3511 		return;
3512 
3513 	/* see if expander is still there before deleting */
3514 	mptsas_sas_expander_pg0(ioc, &buffer,
3515 	    (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3516 	    MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
3517 	    port_info->phy_info[0].identify.handle);
3518 
3519 	if (buffer.num_phys) {
3520 		kfree(buffer.phy_info);
3521 		if (!force)
3522 			return;
3523 	}
3524 
3525 
3526 	/*
3527 	 * Obtain the port_info instance to the parent port
3528 	 */
3529 	port_details = NULL;
3530 	expander_sas_address =
3531 	    port_info->phy_info[0].identify.sas_address;
3532 	parent = mptsas_find_portinfo_by_handle(ioc,
3533 	    port_info->phy_info[0].identify.handle_parent);
3534 	mptsas_delete_expander_siblings(ioc, parent, port_info);
3535 	if (!parent)
3536 		goto out;
3537 
3538 	/*
3539 	 * Delete rphys in the parent that point
3540 	 * to this expander.
3541 	 */
3542 	phy_info = parent->phy_info;
3543 	port = NULL;
3544 	for (i = 0; i < parent->num_phys; i++, phy_info++) {
3545 		if (!phy_info->phy)
3546 			continue;
3547 		if (phy_info->attached.sas_address !=
3548 		    expander_sas_address)
3549 			continue;
3550 		if (!port) {
3551 			port = mptsas_get_port(phy_info);
3552 			port_details = phy_info->port_details;
3553 		}
3554 		dev_printk(KERN_DEBUG, &phy_info->phy->dev,
3555 		    MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n", ioc->name,
3556 		    phy_info->phy_id, phy_info->phy);
3557 		sas_port_delete_phy(port, phy_info->phy);
3558 	}
3559 	if (port) {
3560 		dev_printk(KERN_DEBUG, &port->dev,
3561 		    MYIOC_s_FMT "delete port %d, sas_addr (0x%llx)\n",
3562 		    ioc->name, port->port_identifier,
3563 		    (unsigned long long)expander_sas_address);
3564 		sas_port_delete(port);
3565 		mptsas_port_delete(ioc, port_details);
3566 	}
3567  out:
3568 
3569 	printk(MYIOC_s_INFO_FMT "delete expander: num_phys %d, "
3570 	    "sas_addr (0x%llx)\n",  ioc->name, port_info->num_phys,
3571 	    (unsigned long long)expander_sas_address);
3572 
3573 	/*
3574 	 * free link
3575 	 */
3576 	list_del(&port_info->list);
3577 	kfree(port_info->phy_info);
3578 	kfree(port_info);
3579 }
3580 
3581 
3582 /**
3583  * mptsas_send_expander_event - expanders events
3584  * @ioc: Pointer to MPT_ADAPTER structure
3585  * @expander_data: event data
3586  *
3587  *
3588  * This function handles adding, removing, and refreshing
3589  * device handles within the expander objects.
3590  */
3591 static void
3592 mptsas_send_expander_event(struct fw_event_work *fw_event)
3593 {
3594 	MPT_ADAPTER *ioc;
3595 	MpiEventDataSasExpanderStatusChange_t *expander_data;
3596 	struct mptsas_portinfo *port_info;
3597 	__le64 sas_address;
3598 	int i;
3599 
3600 	ioc = fw_event->ioc;
3601 	expander_data = (MpiEventDataSasExpanderStatusChange_t *)
3602 	    fw_event->event_data;
3603 	memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
3604 	sas_address = le64_to_cpu(sas_address);
3605 	port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3606 
3607 	if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
3608 		if (port_info) {
3609 			for (i = 0; i < port_info->num_phys; i++) {
3610 				port_info->phy_info[i].portinfo = port_info;
3611 				port_info->phy_info[i].handle =
3612 				    le16_to_cpu(expander_data->DevHandle);
3613 				port_info->phy_info[i].identify.sas_address =
3614 				    le64_to_cpu(sas_address);
3615 				port_info->phy_info[i].identify.handle_parent =
3616 				    le16_to_cpu(expander_data->ParentDevHandle);
3617 			}
3618 			mptsas_expander_refresh(ioc, port_info);
3619 		} else if (!port_info && expander_data->NumPhys)
3620 			mptsas_expander_event_add(ioc, expander_data);
3621 	} else if (expander_data->ReasonCode ==
3622 	    MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING)
3623 		mptsas_expander_delete(ioc, port_info, 0);
3624 
3625 	mptsas_free_fw_event(ioc, fw_event);
3626 }
3627 
3628 
3629 /**
3630  * mptsas_expander_add -
3631  * @ioc: Pointer to MPT_ADAPTER structure
3632  * @handle:
3633  *
3634  */
3635 struct mptsas_portinfo *
3636 mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
3637 {
3638 	struct mptsas_portinfo buffer, *port_info;
3639 	int i;
3640 
3641 	if ((mptsas_sas_expander_pg0(ioc, &buffer,
3642 	    (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
3643 	    MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
3644 		return NULL;
3645 
3646 	port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_ATOMIC);
3647 	if (!port_info) {
3648 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3649 		"%s: exit at line=%d\n", ioc->name,
3650 		__func__, __LINE__));
3651 		return NULL;
3652 	}
3653 	port_info->num_phys = buffer.num_phys;
3654 	port_info->phy_info = buffer.phy_info;
3655 	for (i = 0; i < port_info->num_phys; i++)
3656 		port_info->phy_info[i].portinfo = port_info;
3657 	mutex_lock(&ioc->sas_topology_mutex);
3658 	list_add_tail(&port_info->list, &ioc->sas_topology);
3659 	mutex_unlock(&ioc->sas_topology_mutex);
3660 	printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3661 	    "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3662 	    (unsigned long long)buffer.phy_info[0].identify.sas_address);
3663 	mptsas_expander_refresh(ioc, port_info);
3664 	return port_info;
3665 }
3666 
3667 static void
3668 mptsas_send_link_status_event(struct fw_event_work *fw_event)
3669 {
3670 	MPT_ADAPTER *ioc;
3671 	MpiEventDataSasPhyLinkStatus_t *link_data;
3672 	struct mptsas_portinfo *port_info;
3673 	struct mptsas_phyinfo *phy_info = NULL;
3674 	__le64 sas_address;
3675 	u8 phy_num;
3676 	u8 link_rate;
3677 
3678 	ioc = fw_event->ioc;
3679 	link_data = (MpiEventDataSasPhyLinkStatus_t *)fw_event->event_data;
3680 
3681 	memcpy(&sas_address, &link_data->SASAddress, sizeof(__le64));
3682 	sas_address = le64_to_cpu(sas_address);
3683 	link_rate = link_data->LinkRates >> 4;
3684 	phy_num = link_data->PhyNum;
3685 
3686 	port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
3687 	if (port_info) {
3688 		phy_info = &port_info->phy_info[phy_num];
3689 		if (phy_info)
3690 			phy_info->negotiated_link_rate = link_rate;
3691 	}
3692 
3693 	if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
3694 	    link_rate == MPI_SAS_IOUNIT0_RATE_3_0) {
3695 
3696 		if (!port_info) {
3697 			if (ioc->old_sas_discovery_protocal) {
3698 				port_info = mptsas_expander_add(ioc,
3699 					le16_to_cpu(link_data->DevHandle));
3700 				if (port_info)
3701 					goto out;
3702 			}
3703 			goto out;
3704 		}
3705 
3706 		if (port_info == ioc->hba_port_info)
3707 			mptsas_probe_hba_phys(ioc);
3708 		else
3709 			mptsas_expander_refresh(ioc, port_info);
3710 	} else if (phy_info && phy_info->phy) {
3711 		if (link_rate ==  MPI_SAS_IOUNIT0_RATE_PHY_DISABLED)
3712 			phy_info->phy->negotiated_linkrate =
3713 			    SAS_PHY_DISABLED;
3714 		else if (link_rate ==
3715 		    MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
3716 			phy_info->phy->negotiated_linkrate =
3717 			    SAS_LINK_RATE_FAILED;
3718 		else {
3719 			phy_info->phy->negotiated_linkrate =
3720 			    SAS_LINK_RATE_UNKNOWN;
3721 			if (ioc->device_missing_delay &&
3722 			    mptsas_is_end_device(&phy_info->attached)) {
3723 				struct scsi_device		*sdev;
3724 				VirtDevice			*vdevice;
3725 				u8	channel, id;
3726 				id = phy_info->attached.id;
3727 				channel = phy_info->attached.channel;
3728 				devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3729 				"Link down for fw_id %d:fw_channel %d\n",
3730 				    ioc->name, phy_info->attached.id,
3731 				    phy_info->attached.channel));
3732 
3733 				shost_for_each_device(sdev, ioc->sh) {
3734 					vdevice = sdev->hostdata;
3735 					if ((vdevice == NULL) ||
3736 						(vdevice->vtarget == NULL))
3737 						continue;
3738 					if ((vdevice->vtarget->tflags &
3739 					    MPT_TARGET_FLAGS_RAID_COMPONENT ||
3740 					    vdevice->vtarget->raidVolume))
3741 						continue;
3742 					if (vdevice->vtarget->id == id &&
3743 						vdevice->vtarget->channel ==
3744 						channel)
3745 						devtprintk(ioc,
3746 						printk(MYIOC_s_DEBUG_FMT
3747 						"SDEV OUTSTANDING CMDS"
3748 						"%d\n", ioc->name,
3749 						sdev->device_busy));
3750 				}
3751 
3752 			}
3753 		}
3754 	}
3755  out:
3756 	mptsas_free_fw_event(ioc, fw_event);
3757 }
3758 
3759 static void
3760 mptsas_not_responding_devices(MPT_ADAPTER *ioc)
3761 {
3762 	struct mptsas_portinfo buffer, *port_info;
3763 	struct mptsas_device_info	*sas_info;
3764 	struct mptsas_devinfo sas_device;
3765 	u32	handle;
3766 	VirtTarget *vtarget = NULL;
3767 	struct mptsas_phyinfo *phy_info;
3768 	u8 found_expander;
3769 	int retval, retry_count;
3770 	unsigned long flags;
3771 
3772 	mpt_findImVolumes(ioc);
3773 
3774 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3775 	if (ioc->ioc_reset_in_progress) {
3776 		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3777 		   "%s: exiting due to a parallel reset \n", ioc->name,
3778 		    __func__));
3779 		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3780 		return;
3781 	}
3782 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
3783 
3784 	/* devices, logical volumes */
3785 	mutex_lock(&ioc->sas_device_info_mutex);
3786  redo_device_scan:
3787 	list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
3788 		if (sas_info->is_cached)
3789 			continue;
3790 		if (!sas_info->is_logical_volume) {
3791 			sas_device.handle = 0;
3792 			retry_count = 0;
3793 retry_page:
3794 			retval = mptsas_sas_device_pg0(ioc, &sas_device,
3795 				(MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
3796 				<< MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
3797 				(sas_info->fw.channel << 8) +
3798 				sas_info->fw.id);
3799 
3800 			if (sas_device.handle)
3801 				continue;
3802 			if (retval == -EBUSY) {
3803 				spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
3804 				if (ioc->ioc_reset_in_progress) {
3805 					dfailprintk(ioc,
3806 					printk(MYIOC_s_DEBUG_FMT
3807 					"%s: exiting due to reset\n",
3808 					ioc->name, __func__));
3809 					spin_unlock_irqrestore
3810 					(&ioc->taskmgmt_lock, flags);
3811 					mutex_unlock(&ioc->
3812 					sas_device_info_mutex);
3813 					return;
3814 				}
3815 				spin_unlock_irqrestore(&ioc->taskmgmt_lock,
3816 				flags);
3817 			}
3818 
3819 			if (retval && (retval != -ENODEV)) {
3820 				if (retry_count < 10) {
3821 					retry_count++;
3822 					goto retry_page;
3823 				} else {
3824 					devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3825 					"%s: Config page retry exceeded retry "
3826 					"count deleting device 0x%llx\n",
3827 					ioc->name, __func__,
3828 					sas_info->sas_address));
3829 				}
3830 			}
3831 
3832 			/* delete device */
3833 			vtarget = mptsas_find_vtarget(ioc,
3834 				sas_info->fw.channel, sas_info->fw.id);
3835 
3836 			if (vtarget)
3837 				vtarget->deleted = 1;
3838 
3839 			phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
3840 					sas_info->sas_address);
3841 
3842 			if (phy_info) {
3843 				mptsas_del_end_device(ioc, phy_info);
3844 				goto redo_device_scan;
3845 			}
3846 		} else
3847 			mptsas_volume_delete(ioc, sas_info->fw.id);
3848 	}
3849 	mutex_unlock(&ioc->sas_device_info_mutex);
3850 
3851 	/* expanders */
3852 	mutex_lock(&ioc->sas_topology_mutex);
3853  redo_expander_scan:
3854 	list_for_each_entry(port_info, &ioc->sas_topology, list) {
3855 
3856 		if (port_info->phy_info &&
3857 		    (!(port_info->phy_info[0].identify.device_info &
3858 		    MPI_SAS_DEVICE_INFO_SMP_TARGET)))
3859 			continue;
3860 		found_expander = 0;
3861 		handle = 0xFFFF;
3862 		while (!mptsas_sas_expander_pg0(ioc, &buffer,
3863 		    (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3864 		     MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
3865 		    !found_expander) {
3866 
3867 			handle = buffer.phy_info[0].handle;
3868 			if (buffer.phy_info[0].identify.sas_address ==
3869 			    port_info->phy_info[0].identify.sas_address) {
3870 				found_expander = 1;
3871 			}
3872 			kfree(buffer.phy_info);
3873 		}
3874 
3875 		if (!found_expander) {
3876 			mptsas_expander_delete(ioc, port_info, 0);
3877 			goto redo_expander_scan;
3878 		}
3879 	}
3880 	mutex_unlock(&ioc->sas_topology_mutex);
3881 }
3882 
3883 /**
3884  *	mptsas_probe_expanders - adding expanders
3885  *	@ioc: Pointer to MPT_ADAPTER structure
3886  *
3887  **/
3888 static void
3889 mptsas_probe_expanders(MPT_ADAPTER *ioc)
3890 {
3891 	struct mptsas_portinfo buffer, *port_info;
3892 	u32 			handle;
3893 	int i;
3894 
3895 	handle = 0xFFFF;
3896 	while (!mptsas_sas_expander_pg0(ioc, &buffer,
3897 	    (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
3898 	     MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)) {
3899 
3900 		handle = buffer.phy_info[0].handle;
3901 		port_info = mptsas_find_portinfo_by_sas_address(ioc,
3902 		    buffer.phy_info[0].identify.sas_address);
3903 
3904 		if (port_info) {
3905 			/* refreshing handles */
3906 			for (i = 0; i < buffer.num_phys; i++) {
3907 				port_info->phy_info[i].handle = handle;
3908 				port_info->phy_info[i].identify.handle_parent =
3909 				    buffer.phy_info[0].identify.handle_parent;
3910 			}
3911 			mptsas_expander_refresh(ioc, port_info);
3912 			kfree(buffer.phy_info);
3913 			continue;
3914 		}
3915 
3916 		port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
3917 		if (!port_info) {
3918 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
3919 			"%s: exit at line=%d\n", ioc->name,
3920 			__func__, __LINE__));
3921 			return;
3922 		}
3923 		port_info->num_phys = buffer.num_phys;
3924 		port_info->phy_info = buffer.phy_info;
3925 		for (i = 0; i < port_info->num_phys; i++)
3926 			port_info->phy_info[i].portinfo = port_info;
3927 		mutex_lock(&ioc->sas_topology_mutex);
3928 		list_add_tail(&port_info->list, &ioc->sas_topology);
3929 		mutex_unlock(&ioc->sas_topology_mutex);
3930 		printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
3931 		    "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
3932 	    (unsigned long long)buffer.phy_info[0].identify.sas_address);
3933 		mptsas_expander_refresh(ioc, port_info);
3934 	}
3935 }
3936 
3937 static void
3938 mptsas_probe_devices(MPT_ADAPTER *ioc)
3939 {
3940 	u16 handle;
3941 	struct mptsas_devinfo sas_device;
3942 	struct mptsas_phyinfo *phy_info;
3943 
3944 	handle = 0xFFFF;
3945 	while (!(mptsas_sas_device_pg0(ioc, &sas_device,
3946 	    MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
3947 
3948 		handle = sas_device.handle;
3949 
3950 		if ((sas_device.device_info &
3951 		     (MPI_SAS_DEVICE_INFO_SSP_TARGET |
3952 		      MPI_SAS_DEVICE_INFO_STP_TARGET |
3953 		      MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
3954 			continue;
3955 
3956 		/* If there is no FW B_T mapping for this device then continue
3957 		 * */
3958 		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
3959 			|| !(sas_device.flags &
3960 			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
3961 			continue;
3962 
3963 		phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
3964 		if (!phy_info)
3965 			continue;
3966 
3967 		if (mptsas_get_rphy(phy_info))
3968 			continue;
3969 
3970 		mptsas_add_end_device(ioc, phy_info);
3971 	}
3972 }
3973 
3974 /**
3975  *	mptsas_scan_sas_topology -
3976  *	@ioc: Pointer to MPT_ADAPTER structure
3977  *	@sas_address:
3978  *
3979  **/
3980 static void
3981 mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
3982 {
3983 	struct scsi_device *sdev;
3984 	int i;
3985 
3986 	mptsas_probe_hba_phys(ioc);
3987 	mptsas_probe_expanders(ioc);
3988 	mptsas_probe_devices(ioc);
3989 
3990 	/*
3991 	  Reporting RAID volumes.
3992 	*/
3993 	if (!ioc->ir_firmware || !ioc->raid_data.pIocPg2 ||
3994 	    !ioc->raid_data.pIocPg2->NumActiveVolumes)
3995 		return;
3996 	for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
3997 		sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
3998 		    ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
3999 		if (sdev) {
4000 			scsi_device_put(sdev);
4001 			continue;
4002 		}
4003 		printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4004 		    "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4005 		    ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID);
4006 		scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4007 		    ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
4008 	}
4009 }
4010 
4011 
4012 static void
4013 mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
4014 {
4015 	MPT_ADAPTER *ioc;
4016 	EventDataQueueFull_t *qfull_data;
4017 	struct mptsas_device_info *sas_info;
4018 	struct scsi_device	*sdev;
4019 	int depth;
4020 	int id = -1;
4021 	int channel = -1;
4022 	int fw_id, fw_channel;
4023 	u16 current_depth;
4024 
4025 
4026 	ioc = fw_event->ioc;
4027 	qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
4028 	fw_id = qfull_data->TargetID;
4029 	fw_channel = qfull_data->Bus;
4030 	current_depth = le16_to_cpu(qfull_data->CurrentDepth);
4031 
4032 	/* if hidden raid component, look for the volume id */
4033 	mutex_lock(&ioc->sas_device_info_mutex);
4034 	if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
4035 		list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4036 		    list) {
4037 			if (sas_info->is_cached ||
4038 			    sas_info->is_logical_volume)
4039 				continue;
4040 			if (sas_info->is_hidden_raid_component &&
4041 			    (sas_info->fw.channel == fw_channel &&
4042 			    sas_info->fw.id == fw_id)) {
4043 				id = sas_info->volume_id;
4044 				channel = MPTSAS_RAID_CHANNEL;
4045 				goto out;
4046 			}
4047 		}
4048 	} else {
4049 		list_for_each_entry(sas_info, &ioc->sas_device_info_list,
4050 		    list) {
4051 			if (sas_info->is_cached ||
4052 			    sas_info->is_hidden_raid_component ||
4053 			    sas_info->is_logical_volume)
4054 				continue;
4055 			if (sas_info->fw.channel == fw_channel &&
4056 			    sas_info->fw.id == fw_id) {
4057 				id = sas_info->os.id;
4058 				channel = sas_info->os.channel;
4059 				goto out;
4060 			}
4061 		}
4062 
4063 	}
4064 
4065  out:
4066 	mutex_unlock(&ioc->sas_device_info_mutex);
4067 
4068 	if (id != -1) {
4069 		shost_for_each_device(sdev, ioc->sh) {
4070 			if (sdev->id == id && sdev->channel == channel) {
4071 				if (current_depth > sdev->queue_depth) {
4072 					sdev_printk(KERN_INFO, sdev,
4073 					    "strange observation, the queue "
4074 					    "depth is (%d) meanwhile fw queue "
4075 					    "depth (%d)\n", sdev->queue_depth,
4076 					    current_depth);
4077 					continue;
4078 				}
4079 				depth = scsi_track_queue_full(sdev,
4080 				    current_depth - 1);
4081 				if (depth > 0)
4082 					sdev_printk(KERN_INFO, sdev,
4083 					"Queue depth reduced to (%d)\n",
4084 					   depth);
4085 				else if (depth < 0)
4086 					sdev_printk(KERN_INFO, sdev,
4087 					"Tagged Command Queueing is being "
4088 					"disabled\n");
4089 				else if (depth == 0)
4090 					sdev_printk(KERN_INFO, sdev,
4091 					"Queue depth not changed yet\n");
4092 			}
4093 		}
4094 	}
4095 
4096 	mptsas_free_fw_event(ioc, fw_event);
4097 }
4098 
4099 
4100 static struct mptsas_phyinfo *
4101 mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
4102 {
4103 	struct mptsas_portinfo *port_info;
4104 	struct mptsas_phyinfo *phy_info = NULL;
4105 	int i;
4106 
4107 	mutex_lock(&ioc->sas_topology_mutex);
4108 	list_for_each_entry(port_info, &ioc->sas_topology, list) {
4109 		for (i = 0; i < port_info->num_phys; i++) {
4110 			if (!mptsas_is_end_device(
4111 				&port_info->phy_info[i].attached))
4112 				continue;
4113 			if (port_info->phy_info[i].attached.sas_address
4114 			    != sas_address)
4115 				continue;
4116 			phy_info = &port_info->phy_info[i];
4117 			break;
4118 		}
4119 	}
4120 	mutex_unlock(&ioc->sas_topology_mutex);
4121 	return phy_info;
4122 }
4123 
4124 /**
4125  *	mptsas_find_phyinfo_by_phys_disk_num -
4126  *	@ioc: Pointer to MPT_ADAPTER structure
4127  *	@phys_disk_num:
4128  *	@channel:
4129  *	@id:
4130  *
4131  **/
4132 static struct mptsas_phyinfo *
4133 mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
4134 	u8 channel, u8 id)
4135 {
4136 	struct mptsas_phyinfo *phy_info = NULL;
4137 	struct mptsas_portinfo *port_info;
4138 	RaidPhysDiskPage1_t *phys_disk = NULL;
4139 	int num_paths;
4140 	u64 sas_address = 0;
4141 	int i;
4142 
4143 	phy_info = NULL;
4144 	if (!ioc->raid_data.pIocPg3)
4145 		return NULL;
4146 	/* dual port support */
4147 	num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num);
4148 	if (!num_paths)
4149 		goto out;
4150 	phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
4151 	   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
4152 	if (!phys_disk)
4153 		goto out;
4154 	mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk);
4155 	for (i = 0; i < num_paths; i++) {
4156 		if ((phys_disk->Path[i].Flags & 1) != 0)
4157 			/* entry no longer valid */
4158 			continue;
4159 		if ((id == phys_disk->Path[i].PhysDiskID) &&
4160 		    (channel == phys_disk->Path[i].PhysDiskBus)) {
4161 			memcpy(&sas_address, &phys_disk->Path[i].WWID,
4162 				sizeof(u64));
4163 			phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4164 					sas_address);
4165 			goto out;
4166 		}
4167 	}
4168 
4169  out:
4170 	kfree(phys_disk);
4171 	if (phy_info)
4172 		return phy_info;
4173 
4174 	/*
4175 	 * Extra code to handle RAID0 case, where the sas_address is not updated
4176 	 * in phys_disk_page_1 when hotswapped
4177 	 */
4178 	mutex_lock(&ioc->sas_topology_mutex);
4179 	list_for_each_entry(port_info, &ioc->sas_topology, list) {
4180 		for (i = 0; i < port_info->num_phys && !phy_info; i++) {
4181 			if (!mptsas_is_end_device(
4182 				&port_info->phy_info[i].attached))
4183 				continue;
4184 			if (port_info->phy_info[i].attached.phys_disk_num == ~0)
4185 				continue;
4186 			if ((port_info->phy_info[i].attached.phys_disk_num ==
4187 			    phys_disk_num) &&
4188 			    (port_info->phy_info[i].attached.id == id) &&
4189 			    (port_info->phy_info[i].attached.channel ==
4190 			     channel))
4191 				phy_info = &port_info->phy_info[i];
4192 		}
4193 	}
4194 	mutex_unlock(&ioc->sas_topology_mutex);
4195 	return phy_info;
4196 }
4197 
4198 static void
4199 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
4200 {
4201 	int rc;
4202 
4203 	sdev->no_uld_attach = data ? 1 : 0;
4204 	rc = scsi_device_reprobe(sdev);
4205 }
4206 
4207 static void
4208 mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
4209 {
4210 	starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
4211 			mptsas_reprobe_lun);
4212 }
4213 
4214 static void
4215 mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
4216 {
4217 	CONFIGPARMS			cfg;
4218 	ConfigPageHeader_t		hdr;
4219 	dma_addr_t			dma_handle;
4220 	pRaidVolumePage0_t		buffer = NULL;
4221 	RaidPhysDiskPage0_t 		phys_disk;
4222 	int				i;
4223 	struct mptsas_phyinfo	*phy_info;
4224 	struct mptsas_devinfo		sas_device;
4225 
4226 	memset(&cfg, 0 , sizeof(CONFIGPARMS));
4227 	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4228 	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
4229 	cfg.pageAddr = (channel << 8) + id;
4230 	cfg.cfghdr.hdr = &hdr;
4231 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4232 	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
4233 
4234 	if (mpt_config(ioc, &cfg) != 0)
4235 		goto out;
4236 
4237 	if (!hdr.PageLength)
4238 		goto out;
4239 
4240 	buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4241 	    &dma_handle);
4242 
4243 	if (!buffer)
4244 		goto out;
4245 
4246 	cfg.physAddr = dma_handle;
4247 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4248 
4249 	if (mpt_config(ioc, &cfg) != 0)
4250 		goto out;
4251 
4252 	if (!(buffer->VolumeStatus.Flags &
4253 	    MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
4254 		goto out;
4255 
4256 	if (!buffer->NumPhysDisks)
4257 		goto out;
4258 
4259 	for (i = 0; i < buffer->NumPhysDisks; i++) {
4260 
4261 		if (mpt_raid_phys_disk_pg0(ioc,
4262 		    buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
4263 			continue;
4264 
4265 		if (mptsas_sas_device_pg0(ioc, &sas_device,
4266 		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4267 		     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4268 			(phys_disk.PhysDiskBus << 8) +
4269 			phys_disk.PhysDiskID))
4270 			continue;
4271 
4272 		/* If there is no FW B_T mapping for this device then continue
4273 		 * */
4274 		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4275 			|| !(sas_device.flags &
4276 			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4277 			continue;
4278 
4279 
4280 		phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4281 		    sas_device.sas_address);
4282 		mptsas_add_end_device(ioc, phy_info);
4283 	}
4284 
4285  out:
4286 	if (buffer)
4287 		pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4288 		    dma_handle);
4289 }
4290 /*
4291  * Work queue thread to handle SAS hotplug events
4292  */
4293 static void
4294 mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
4295     struct mptsas_hotplug_event *hot_plug_info)
4296 {
4297 	struct mptsas_phyinfo *phy_info;
4298 	struct scsi_target * starget;
4299 	struct mptsas_devinfo sas_device;
4300 	VirtTarget *vtarget;
4301 	int i;
4302 	struct mptsas_portinfo *port_info;
4303 
4304 	switch (hot_plug_info->event_type) {
4305 
4306 	case MPTSAS_ADD_PHYSDISK:
4307 
4308 		if (!ioc->raid_data.pIocPg2)
4309 			break;
4310 
4311 		for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
4312 			if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
4313 			    hot_plug_info->id) {
4314 				printk(MYIOC_s_WARN_FMT "firmware bug: unable "
4315 				    "to add hidden disk - target_id matchs "
4316 				    "volume_id\n", ioc->name);
4317 				mptsas_free_fw_event(ioc, fw_event);
4318 				return;
4319 			}
4320 		}
4321 		mpt_findImVolumes(ioc);
4322 
4323 	case MPTSAS_ADD_DEVICE:
4324 		memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
4325 		mptsas_sas_device_pg0(ioc, &sas_device,
4326 		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4327 		    MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4328 		    (hot_plug_info->channel << 8) +
4329 		    hot_plug_info->id);
4330 
4331 		/* If there is no FW B_T mapping for this device then break
4332 		 * */
4333 		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4334 			|| !(sas_device.flags &
4335 			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4336 			break;
4337 
4338 		if (!sas_device.handle)
4339 			return;
4340 
4341 		phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
4342 		/* Only For SATA Device ADD */
4343 		if (!phy_info && (sas_device.device_info &
4344 				MPI_SAS_DEVICE_INFO_SATA_DEVICE)) {
4345 			devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4346 				"%s %d SATA HOT PLUG: "
4347 				"parent handle of device %x\n", ioc->name,
4348 				__func__, __LINE__, sas_device.handle_parent));
4349 			port_info = mptsas_find_portinfo_by_handle(ioc,
4350 				sas_device.handle_parent);
4351 
4352 			if (port_info == ioc->hba_port_info)
4353 				mptsas_probe_hba_phys(ioc);
4354 			else if (port_info)
4355 				mptsas_expander_refresh(ioc, port_info);
4356 			else {
4357 				dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4358 					"%s %d port info is NULL\n",
4359 					ioc->name, __func__, __LINE__));
4360 				break;
4361 			}
4362 			phy_info = mptsas_refreshing_device_handles
4363 				(ioc, &sas_device);
4364 		}
4365 
4366 		if (!phy_info) {
4367 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4368 				"%s %d phy info is NULL\n",
4369 				ioc->name, __func__, __LINE__));
4370 			break;
4371 		}
4372 
4373 		if (mptsas_get_rphy(phy_info))
4374 			break;
4375 
4376 		mptsas_add_end_device(ioc, phy_info);
4377 		break;
4378 
4379 	case MPTSAS_DEL_DEVICE:
4380 		phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4381 		    hot_plug_info->sas_address);
4382 		mptsas_del_end_device(ioc, phy_info);
4383 		break;
4384 
4385 	case MPTSAS_DEL_PHYSDISK:
4386 
4387 		mpt_findImVolumes(ioc);
4388 
4389 		phy_info = mptsas_find_phyinfo_by_phys_disk_num(
4390 				ioc, hot_plug_info->phys_disk_num,
4391 				hot_plug_info->channel,
4392 				hot_plug_info->id);
4393 		mptsas_del_end_device(ioc, phy_info);
4394 		break;
4395 
4396 	case MPTSAS_ADD_PHYSDISK_REPROBE:
4397 
4398 		if (mptsas_sas_device_pg0(ioc, &sas_device,
4399 		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4400 		     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4401 		    (hot_plug_info->channel << 8) + hot_plug_info->id)) {
4402 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4403 			"%s: fw_id=%d exit at line=%d\n", ioc->name,
4404 				 __func__, hot_plug_info->id, __LINE__));
4405 			break;
4406 		}
4407 
4408 		/* If there is no FW B_T mapping for this device then break
4409 		 * */
4410 		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4411 			|| !(sas_device.flags &
4412 			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4413 			break;
4414 
4415 		phy_info = mptsas_find_phyinfo_by_sas_address(
4416 		    ioc, sas_device.sas_address);
4417 
4418 		if (!phy_info) {
4419 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4420 				"%s: fw_id=%d exit at line=%d\n", ioc->name,
4421 				 __func__, hot_plug_info->id, __LINE__));
4422 			break;
4423 		}
4424 
4425 		starget = mptsas_get_starget(phy_info);
4426 		if (!starget) {
4427 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4428 				"%s: fw_id=%d exit at line=%d\n", ioc->name,
4429 				 __func__, hot_plug_info->id, __LINE__));
4430 			break;
4431 		}
4432 
4433 		vtarget = starget->hostdata;
4434 		if (!vtarget) {
4435 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4436 				"%s: fw_id=%d exit at line=%d\n", ioc->name,
4437 				 __func__, hot_plug_info->id, __LINE__));
4438 			break;
4439 		}
4440 
4441 		mpt_findImVolumes(ioc);
4442 
4443 		starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
4444 		    "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4445 		    ioc->name, hot_plug_info->channel, hot_plug_info->id,
4446 		    hot_plug_info->phys_disk_num, (unsigned long long)
4447 		    sas_device.sas_address);
4448 
4449 		vtarget->id = hot_plug_info->phys_disk_num;
4450 		vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
4451 		phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
4452 		mptsas_reprobe_target(starget, 1);
4453 		break;
4454 
4455 	case MPTSAS_DEL_PHYSDISK_REPROBE:
4456 
4457 		if (mptsas_sas_device_pg0(ioc, &sas_device,
4458 		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
4459 		     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
4460 			(hot_plug_info->channel << 8) + hot_plug_info->id)) {
4461 				dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4462 				    "%s: fw_id=%d exit at line=%d\n",
4463 				    ioc->name, __func__,
4464 				    hot_plug_info->id, __LINE__));
4465 			break;
4466 		}
4467 
4468 		/* If there is no FW B_T mapping for this device then break
4469 		 * */
4470 		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
4471 			|| !(sas_device.flags &
4472 			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
4473 			break;
4474 
4475 		phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
4476 				sas_device.sas_address);
4477 		if (!phy_info) {
4478 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4479 			    "%s: fw_id=%d exit at line=%d\n", ioc->name,
4480 			 __func__, hot_plug_info->id, __LINE__));
4481 			break;
4482 		}
4483 
4484 		starget = mptsas_get_starget(phy_info);
4485 		if (!starget) {
4486 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4487 			    "%s: fw_id=%d exit at line=%d\n", ioc->name,
4488 			 __func__, hot_plug_info->id, __LINE__));
4489 			break;
4490 		}
4491 
4492 		vtarget = starget->hostdata;
4493 		if (!vtarget) {
4494 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4495 			    "%s: fw_id=%d exit at line=%d\n", ioc->name,
4496 			 __func__, hot_plug_info->id, __LINE__));
4497 			break;
4498 		}
4499 
4500 		if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
4501 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
4502 			    "%s: fw_id=%d exit at line=%d\n", ioc->name,
4503 			 __func__, hot_plug_info->id, __LINE__));
4504 			break;
4505 		}
4506 
4507 		mpt_findImVolumes(ioc);
4508 
4509 		starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
4510 		    " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
4511 		    ioc->name, hot_plug_info->channel, hot_plug_info->id,
4512 		    hot_plug_info->phys_disk_num, (unsigned long long)
4513 		    sas_device.sas_address);
4514 
4515 		vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
4516 		vtarget->id = hot_plug_info->id;
4517 		phy_info->attached.phys_disk_num = ~0;
4518 		mptsas_reprobe_target(starget, 0);
4519 		mptsas_add_device_component_by_fw(ioc,
4520 		    hot_plug_info->channel, hot_plug_info->id);
4521 		break;
4522 
4523 	case MPTSAS_ADD_RAID:
4524 
4525 		mpt_findImVolumes(ioc);
4526 		printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
4527 		    "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4528 		    hot_plug_info->id);
4529 		scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
4530 		    hot_plug_info->id, 0);
4531 		break;
4532 
4533 	case MPTSAS_DEL_RAID:
4534 
4535 		mpt_findImVolumes(ioc);
4536 		printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
4537 		    "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
4538 		    hot_plug_info->id);
4539 		scsi_remove_device(hot_plug_info->sdev);
4540 		scsi_device_put(hot_plug_info->sdev);
4541 		break;
4542 
4543 	case MPTSAS_ADD_INACTIVE_VOLUME:
4544 
4545 		mpt_findImVolumes(ioc);
4546 		mptsas_adding_inactive_raid_components(ioc,
4547 		    hot_plug_info->channel, hot_plug_info->id);
4548 		break;
4549 
4550 	default:
4551 		break;
4552 	}
4553 
4554 	mptsas_free_fw_event(ioc, fw_event);
4555 }
4556 
4557 static void
4558 mptsas_send_sas_event(struct fw_event_work *fw_event)
4559 {
4560 	MPT_ADAPTER *ioc;
4561 	struct mptsas_hotplug_event hot_plug_info;
4562 	EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
4563 	u32 device_info;
4564 	u64 sas_address;
4565 
4566 	ioc = fw_event->ioc;
4567 	sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
4568 	    fw_event->event_data;
4569 	device_info = le32_to_cpu(sas_event_data->DeviceInfo);
4570 
4571 	if ((device_info &
4572 		(MPI_SAS_DEVICE_INFO_SSP_TARGET |
4573 		MPI_SAS_DEVICE_INFO_STP_TARGET |
4574 		MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
4575 		mptsas_free_fw_event(ioc, fw_event);
4576 		return;
4577 	}
4578 
4579 	if (sas_event_data->ReasonCode ==
4580 		MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
4581 		mptbase_sas_persist_operation(ioc,
4582 		MPI_SAS_OP_CLEAR_NOT_PRESENT);
4583 		mptsas_free_fw_event(ioc, fw_event);
4584 		return;
4585 	}
4586 
4587 	switch (sas_event_data->ReasonCode) {
4588 	case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
4589 	case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
4590 		memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4591 		hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
4592 		hot_plug_info.channel = sas_event_data->Bus;
4593 		hot_plug_info.id = sas_event_data->TargetID;
4594 		hot_plug_info.phy_id = sas_event_data->PhyNum;
4595 		memcpy(&sas_address, &sas_event_data->SASAddress,
4596 		    sizeof(u64));
4597 		hot_plug_info.sas_address = le64_to_cpu(sas_address);
4598 		hot_plug_info.device_info = device_info;
4599 		if (sas_event_data->ReasonCode &
4600 		    MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
4601 			hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
4602 		else
4603 			hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
4604 		mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4605 		break;
4606 
4607 	case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
4608 		mptbase_sas_persist_operation(ioc,
4609 		    MPI_SAS_OP_CLEAR_NOT_PRESENT);
4610 		mptsas_free_fw_event(ioc, fw_event);
4611 		break;
4612 
4613 	case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
4614 	/* TODO */
4615 	case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
4616 	/* TODO */
4617 	default:
4618 		mptsas_free_fw_event(ioc, fw_event);
4619 		break;
4620 	}
4621 }
4622 
4623 static void
4624 mptsas_send_raid_event(struct fw_event_work *fw_event)
4625 {
4626 	MPT_ADAPTER *ioc;
4627 	EVENT_DATA_RAID *raid_event_data;
4628 	struct mptsas_hotplug_event hot_plug_info;
4629 	int status;
4630 	int state;
4631 	struct scsi_device *sdev = NULL;
4632 	VirtDevice *vdevice = NULL;
4633 	RaidPhysDiskPage0_t phys_disk;
4634 
4635 	ioc = fw_event->ioc;
4636 	raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
4637 	status = le32_to_cpu(raid_event_data->SettingsStatus);
4638 	state = (status >> 8) & 0xff;
4639 
4640 	memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4641 	hot_plug_info.id = raid_event_data->VolumeID;
4642 	hot_plug_info.channel = raid_event_data->VolumeBus;
4643 	hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
4644 
4645 	if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
4646 	    raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
4647 	    raid_event_data->ReasonCode ==
4648 	    MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
4649 		sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
4650 		    hot_plug_info.id, 0);
4651 		hot_plug_info.sdev = sdev;
4652 		if (sdev)
4653 			vdevice = sdev->hostdata;
4654 	}
4655 
4656 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4657 	    "ReasonCode=%02x\n", ioc->name, __func__,
4658 	    raid_event_data->ReasonCode));
4659 
4660 	switch (raid_event_data->ReasonCode) {
4661 	case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4662 		hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
4663 		break;
4664 	case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4665 		hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
4666 		break;
4667 	case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4668 		switch (state) {
4669 		case MPI_PD_STATE_ONLINE:
4670 		case MPI_PD_STATE_NOT_COMPATIBLE:
4671 			mpt_raid_phys_disk_pg0(ioc,
4672 			    raid_event_data->PhysDiskNum, &phys_disk);
4673 			hot_plug_info.id = phys_disk.PhysDiskID;
4674 			hot_plug_info.channel = phys_disk.PhysDiskBus;
4675 			hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4676 			break;
4677 		case MPI_PD_STATE_FAILED:
4678 		case MPI_PD_STATE_MISSING:
4679 		case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
4680 		case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
4681 		case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
4682 			hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4683 			break;
4684 		default:
4685 			break;
4686 		}
4687 		break;
4688 	case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4689 		if (!sdev)
4690 			break;
4691 		vdevice->vtarget->deleted = 1; /* block IO */
4692 		hot_plug_info.event_type = MPTSAS_DEL_RAID;
4693 		break;
4694 	case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4695 		if (sdev) {
4696 			scsi_device_put(sdev);
4697 			break;
4698 		}
4699 		hot_plug_info.event_type = MPTSAS_ADD_RAID;
4700 		break;
4701 	case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4702 		if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
4703 			if (!sdev)
4704 				break;
4705 			vdevice->vtarget->deleted = 1; /* block IO */
4706 			hot_plug_info.event_type = MPTSAS_DEL_RAID;
4707 			break;
4708 		}
4709 		switch (state) {
4710 		case MPI_RAIDVOL0_STATUS_STATE_FAILED:
4711 		case MPI_RAIDVOL0_STATUS_STATE_MISSING:
4712 			if (!sdev)
4713 				break;
4714 			vdevice->vtarget->deleted = 1; /* block IO */
4715 			hot_plug_info.event_type = MPTSAS_DEL_RAID;
4716 			break;
4717 		case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
4718 		case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
4719 			if (sdev) {
4720 				scsi_device_put(sdev);
4721 				break;
4722 			}
4723 			hot_plug_info.event_type = MPTSAS_ADD_RAID;
4724 			break;
4725 		default:
4726 			break;
4727 		}
4728 		break;
4729 	default:
4730 		break;
4731 	}
4732 
4733 	if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
4734 		mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4735 	else
4736 		mptsas_free_fw_event(ioc, fw_event);
4737 }
4738 
4739 /**
4740  *	mptsas_issue_tm - send mptsas internal tm request
4741  *	@ioc: Pointer to MPT_ADAPTER structure
4742  *	@type: Task Management type
4743  *	@channel: channel number for task management
4744  *	@id: Logical Target ID for reset (if appropriate)
4745  *	@lun: Logical unit for reset (if appropriate)
4746  *	@task_context: Context for the task to be aborted
4747  *	@timeout: timeout for task management control
4748  *
4749  *	return 0 on success and -1 on failure:
4750  *
4751  */
4752 static int
4753 mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
4754 	int task_context, ulong timeout, u8 *issue_reset)
4755 {
4756 	MPT_FRAME_HDR	*mf;
4757 	SCSITaskMgmt_t	*pScsiTm;
4758 	int		 retval;
4759 	unsigned long	 timeleft;
4760 
4761 	*issue_reset = 0;
4762 	mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
4763 	if (mf == NULL) {
4764 		retval = -1; /* return failure */
4765 		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt request: no "
4766 		    "msg frames!!\n", ioc->name));
4767 		goto out;
4768 	}
4769 
4770 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request: mr = %p, "
4771 	    "task_type = 0x%02X,\n\t timeout = %ld, fw_channel = %d, "
4772 	    "fw_id = %d, lun = %lld,\n\t task_context = 0x%x\n", ioc->name, mf,
4773 	     type, timeout, channel, id, (unsigned long long)lun,
4774 	     task_context));
4775 
4776 	pScsiTm = (SCSITaskMgmt_t *) mf;
4777 	memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
4778 	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
4779 	pScsiTm->TaskType = type;
4780 	pScsiTm->MsgFlags = 0;
4781 	pScsiTm->TargetID = id;
4782 	pScsiTm->Bus = channel;
4783 	pScsiTm->ChainOffset = 0;
4784 	pScsiTm->Reserved = 0;
4785 	pScsiTm->Reserved1 = 0;
4786 	pScsiTm->TaskMsgContext = task_context;
4787 	int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
4788 
4789 	INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4790 	CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
4791 	retval = 0;
4792 	mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
4793 
4794 	/* Now wait for the command to complete */
4795 	timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
4796 	    timeout*HZ);
4797 	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4798 		retval = -1; /* return failure */
4799 		dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
4800 		    "TaskMgmt request: TIMED OUT!(mr=%p)\n", ioc->name, mf));
4801 		mpt_free_msg_frame(ioc, mf);
4802 		if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4803 			goto out;
4804 		*issue_reset = 1;
4805 		goto out;
4806 	}
4807 
4808 	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
4809 		retval = -1; /* return failure */
4810 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4811 		    "TaskMgmt request: failed with no reply\n", ioc->name));
4812 		goto out;
4813 	}
4814 
4815  out:
4816 	CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
4817 	return retval;
4818 }
4819 
4820 /**
4821  *	mptsas_broadcast_primative_work - Handle broadcast primitives
4822  *	@work: work queue payload containing info describing the event
4823  *
4824  *	this will be handled in workqueue context.
4825  */
4826 static void
4827 mptsas_broadcast_primative_work(struct fw_event_work *fw_event)
4828 {
4829 	MPT_ADAPTER *ioc = fw_event->ioc;
4830 	MPT_FRAME_HDR	*mf;
4831 	VirtDevice	*vdevice;
4832 	int			ii;
4833 	struct scsi_cmnd	*sc;
4834 	SCSITaskMgmtReply_t	*pScsiTmReply;
4835 	u8			issue_reset;
4836 	int			task_context;
4837 	u8			channel, id;
4838 	int			 lun;
4839 	u32			 termination_count;
4840 	u32			 query_count;
4841 
4842 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4843 	    "%s - enter\n", ioc->name, __func__));
4844 
4845 	mutex_lock(&ioc->taskmgmt_cmds.mutex);
4846 	if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
4847 		mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4848 		mptsas_requeue_fw_event(ioc, fw_event, 1000);
4849 		return;
4850 	}
4851 
4852 	issue_reset = 0;
4853 	termination_count = 0;
4854 	query_count = 0;
4855 	mpt_findImVolumes(ioc);
4856 	pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
4857 
4858 	for (ii = 0; ii < ioc->req_depth; ii++) {
4859 		if (ioc->fw_events_off)
4860 			goto out;
4861 		sc = mptscsih_get_scsi_lookup(ioc, ii);
4862 		if (!sc)
4863 			continue;
4864 		mf = MPT_INDEX_2_MFPTR(ioc, ii);
4865 		if (!mf)
4866 			continue;
4867 		task_context = mf->u.frame.hwhdr.msgctxu.MsgContext;
4868 		vdevice = sc->device->hostdata;
4869 		if (!vdevice || !vdevice->vtarget)
4870 			continue;
4871 		if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
4872 			continue; /* skip hidden raid components */
4873 		if (vdevice->vtarget->raidVolume)
4874 			continue; /* skip hidden raid components */
4875 		channel = vdevice->vtarget->channel;
4876 		id = vdevice->vtarget->id;
4877 		lun = vdevice->lun;
4878 		if (mptsas_issue_tm(ioc, MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK,
4879 		    channel, id, (u64)lun, task_context, 30, &issue_reset))
4880 			goto out;
4881 		query_count++;
4882 		termination_count +=
4883 		    le32_to_cpu(pScsiTmReply->TerminationCount);
4884 		if ((pScsiTmReply->IOCStatus == MPI_IOCSTATUS_SUCCESS) &&
4885 		    (pScsiTmReply->ResponseCode ==
4886 		    MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
4887 		    pScsiTmReply->ResponseCode ==
4888 		    MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
4889 			continue;
4890 		if (mptsas_issue_tm(ioc,
4891 		    MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET,
4892 		    channel, id, (u64)lun, 0, 30, &issue_reset))
4893 			goto out;
4894 		termination_count +=
4895 		    le32_to_cpu(pScsiTmReply->TerminationCount);
4896 	}
4897 
4898  out:
4899 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4900 	    "%s - exit, query_count = %d termination_count = %d\n",
4901 	    ioc->name, __func__, query_count, termination_count));
4902 
4903 	ioc->broadcast_aen_busy = 0;
4904 	mpt_clear_taskmgmt_in_progress_flag(ioc);
4905 	mutex_unlock(&ioc->taskmgmt_cmds.mutex);
4906 
4907 	if (issue_reset) {
4908 		printk(MYIOC_s_WARN_FMT
4909 		       "Issuing Reset from %s!! doorbell=0x%08x\n",
4910 		       ioc->name, __func__, mpt_GetIocState(ioc, 0));
4911 		mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
4912 	}
4913 	mptsas_free_fw_event(ioc, fw_event);
4914 }
4915 
4916 /*
4917  * mptsas_send_ir2_event - handle exposing hidden disk when
4918  * an inactive raid volume is added
4919  *
4920  * @ioc: Pointer to MPT_ADAPTER structure
4921  * @ir2_data
4922  *
4923  */
4924 static void
4925 mptsas_send_ir2_event(struct fw_event_work *fw_event)
4926 {
4927 	MPT_ADAPTER	*ioc;
4928 	struct mptsas_hotplug_event hot_plug_info;
4929 	MPI_EVENT_DATA_IR2	*ir2_data;
4930 	u8 reasonCode;
4931 	RaidPhysDiskPage0_t phys_disk;
4932 
4933 	ioc = fw_event->ioc;
4934 	ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
4935 	reasonCode = ir2_data->ReasonCode;
4936 
4937 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
4938 	    "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
4939 
4940 	memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
4941 	hot_plug_info.id = ir2_data->TargetID;
4942 	hot_plug_info.channel = ir2_data->Bus;
4943 	switch (reasonCode) {
4944 	case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
4945 		hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
4946 		break;
4947 	case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
4948 		hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4949 		hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
4950 		break;
4951 	case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
4952 		hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
4953 		mpt_raid_phys_disk_pg0(ioc,
4954 		    ir2_data->PhysDiskNum, &phys_disk);
4955 		hot_plug_info.id = phys_disk.PhysDiskID;
4956 		hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
4957 		break;
4958 	default:
4959 		mptsas_free_fw_event(ioc, fw_event);
4960 		return;
4961 	}
4962 	mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
4963 }
4964 
4965 static int
4966 mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
4967 {
4968 	u32 event = le32_to_cpu(reply->Event);
4969 	int sz, event_data_sz;
4970 	struct fw_event_work *fw_event;
4971 	unsigned long delay;
4972 
4973 	if (ioc->bus_type != SAS)
4974 		return 0;
4975 
4976 	/* events turned off due to host reset or driver unloading */
4977 	if (ioc->fw_events_off)
4978 		return 0;
4979 
4980 	delay = msecs_to_jiffies(1);
4981 	switch (event) {
4982 	case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
4983 	{
4984 		EVENT_DATA_SAS_BROADCAST_PRIMITIVE *broadcast_event_data =
4985 		    (EVENT_DATA_SAS_BROADCAST_PRIMITIVE *)reply->Data;
4986 		if (broadcast_event_data->Primitive !=
4987 		    MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
4988 			return 0;
4989 		if (ioc->broadcast_aen_busy)
4990 			return 0;
4991 		ioc->broadcast_aen_busy = 1;
4992 		break;
4993 	}
4994 	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
4995 	{
4996 		EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
4997 		    (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
4998 		u16	ioc_stat;
4999 		ioc_stat = le16_to_cpu(reply->IOCStatus);
5000 
5001 		if (sas_event_data->ReasonCode ==
5002 		    MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
5003 			mptsas_target_reset_queue(ioc, sas_event_data);
5004 			return 0;
5005 		}
5006 		if (sas_event_data->ReasonCode ==
5007 			MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
5008 			ioc->device_missing_delay &&
5009 			(ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)) {
5010 			VirtTarget *vtarget = NULL;
5011 			u8		id, channel;
5012 			u32	 log_info = le32_to_cpu(reply->IOCLogInfo);
5013 
5014 			id = sas_event_data->TargetID;
5015 			channel = sas_event_data->Bus;
5016 
5017 			vtarget = mptsas_find_vtarget(ioc, channel, id);
5018 			if (vtarget) {
5019 				devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5020 				    "LogInfo (0x%x) available for "
5021 				   "INTERNAL_DEVICE_RESET"
5022 				   "fw_id %d fw_channel %d\n", ioc->name,
5023 				   log_info, id, channel));
5024 				if (vtarget->raidVolume) {
5025 					devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5026 					"Skipping Raid Volume for inDMD\n",
5027 					ioc->name));
5028 				} else {
5029 					devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5030 					"Setting device flag inDMD\n",
5031 					ioc->name));
5032 					vtarget->inDMD = 1;
5033 				}
5034 
5035 			}
5036 
5037 		}
5038 
5039 		break;
5040 	}
5041 	case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
5042 	{
5043 		MpiEventDataSasExpanderStatusChange_t *expander_data =
5044 		    (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
5045 
5046 		if (ioc->old_sas_discovery_protocal)
5047 			return 0;
5048 
5049 		if (expander_data->ReasonCode ==
5050 		    MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
5051 		    ioc->device_missing_delay)
5052 			delay = HZ * ioc->device_missing_delay;
5053 		break;
5054 	}
5055 	case MPI_EVENT_SAS_DISCOVERY:
5056 	{
5057 		u32 discovery_status;
5058 		EventDataSasDiscovery_t *discovery_data =
5059 		    (EventDataSasDiscovery_t *)reply->Data;
5060 
5061 		discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
5062 		ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
5063 		if (ioc->old_sas_discovery_protocal && !discovery_status)
5064 			mptsas_queue_rescan(ioc);
5065 		return 0;
5066 	}
5067 	case MPI_EVENT_INTEGRATED_RAID:
5068 	case MPI_EVENT_PERSISTENT_TABLE_FULL:
5069 	case MPI_EVENT_IR2:
5070 	case MPI_EVENT_SAS_PHY_LINK_STATUS:
5071 	case MPI_EVENT_QUEUE_FULL:
5072 		break;
5073 	default:
5074 		return 0;
5075 	}
5076 
5077 	event_data_sz = ((reply->MsgLength * 4) -
5078 	    offsetof(EventNotificationReply_t, Data));
5079 	sz = offsetof(struct fw_event_work, event_data) + event_data_sz;
5080 	fw_event = kzalloc(sz, GFP_ATOMIC);
5081 	if (!fw_event) {
5082 		printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
5083 		 __func__, __LINE__);
5084 		return 0;
5085 	}
5086 	memcpy(fw_event->event_data, reply->Data, event_data_sz);
5087 	fw_event->event = event;
5088 	fw_event->ioc = ioc;
5089 	mptsas_add_fw_event(ioc, fw_event, delay);
5090 	return 0;
5091 }
5092 
5093 /* Delete a volume when no longer listed in ioc pg2
5094  */
5095 static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id)
5096 {
5097 	struct scsi_device *sdev;
5098 	int i;
5099 
5100 	sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0);
5101 	if (!sdev)
5102 		return;
5103 	if (!ioc->raid_data.pIocPg2)
5104 		goto out;
5105 	if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
5106 		goto out;
5107 	for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
5108 		if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id)
5109 			goto release_sdev;
5110  out:
5111 	printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
5112 	    "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id);
5113 	scsi_remove_device(sdev);
5114  release_sdev:
5115 	scsi_device_put(sdev);
5116 }
5117 
5118 static int
5119 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5120 {
5121 	struct Scsi_Host	*sh;
5122 	MPT_SCSI_HOST		*hd;
5123 	MPT_ADAPTER 		*ioc;
5124 	unsigned long		 flags;
5125 	int			 ii;
5126 	int			 numSGE = 0;
5127 	int			 scale;
5128 	int			 ioc_cap;
5129 	int			error=0;
5130 	int			r;
5131 
5132 	r = mpt_attach(pdev,id);
5133 	if (r)
5134 		return r;
5135 
5136 	ioc = pci_get_drvdata(pdev);
5137 	mptsas_fw_event_off(ioc);
5138 	ioc->DoneCtx = mptsasDoneCtx;
5139 	ioc->TaskCtx = mptsasTaskCtx;
5140 	ioc->InternalCtx = mptsasInternalCtx;
5141 	ioc->schedule_target_reset = &mptsas_schedule_target_reset;
5142 	/*  Added sanity check on readiness of the MPT adapter.
5143 	 */
5144 	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
5145 		printk(MYIOC_s_WARN_FMT
5146 		  "Skipping because it's not operational!\n",
5147 		  ioc->name);
5148 		error = -ENODEV;
5149 		goto out_mptsas_probe;
5150 	}
5151 
5152 	if (!ioc->active) {
5153 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
5154 		  ioc->name);
5155 		error = -ENODEV;
5156 		goto out_mptsas_probe;
5157 	}
5158 
5159 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
5160 	 */
5161 	ioc_cap = 0;
5162 	for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
5163 		if (ioc->pfacts[ii].ProtocolFlags &
5164 				MPI_PORTFACTS_PROTOCOL_INITIATOR)
5165 			ioc_cap++;
5166 	}
5167 
5168 	if (!ioc_cap) {
5169 		printk(MYIOC_s_WARN_FMT
5170 			"Skipping ioc=%p because SCSI Initiator mode "
5171 			"is NOT enabled!\n", ioc->name, ioc);
5172 		return 0;
5173 	}
5174 
5175 	sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
5176 	if (!sh) {
5177 		printk(MYIOC_s_WARN_FMT
5178 			"Unable to register controller with SCSI subsystem\n",
5179 			ioc->name);
5180 		error = -1;
5181 		goto out_mptsas_probe;
5182         }
5183 
5184 	spin_lock_irqsave(&ioc->FreeQlock, flags);
5185 
5186 	/* Attach the SCSI Host to the IOC structure
5187 	 */
5188 	ioc->sh = sh;
5189 
5190 	sh->io_port = 0;
5191 	sh->n_io_port = 0;
5192 	sh->irq = 0;
5193 
5194 	/* set 16 byte cdb's */
5195 	sh->max_cmd_len = 16;
5196 	sh->can_queue = min_t(int, ioc->req_depth - 10, sh->can_queue);
5197 	sh->max_id = -1;
5198 	sh->max_lun = max_lun;
5199 	sh->transportt = mptsas_transport_template;
5200 
5201 	/* Required entry.
5202 	 */
5203 	sh->unique_id = ioc->id;
5204 
5205 	INIT_LIST_HEAD(&ioc->sas_topology);
5206 	mutex_init(&ioc->sas_topology_mutex);
5207 	mutex_init(&ioc->sas_discovery_mutex);
5208 	mutex_init(&ioc->sas_mgmt.mutex);
5209 	init_completion(&ioc->sas_mgmt.done);
5210 
5211 	/* Verify that we won't exceed the maximum
5212 	 * number of chain buffers
5213 	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
5214 	 * For 32bit SGE's:
5215 	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
5216 	 *               + (req_sz - 64)/sizeof(SGE)
5217 	 * A slightly different algorithm is required for
5218 	 * 64bit SGEs.
5219 	 */
5220 	scale = ioc->req_sz/ioc->SGE_size;
5221 	if (ioc->sg_addr_size == sizeof(u64)) {
5222 		numSGE = (scale - 1) *
5223 		  (ioc->facts.MaxChainDepth-1) + scale +
5224 		  (ioc->req_sz - 60) / ioc->SGE_size;
5225 	} else {
5226 		numSGE = 1 + (scale - 1) *
5227 		  (ioc->facts.MaxChainDepth-1) + scale +
5228 		  (ioc->req_sz - 64) / ioc->SGE_size;
5229 	}
5230 
5231 	if (numSGE < sh->sg_tablesize) {
5232 		/* Reset this value */
5233 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5234 		  "Resetting sg_tablesize to %d from %d\n",
5235 		  ioc->name, numSGE, sh->sg_tablesize));
5236 		sh->sg_tablesize = numSGE;
5237 	}
5238 
5239 	hd = shost_priv(sh);
5240 	hd->ioc = ioc;
5241 
5242 	/* SCSI needs scsi_cmnd lookup table!
5243 	 * (with size equal to req_depth*PtrSz!)
5244 	 */
5245 	ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
5246 	if (!ioc->ScsiLookup) {
5247 		error = -ENOMEM;
5248 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5249 		goto out_mptsas_probe;
5250 	}
5251 	spin_lock_init(&ioc->scsi_lookup_lock);
5252 
5253 	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
5254 		 ioc->name, ioc->ScsiLookup));
5255 
5256 	ioc->sas_data.ptClear = mpt_pt_clear;
5257 
5258 	hd->last_queue_full = 0;
5259 	INIT_LIST_HEAD(&hd->target_reset_list);
5260 	INIT_LIST_HEAD(&ioc->sas_device_info_list);
5261 	mutex_init(&ioc->sas_device_info_mutex);
5262 
5263 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5264 
5265 	if (ioc->sas_data.ptClear==1) {
5266 		mptbase_sas_persist_operation(
5267 		    ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
5268 	}
5269 
5270 	error = scsi_add_host(sh, &ioc->pcidev->dev);
5271 	if (error) {
5272 		dprintk(ioc, printk(MYIOC_s_ERR_FMT
5273 		  "scsi_add_host failed\n", ioc->name));
5274 		goto out_mptsas_probe;
5275 	}
5276 
5277 	/* older firmware doesn't support expander events */
5278 	if ((ioc->facts.HeaderVersion >> 8) < 0xE)
5279 		ioc->old_sas_discovery_protocal = 1;
5280 	mptsas_scan_sas_topology(ioc);
5281 	mptsas_fw_event_on(ioc);
5282 	return 0;
5283 
5284  out_mptsas_probe:
5285 
5286 	mptscsih_remove(pdev);
5287 	return error;
5288 }
5289 
5290 void
5291 mptsas_shutdown(struct pci_dev *pdev)
5292 {
5293 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5294 
5295 	mptsas_fw_event_off(ioc);
5296 	mptsas_cleanup_fw_event_q(ioc);
5297 }
5298 
5299 static void __devexit mptsas_remove(struct pci_dev *pdev)
5300 {
5301 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
5302 	struct mptsas_portinfo *p, *n;
5303 	int i;
5304 
5305 	if (!ioc->sh) {
5306 		printk(MYIOC_s_INFO_FMT "IOC is in Target mode\n", ioc->name);
5307 		mpt_detach(pdev);
5308 		return;
5309 	}
5310 
5311 	mptsas_shutdown(pdev);
5312 
5313 	mptsas_del_device_components(ioc);
5314 
5315 	ioc->sas_discovery_ignore_events = 1;
5316 	sas_remove_host(ioc->sh);
5317 
5318 	mutex_lock(&ioc->sas_topology_mutex);
5319 	list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
5320 		list_del(&p->list);
5321 		for (i = 0 ; i < p->num_phys ; i++)
5322 			mptsas_port_delete(ioc, p->phy_info[i].port_details);
5323 
5324 		kfree(p->phy_info);
5325 		kfree(p);
5326 	}
5327 	mutex_unlock(&ioc->sas_topology_mutex);
5328 	ioc->hba_port_info = NULL;
5329 	mptscsih_remove(pdev);
5330 }
5331 
5332 static struct pci_device_id mptsas_pci_table[] = {
5333 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
5334 		PCI_ANY_ID, PCI_ANY_ID },
5335 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
5336 		PCI_ANY_ID, PCI_ANY_ID },
5337 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
5338 		PCI_ANY_ID, PCI_ANY_ID },
5339 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
5340 		PCI_ANY_ID, PCI_ANY_ID },
5341 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
5342 		PCI_ANY_ID, PCI_ANY_ID },
5343 	{0}	/* Terminating entry */
5344 };
5345 MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
5346 
5347 
5348 static struct pci_driver mptsas_driver = {
5349 	.name		= "mptsas",
5350 	.id_table	= mptsas_pci_table,
5351 	.probe		= mptsas_probe,
5352 	.remove		= __devexit_p(mptsas_remove),
5353 	.shutdown	= mptsas_shutdown,
5354 #ifdef CONFIG_PM
5355 	.suspend	= mptscsih_suspend,
5356 	.resume		= mptscsih_resume,
5357 #endif
5358 };
5359 
5360 static int __init
5361 mptsas_init(void)
5362 {
5363 	int error;
5364 
5365 	show_mptmod_ver(my_NAME, my_VERSION);
5366 
5367 	mptsas_transport_template =
5368 	    sas_attach_transport(&mptsas_transport_functions);
5369 	if (!mptsas_transport_template)
5370 		return -ENODEV;
5371 	mptsas_transport_template->eh_timed_out = mptsas_eh_timed_out;
5372 
5373 	mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER,
5374 	    "mptscsih_io_done");
5375 	mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER,
5376 	    "mptscsih_taskmgmt_complete");
5377 	mptsasInternalCtx =
5378 		mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER,
5379 		    "mptscsih_scandv_complete");
5380 	mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER,
5381 	    "mptsas_mgmt_done");
5382 	mptsasDeviceResetCtx =
5383 		mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER,
5384 		    "mptsas_taskmgmt_complete");
5385 
5386 	mpt_event_register(mptsasDoneCtx, mptsas_event_process);
5387 	mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
5388 
5389 	error = pci_register_driver(&mptsas_driver);
5390 	if (error)
5391 		sas_release_transport(mptsas_transport_template);
5392 
5393 	return error;
5394 }
5395 
5396 static void __exit
5397 mptsas_exit(void)
5398 {
5399 	pci_unregister_driver(&mptsas_driver);
5400 	sas_release_transport(mptsas_transport_template);
5401 
5402 	mpt_reset_deregister(mptsasDoneCtx);
5403 	mpt_event_deregister(mptsasDoneCtx);
5404 
5405 	mpt_deregister(mptsasMgmtCtx);
5406 	mpt_deregister(mptsasInternalCtx);
5407 	mpt_deregister(mptsasTaskCtx);
5408 	mpt_deregister(mptsasDoneCtx);
5409 	mpt_deregister(mptsasDeviceResetCtx);
5410 }
5411 
5412 module_init(mptsas_init);
5413 module_exit(mptsas_exit);
5414