Linux Audio

Check our new training course

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