Linux Audio

Check our new training course

Embedded Linux training

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