Linux Audio

Check our new training course

Embedded Linux training

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