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