Linux Audio

Check our new training course

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