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