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