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