cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mptsas.c (152427B)


      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 blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
   1956{
   1957	MPT_SCSI_HOST *hd;
   1958	MPT_ADAPTER   *ioc;
   1959	VirtDevice    *vdevice;
   1960	enum blk_eh_timer_return rc = BLK_EH_DONE;
   1961
   1962	hd = shost_priv(sc->device->host);
   1963	if (hd == NULL) {
   1964		printk(KERN_ERR MYNAM ": %s: Can't locate host! (sc=%p)\n",
   1965		    __func__, sc);
   1966		goto done;
   1967	}
   1968
   1969	ioc = hd->ioc;
   1970	if (ioc->bus_type != SAS) {
   1971		printk(KERN_ERR MYNAM ": %s: Wrong bus type (sc=%p)\n",
   1972		    __func__, sc);
   1973		goto done;
   1974	}
   1975
   1976	/* In case if IOC is in reset from internal context.
   1977	*  Do not execute EEH for the same IOC. SML should to reset timer.
   1978	*/
   1979	if (ioc->ioc_reset_in_progress) {
   1980		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: ioc is in reset,"
   1981		    "SML need to reset the timer (sc=%p)\n",
   1982		    ioc->name, __func__, sc));
   1983		rc = BLK_EH_RESET_TIMER;
   1984	}
   1985	vdevice = sc->device->hostdata;
   1986	if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD
   1987		|| vdevice->vtarget->deleted)) {
   1988		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: target removed "
   1989		    "or in device removal delay (sc=%p)\n",
   1990		    ioc->name, __func__, sc));
   1991		rc = BLK_EH_RESET_TIMER;
   1992		goto done;
   1993	}
   1994
   1995done:
   1996	return rc;
   1997}
   1998
   1999
   2000static struct scsi_host_template mptsas_driver_template = {
   2001	.module				= THIS_MODULE,
   2002	.proc_name			= "mptsas",
   2003	.show_info			= mptscsih_show_info,
   2004	.name				= "MPT SAS Host",
   2005	.info				= mptscsih_info,
   2006	.queuecommand			= mptsas_qcmd,
   2007	.target_alloc			= mptsas_target_alloc,
   2008	.slave_alloc			= mptsas_slave_alloc,
   2009	.slave_configure		= mptsas_slave_configure,
   2010	.target_destroy			= mptsas_target_destroy,
   2011	.slave_destroy			= mptscsih_slave_destroy,
   2012	.change_queue_depth 		= mptscsih_change_queue_depth,
   2013	.eh_timed_out			= mptsas_eh_timed_out,
   2014	.eh_abort_handler		= mptscsih_abort,
   2015	.eh_device_reset_handler	= mptscsih_dev_reset,
   2016	.eh_host_reset_handler		= mptscsih_host_reset,
   2017	.bios_param			= mptscsih_bios_param,
   2018	.can_queue			= MPT_SAS_CAN_QUEUE,
   2019	.this_id			= -1,
   2020	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
   2021	.max_sectors			= 8192,
   2022	.cmd_per_lun			= 7,
   2023	.shost_groups			= mptscsih_host_attr_groups,
   2024	.no_write_same			= 1,
   2025};
   2026
   2027static int mptsas_get_linkerrors(struct sas_phy *phy)
   2028{
   2029	MPT_ADAPTER *ioc = phy_to_ioc(phy);
   2030	ConfigExtendedPageHeader_t hdr;
   2031	CONFIGPARMS cfg;
   2032	SasPhyPage1_t *buffer;
   2033	dma_addr_t dma_handle;
   2034	int error;
   2035
   2036	/* FIXME: only have link errors on local phys */
   2037	if (!scsi_is_sas_phy_local(phy))
   2038		return -EINVAL;
   2039
   2040	hdr.PageVersion = MPI_SASPHY1_PAGEVERSION;
   2041	hdr.ExtPageLength = 0;
   2042	hdr.PageNumber = 1 /* page number 1*/;
   2043	hdr.Reserved1 = 0;
   2044	hdr.Reserved2 = 0;
   2045	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
   2046	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
   2047
   2048	cfg.cfghdr.ehdr = &hdr;
   2049	cfg.physAddr = -1;
   2050	cfg.pageAddr = phy->identify.phy_identifier;
   2051	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
   2052	cfg.dir = 0;    /* read */
   2053	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
   2054
   2055	error = mpt_config(ioc, &cfg);
   2056	if (error)
   2057		return error;
   2058	if (!hdr.ExtPageLength)
   2059		return -ENXIO;
   2060
   2061	buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
   2062				    &dma_handle, GFP_KERNEL);
   2063	if (!buffer)
   2064		return -ENOMEM;
   2065
   2066	cfg.physAddr = dma_handle;
   2067	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
   2068
   2069	error = mpt_config(ioc, &cfg);
   2070	if (error)
   2071		goto out_free_consistent;
   2072
   2073	mptsas_print_phy_pg1(ioc, buffer);
   2074
   2075	phy->invalid_dword_count = le32_to_cpu(buffer->InvalidDwordCount);
   2076	phy->running_disparity_error_count =
   2077		le32_to_cpu(buffer->RunningDisparityErrorCount);
   2078	phy->loss_of_dword_sync_count =
   2079		le32_to_cpu(buffer->LossDwordSynchCount);
   2080	phy->phy_reset_problem_count =
   2081		le32_to_cpu(buffer->PhyResetProblemCount);
   2082
   2083 out_free_consistent:
   2084	dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
   2085			  dma_handle);
   2086	return error;
   2087}
   2088
   2089static int mptsas_mgmt_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
   2090		MPT_FRAME_HDR *reply)
   2091{
   2092	ioc->sas_mgmt.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
   2093	if (reply != NULL) {
   2094		ioc->sas_mgmt.status |= MPT_MGMT_STATUS_RF_VALID;
   2095		memcpy(ioc->sas_mgmt.reply, reply,
   2096		    min(ioc->reply_sz, 4 * reply->u.reply.MsgLength));
   2097	}
   2098
   2099	if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_PENDING) {
   2100		ioc->sas_mgmt.status &= ~MPT_MGMT_STATUS_PENDING;
   2101		complete(&ioc->sas_mgmt.done);
   2102		return 1;
   2103	}
   2104	return 0;
   2105}
   2106
   2107static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
   2108{
   2109	MPT_ADAPTER *ioc = phy_to_ioc(phy);
   2110	SasIoUnitControlRequest_t *req;
   2111	SasIoUnitControlReply_t *reply;
   2112	MPT_FRAME_HDR *mf;
   2113	MPIHeader_t *hdr;
   2114	unsigned long timeleft;
   2115	int error = -ERESTARTSYS;
   2116
   2117	/* FIXME: fusion doesn't allow non-local phy reset */
   2118	if (!scsi_is_sas_phy_local(phy))
   2119		return -EINVAL;
   2120
   2121	/* not implemented for expanders */
   2122	if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP)
   2123		return -ENXIO;
   2124
   2125	if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex))
   2126		goto out;
   2127
   2128	mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
   2129	if (!mf) {
   2130		error = -ENOMEM;
   2131		goto out_unlock;
   2132	}
   2133
   2134	hdr = (MPIHeader_t *) mf;
   2135	req = (SasIoUnitControlRequest_t *)mf;
   2136	memset(req, 0, sizeof(SasIoUnitControlRequest_t));
   2137	req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
   2138	req->MsgContext = hdr->MsgContext;
   2139	req->Operation = hard_reset ?
   2140		MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET;
   2141	req->PhyNum = phy->identify.phy_identifier;
   2142
   2143	INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
   2144	mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
   2145
   2146	timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
   2147			10 * HZ);
   2148	if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
   2149		error = -ETIME;
   2150		mpt_free_msg_frame(ioc, mf);
   2151		if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
   2152			goto out_unlock;
   2153		if (!timeleft)
   2154			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
   2155		goto out_unlock;
   2156	}
   2157
   2158	/* a reply frame is expected */
   2159	if ((ioc->sas_mgmt.status &
   2160	    MPT_MGMT_STATUS_RF_VALID) == 0) {
   2161		error = -ENXIO;
   2162		goto out_unlock;
   2163	}
   2164
   2165	/* process the completed Reply Message Frame */
   2166	reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply;
   2167	if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) {
   2168		printk(MYIOC_s_INFO_FMT "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
   2169		    ioc->name, __func__, reply->IOCStatus, reply->IOCLogInfo);
   2170		error = -ENXIO;
   2171		goto out_unlock;
   2172	}
   2173
   2174	error = 0;
   2175
   2176 out_unlock:
   2177	CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
   2178	mutex_unlock(&ioc->sas_mgmt.mutex);
   2179 out:
   2180	return error;
   2181}
   2182
   2183static int
   2184mptsas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
   2185{
   2186	MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
   2187	int i, error;
   2188	struct mptsas_portinfo *p;
   2189	struct mptsas_enclosure enclosure_info;
   2190	u64 enclosure_handle;
   2191
   2192	mutex_lock(&ioc->sas_topology_mutex);
   2193	list_for_each_entry(p, &ioc->sas_topology, list) {
   2194		for (i = 0; i < p->num_phys; i++) {
   2195			if (p->phy_info[i].attached.sas_address ==
   2196			    rphy->identify.sas_address) {
   2197				enclosure_handle = p->phy_info[i].
   2198					attached.handle_enclosure;
   2199				goto found_info;
   2200			}
   2201		}
   2202	}
   2203	mutex_unlock(&ioc->sas_topology_mutex);
   2204	return -ENXIO;
   2205
   2206 found_info:
   2207	mutex_unlock(&ioc->sas_topology_mutex);
   2208	memset(&enclosure_info, 0, sizeof(struct mptsas_enclosure));
   2209	error = mptsas_sas_enclosure_pg0(ioc, &enclosure_info,
   2210			(MPI_SAS_ENCLOS_PGAD_FORM_HANDLE <<
   2211			 MPI_SAS_ENCLOS_PGAD_FORM_SHIFT), enclosure_handle);
   2212	if (!error)
   2213		*identifier = enclosure_info.enclosure_logical_id;
   2214	return error;
   2215}
   2216
   2217static int
   2218mptsas_get_bay_identifier(struct sas_rphy *rphy)
   2219{
   2220	MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
   2221	struct mptsas_portinfo *p;
   2222	int i, rc;
   2223
   2224	mutex_lock(&ioc->sas_topology_mutex);
   2225	list_for_each_entry(p, &ioc->sas_topology, list) {
   2226		for (i = 0; i < p->num_phys; i++) {
   2227			if (p->phy_info[i].attached.sas_address ==
   2228			    rphy->identify.sas_address) {
   2229				rc = p->phy_info[i].attached.slot;
   2230				goto out;
   2231			}
   2232		}
   2233	}
   2234	rc = -ENXIO;
   2235 out:
   2236	mutex_unlock(&ioc->sas_topology_mutex);
   2237	return rc;
   2238}
   2239
   2240static void mptsas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
   2241		struct sas_rphy *rphy)
   2242{
   2243	MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
   2244	MPT_FRAME_HDR *mf;
   2245	SmpPassthroughRequest_t *smpreq;
   2246	int flagsLength;
   2247	unsigned long timeleft;
   2248	char *psge;
   2249	u64 sas_address = 0;
   2250	unsigned int reslen = 0;
   2251	int ret = -EINVAL;
   2252
   2253	/* do we need to support multiple segments? */
   2254	if (job->request_payload.sg_cnt > 1 ||
   2255	    job->reply_payload.sg_cnt > 1) {
   2256		printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u, rsp %u\n",
   2257		    ioc->name, __func__, job->request_payload.payload_len,
   2258		    job->reply_payload.payload_len);
   2259		goto out;
   2260	}
   2261
   2262	ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
   2263	if (ret)
   2264		goto out;
   2265
   2266	mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
   2267	if (!mf) {
   2268		ret = -ENOMEM;
   2269		goto out_unlock;
   2270	}
   2271
   2272	smpreq = (SmpPassthroughRequest_t *)mf;
   2273	memset(smpreq, 0, sizeof(*smpreq));
   2274
   2275	smpreq->RequestDataLength =
   2276		cpu_to_le16(job->request_payload.payload_len - 4);
   2277	smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
   2278
   2279	if (rphy)
   2280		sas_address = rphy->identify.sas_address;
   2281	else {
   2282		struct mptsas_portinfo *port_info;
   2283
   2284		mutex_lock(&ioc->sas_topology_mutex);
   2285		port_info = ioc->hba_port_info;
   2286		if (port_info && port_info->phy_info)
   2287			sas_address =
   2288				port_info->phy_info[0].phy->identify.sas_address;
   2289		mutex_unlock(&ioc->sas_topology_mutex);
   2290	}
   2291
   2292	*((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
   2293
   2294	psge = (char *)
   2295		(((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
   2296
   2297	/* request */
   2298	flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
   2299		       MPI_SGE_FLAGS_END_OF_BUFFER |
   2300		       MPI_SGE_FLAGS_DIRECTION)
   2301		       << MPI_SGE_FLAGS_SHIFT;
   2302
   2303	if (!dma_map_sg(&ioc->pcidev->dev, job->request_payload.sg_list,
   2304			1, DMA_BIDIRECTIONAL))
   2305		goto put_mf;
   2306
   2307	flagsLength |= (sg_dma_len(job->request_payload.sg_list) - 4);
   2308	ioc->add_sge(psge, flagsLength,
   2309			sg_dma_address(job->request_payload.sg_list));
   2310	psge += ioc->SGE_size;
   2311
   2312	/* response */
   2313	flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
   2314		MPI_SGE_FLAGS_SYSTEM_ADDRESS |
   2315		MPI_SGE_FLAGS_IOC_TO_HOST |
   2316		MPI_SGE_FLAGS_END_OF_BUFFER;
   2317
   2318	flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
   2319
   2320	if (!dma_map_sg(&ioc->pcidev->dev, job->reply_payload.sg_list,
   2321			1, DMA_BIDIRECTIONAL))
   2322		goto unmap_out;
   2323	flagsLength |= sg_dma_len(job->reply_payload.sg_list) + 4;
   2324	ioc->add_sge(psge, flagsLength,
   2325			sg_dma_address(job->reply_payload.sg_list));
   2326
   2327	INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
   2328	mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
   2329
   2330	timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
   2331	if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
   2332		ret = -ETIME;
   2333		mpt_free_msg_frame(ioc, mf);
   2334		mf = NULL;
   2335		if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
   2336			goto unmap_in;
   2337		if (!timeleft)
   2338			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
   2339		goto unmap_in;
   2340	}
   2341	mf = NULL;
   2342
   2343	if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
   2344		SmpPassthroughReply_t *smprep;
   2345
   2346		smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
   2347		memcpy(job->reply, smprep, sizeof(*smprep));
   2348		job->reply_len = sizeof(*smprep);
   2349		reslen = smprep->ResponseDataLength;
   2350	} else {
   2351		printk(MYIOC_s_ERR_FMT
   2352		    "%s: smp passthru reply failed to be returned\n",
   2353		    ioc->name, __func__);
   2354		ret = -ENXIO;
   2355	}
   2356
   2357unmap_in:
   2358	dma_unmap_sg(&ioc->pcidev->dev, job->reply_payload.sg_list, 1,
   2359			DMA_BIDIRECTIONAL);
   2360unmap_out:
   2361	dma_unmap_sg(&ioc->pcidev->dev, job->request_payload.sg_list, 1,
   2362			DMA_BIDIRECTIONAL);
   2363put_mf:
   2364	if (mf)
   2365		mpt_free_msg_frame(ioc, mf);
   2366out_unlock:
   2367	CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
   2368	mutex_unlock(&ioc->sas_mgmt.mutex);
   2369out:
   2370	bsg_job_done(job, ret, reslen);
   2371}
   2372
   2373static struct sas_function_template mptsas_transport_functions = {
   2374	.get_linkerrors		= mptsas_get_linkerrors,
   2375	.get_enclosure_identifier = mptsas_get_enclosure_identifier,
   2376	.get_bay_identifier	= mptsas_get_bay_identifier,
   2377	.phy_reset		= mptsas_phy_reset,
   2378	.smp_handler		= mptsas_smp_handler,
   2379};
   2380
   2381static struct scsi_transport_template *mptsas_transport_template;
   2382
   2383static int
   2384mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
   2385{
   2386	ConfigExtendedPageHeader_t hdr;
   2387	CONFIGPARMS cfg;
   2388	SasIOUnitPage0_t *buffer;
   2389	dma_addr_t dma_handle;
   2390	int error, i;
   2391
   2392	hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
   2393	hdr.ExtPageLength = 0;
   2394	hdr.PageNumber = 0;
   2395	hdr.Reserved1 = 0;
   2396	hdr.Reserved2 = 0;
   2397	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
   2398	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
   2399
   2400	cfg.cfghdr.ehdr = &hdr;
   2401	cfg.physAddr = -1;
   2402	cfg.pageAddr = 0;
   2403	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
   2404	cfg.dir = 0;	/* read */
   2405	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
   2406
   2407	error = mpt_config(ioc, &cfg);
   2408	if (error)
   2409		goto out;
   2410	if (!hdr.ExtPageLength) {
   2411		error = -ENXIO;
   2412		goto out;
   2413	}
   2414
   2415	buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
   2416				    &dma_handle, GFP_KERNEL);
   2417	if (!buffer) {
   2418		error = -ENOMEM;
   2419		goto out;
   2420	}
   2421
   2422	cfg.physAddr = dma_handle;
   2423	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
   2424
   2425	error = mpt_config(ioc, &cfg);
   2426	if (error)
   2427		goto out_free_consistent;
   2428
   2429	port_info->num_phys = buffer->NumPhys;
   2430	port_info->phy_info = kcalloc(port_info->num_phys,
   2431		sizeof(struct mptsas_phyinfo), GFP_KERNEL);
   2432	if (!port_info->phy_info) {
   2433		error = -ENOMEM;
   2434		goto out_free_consistent;
   2435	}
   2436
   2437	ioc->nvdata_version_persistent =
   2438	    le16_to_cpu(buffer->NvdataVersionPersistent);
   2439	ioc->nvdata_version_default =
   2440	    le16_to_cpu(buffer->NvdataVersionDefault);
   2441
   2442	for (i = 0; i < port_info->num_phys; i++) {
   2443		mptsas_print_phy_data(ioc, &buffer->PhyData[i]);
   2444		port_info->phy_info[i].phy_id = i;
   2445		port_info->phy_info[i].port_id =
   2446		    buffer->PhyData[i].Port;
   2447		port_info->phy_info[i].negotiated_link_rate =
   2448		    buffer->PhyData[i].NegotiatedLinkRate;
   2449		port_info->phy_info[i].portinfo = port_info;
   2450		port_info->phy_info[i].handle =
   2451		    le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
   2452	}
   2453
   2454 out_free_consistent:
   2455	dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
   2456			  dma_handle);
   2457 out:
   2458	return error;
   2459}
   2460
   2461static int
   2462mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
   2463{
   2464	ConfigExtendedPageHeader_t hdr;
   2465	CONFIGPARMS cfg;
   2466	SasIOUnitPage1_t *buffer;
   2467	dma_addr_t dma_handle;
   2468	int error;
   2469	u8 device_missing_delay;
   2470
   2471	memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
   2472	memset(&cfg, 0, sizeof(CONFIGPARMS));
   2473
   2474	cfg.cfghdr.ehdr = &hdr;
   2475	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
   2476	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
   2477	cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
   2478	cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
   2479	cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
   2480	cfg.cfghdr.ehdr->PageNumber = 1;
   2481
   2482	error = mpt_config(ioc, &cfg);
   2483	if (error)
   2484		goto out;
   2485	if (!hdr.ExtPageLength) {
   2486		error = -ENXIO;
   2487		goto out;
   2488	}
   2489
   2490	buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
   2491				    &dma_handle, GFP_KERNEL);
   2492	if (!buffer) {
   2493		error = -ENOMEM;
   2494		goto out;
   2495	}
   2496
   2497	cfg.physAddr = dma_handle;
   2498	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
   2499
   2500	error = mpt_config(ioc, &cfg);
   2501	if (error)
   2502		goto out_free_consistent;
   2503
   2504	ioc->io_missing_delay  =
   2505	    le16_to_cpu(buffer->IODeviceMissingDelay);
   2506	device_missing_delay = buffer->ReportDeviceMissingDelay;
   2507	ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
   2508	    (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
   2509	    device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
   2510
   2511 out_free_consistent:
   2512	dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
   2513			  dma_handle);
   2514 out:
   2515	return error;
   2516}
   2517
   2518static int
   2519mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
   2520		u32 form, u32 form_specific)
   2521{
   2522	ConfigExtendedPageHeader_t hdr;
   2523	CONFIGPARMS cfg;
   2524	SasPhyPage0_t *buffer;
   2525	dma_addr_t dma_handle;
   2526	int error;
   2527
   2528	hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
   2529	hdr.ExtPageLength = 0;
   2530	hdr.PageNumber = 0;
   2531	hdr.Reserved1 = 0;
   2532	hdr.Reserved2 = 0;
   2533	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
   2534	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
   2535
   2536	cfg.cfghdr.ehdr = &hdr;
   2537	cfg.dir = 0;	/* read */
   2538	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
   2539
   2540	/* Get Phy Pg 0 for each Phy. */
   2541	cfg.physAddr = -1;
   2542	cfg.pageAddr = form + form_specific;
   2543	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
   2544
   2545	error = mpt_config(ioc, &cfg);
   2546	if (error)
   2547		goto out;
   2548
   2549	if (!hdr.ExtPageLength) {
   2550		error = -ENXIO;
   2551		goto out;
   2552	}
   2553
   2554	buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
   2555				    &dma_handle, GFP_KERNEL);
   2556	if (!buffer) {
   2557		error = -ENOMEM;
   2558		goto out;
   2559	}
   2560
   2561	cfg.physAddr = dma_handle;
   2562	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
   2563
   2564	error = mpt_config(ioc, &cfg);
   2565	if (error)
   2566		goto out_free_consistent;
   2567
   2568	mptsas_print_phy_pg0(ioc, buffer);
   2569
   2570	phy_info->hw_link_rate = buffer->HwLinkRate;
   2571	phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
   2572	phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
   2573	phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
   2574
   2575 out_free_consistent:
   2576	dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
   2577			  dma_handle);
   2578 out:
   2579	return error;
   2580}
   2581
   2582static int
   2583mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
   2584		u32 form, u32 form_specific)
   2585{
   2586	ConfigExtendedPageHeader_t hdr;
   2587	CONFIGPARMS cfg;
   2588	SasDevicePage0_t *buffer;
   2589	dma_addr_t dma_handle;
   2590	__le64 sas_address;
   2591	int error=0;
   2592
   2593	hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
   2594	hdr.ExtPageLength = 0;
   2595	hdr.PageNumber = 0;
   2596	hdr.Reserved1 = 0;
   2597	hdr.Reserved2 = 0;
   2598	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
   2599	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
   2600
   2601	cfg.cfghdr.ehdr = &hdr;
   2602	cfg.pageAddr = form + form_specific;
   2603	cfg.physAddr = -1;
   2604	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
   2605	cfg.dir = 0;	/* read */
   2606	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
   2607
   2608	memset(device_info, 0, sizeof(struct mptsas_devinfo));
   2609	error = mpt_config(ioc, &cfg);
   2610	if (error)
   2611		goto out;
   2612	if (!hdr.ExtPageLength) {
   2613		error = -ENXIO;
   2614		goto out;
   2615	}
   2616
   2617	buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
   2618				    &dma_handle, GFP_KERNEL);
   2619	if (!buffer) {
   2620		error = -ENOMEM;
   2621		goto out;
   2622	}
   2623
   2624	cfg.physAddr = dma_handle;
   2625	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
   2626
   2627	error = mpt_config(ioc, &cfg);
   2628
   2629	if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
   2630		error = -ENODEV;
   2631		goto out_free_consistent;
   2632	}
   2633
   2634	if (error)
   2635		goto out_free_consistent;
   2636
   2637	mptsas_print_device_pg0(ioc, buffer);
   2638
   2639	memset(device_info, 0, sizeof(struct mptsas_devinfo));
   2640	device_info->handle = le16_to_cpu(buffer->DevHandle);
   2641	device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle);
   2642	device_info->handle_enclosure =
   2643	    le16_to_cpu(buffer->EnclosureHandle);
   2644	device_info->slot = le16_to_cpu(buffer->Slot);
   2645	device_info->phy_id = buffer->PhyNum;
   2646	device_info->port_id = buffer->PhysicalPort;
   2647	device_info->id = buffer->TargetID;
   2648	device_info->phys_disk_num = ~0;
   2649	device_info->channel = buffer->Bus;
   2650	memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
   2651	device_info->sas_address = le64_to_cpu(sas_address);
   2652	device_info->device_info =
   2653	    le32_to_cpu(buffer->DeviceInfo);
   2654	device_info->flags = le16_to_cpu(buffer->Flags);
   2655
   2656 out_free_consistent:
   2657	dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
   2658			  dma_handle);
   2659 out:
   2660	return error;
   2661}
   2662
   2663static int
   2664mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
   2665		u32 form, u32 form_specific)
   2666{
   2667	ConfigExtendedPageHeader_t hdr;
   2668	CONFIGPARMS cfg;
   2669	SasExpanderPage0_t *buffer;
   2670	dma_addr_t dma_handle;
   2671	int i, error;
   2672	__le64 sas_address;
   2673
   2674	memset(port_info, 0, sizeof(struct mptsas_portinfo));
   2675	hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
   2676	hdr.ExtPageLength = 0;
   2677	hdr.PageNumber = 0;
   2678	hdr.Reserved1 = 0;
   2679	hdr.Reserved2 = 0;
   2680	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
   2681	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
   2682
   2683	cfg.cfghdr.ehdr = &hdr;
   2684	cfg.physAddr = -1;
   2685	cfg.pageAddr = form + form_specific;
   2686	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
   2687	cfg.dir = 0;	/* read */
   2688	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
   2689
   2690	memset(port_info, 0, sizeof(struct mptsas_portinfo));
   2691	error = mpt_config(ioc, &cfg);
   2692	if (error)
   2693		goto out;
   2694
   2695	if (!hdr.ExtPageLength) {
   2696		error = -ENXIO;
   2697		goto out;
   2698	}
   2699
   2700	buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
   2701				    &dma_handle, GFP_KERNEL);
   2702	if (!buffer) {
   2703		error = -ENOMEM;
   2704		goto out;
   2705	}
   2706
   2707	cfg.physAddr = dma_handle;
   2708	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
   2709
   2710	error = mpt_config(ioc, &cfg);
   2711	if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
   2712		error = -ENODEV;
   2713		goto out_free_consistent;
   2714	}
   2715
   2716	if (error)
   2717		goto out_free_consistent;
   2718
   2719	/* save config data */
   2720	port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
   2721	port_info->phy_info = kcalloc(port_info->num_phys,
   2722		sizeof(struct mptsas_phyinfo), GFP_KERNEL);
   2723	if (!port_info->phy_info) {
   2724		error = -ENOMEM;
   2725		goto out_free_consistent;
   2726	}
   2727
   2728	memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
   2729	for (i = 0; i < port_info->num_phys; i++) {
   2730		port_info->phy_info[i].portinfo = port_info;
   2731		port_info->phy_info[i].handle =
   2732		    le16_to_cpu(buffer->DevHandle);
   2733		port_info->phy_info[i].identify.sas_address =
   2734		    le64_to_cpu(sas_address);
   2735		port_info->phy_info[i].identify.handle_parent =
   2736		    le16_to_cpu(buffer->ParentDevHandle);
   2737	}
   2738
   2739 out_free_consistent:
   2740	dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
   2741			  dma_handle);
   2742 out:
   2743	return error;
   2744}
   2745
   2746static int
   2747mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
   2748		u32 form, u32 form_specific)
   2749{
   2750	ConfigExtendedPageHeader_t hdr;
   2751	CONFIGPARMS cfg;
   2752	SasExpanderPage1_t *buffer;
   2753	dma_addr_t dma_handle;
   2754	int error=0;
   2755
   2756	hdr.PageVersion = MPI_SASEXPANDER1_PAGEVERSION;
   2757	hdr.ExtPageLength = 0;
   2758	hdr.PageNumber = 1;
   2759	hdr.Reserved1 = 0;
   2760	hdr.Reserved2 = 0;
   2761	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
   2762	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
   2763
   2764	cfg.cfghdr.ehdr = &hdr;
   2765	cfg.physAddr = -1;
   2766	cfg.pageAddr = form + form_specific;
   2767	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
   2768	cfg.dir = 0;	/* read */
   2769	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
   2770
   2771	error = mpt_config(ioc, &cfg);
   2772	if (error)
   2773		goto out;
   2774
   2775	if (!hdr.ExtPageLength) {
   2776		error = -ENXIO;
   2777		goto out;
   2778	}
   2779
   2780	buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4,
   2781				    &dma_handle, GFP_KERNEL);
   2782	if (!buffer) {
   2783		error = -ENOMEM;
   2784		goto out;
   2785	}
   2786
   2787	cfg.physAddr = dma_handle;
   2788	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
   2789
   2790	error = mpt_config(ioc, &cfg);
   2791
   2792	if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
   2793		error = -ENODEV;
   2794		goto out_free_consistent;
   2795	}
   2796
   2797	if (error)
   2798		goto out_free_consistent;
   2799
   2800
   2801	mptsas_print_expander_pg1(ioc, buffer);
   2802
   2803	/* save config data */
   2804	phy_info->phy_id = buffer->PhyIdentifier;
   2805	phy_info->port_id = buffer->PhysicalPort;
   2806	phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
   2807	phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
   2808	phy_info->hw_link_rate = buffer->HwLinkRate;
   2809	phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
   2810	phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
   2811
   2812 out_free_consistent:
   2813	dma_free_coherent(&ioc->pcidev->dev, hdr.ExtPageLength * 4, buffer,
   2814			  dma_handle);
   2815 out:
   2816	return error;
   2817}
   2818
   2819struct rep_manu_request{
   2820	u8 smp_frame_type;
   2821	u8 function;
   2822	u8 reserved;
   2823	u8 request_length;
   2824};
   2825
   2826struct rep_manu_reply{
   2827	u8 smp_frame_type; /* 0x41 */
   2828	u8 function; /* 0x01 */
   2829	u8 function_result;
   2830	u8 response_length;
   2831	u16 expander_change_count;
   2832	u8 reserved0[2];
   2833	u8 sas_format:1;
   2834	u8 reserved1:7;
   2835	u8 reserved2[3];
   2836	u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
   2837	u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
   2838	u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
   2839	u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
   2840	u16 component_id;
   2841	u8 component_revision_id;
   2842	u8 reserved3;
   2843	u8 vendor_specific[8];
   2844};
   2845
   2846/**
   2847  * mptsas_exp_repmanufacture_info - sets expander manufacturer info
   2848  * @ioc: per adapter object
   2849  * @sas_address: expander sas address
   2850  * @edev: the sas_expander_device object
   2851  *
   2852  * For an edge expander or a fanout expander:
   2853  * fills in the sas_expander_device object when SMP port is created.
   2854  *
   2855  * Return: 0 for success, non-zero for failure.
   2856  */
   2857static int
   2858mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
   2859	u64 sas_address, struct sas_expander_device *edev)
   2860{
   2861	MPT_FRAME_HDR *mf;
   2862	SmpPassthroughRequest_t *smpreq;
   2863	SmpPassthroughReply_t *smprep;
   2864	struct rep_manu_reply *manufacture_reply;
   2865	struct rep_manu_request *manufacture_request;
   2866	int ret;
   2867	int flagsLength;
   2868	unsigned long timeleft;
   2869	char *psge;
   2870	unsigned long flags;
   2871	void *data_out = NULL;
   2872	dma_addr_t data_out_dma = 0;
   2873	u32 sz;
   2874
   2875	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
   2876	if (ioc->ioc_reset_in_progress) {
   2877		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
   2878		printk(MYIOC_s_INFO_FMT "%s: host reset in progress!\n",
   2879			__func__, ioc->name);
   2880		return -EFAULT;
   2881	}
   2882	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
   2883
   2884	ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
   2885	if (ret)
   2886		goto out;
   2887
   2888	mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
   2889	if (!mf) {
   2890		ret = -ENOMEM;
   2891		goto out_unlock;
   2892	}
   2893
   2894	smpreq = (SmpPassthroughRequest_t *)mf;
   2895	memset(smpreq, 0, sizeof(*smpreq));
   2896
   2897	sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
   2898
   2899	data_out = dma_alloc_coherent(&ioc->pcidev->dev, sz, &data_out_dma,
   2900				      GFP_KERNEL);
   2901	if (!data_out) {
   2902		printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
   2903			__FILE__, __LINE__, __func__);
   2904		ret = -ENOMEM;
   2905		goto put_mf;
   2906	}
   2907
   2908	manufacture_request = data_out;
   2909	manufacture_request->smp_frame_type = 0x40;
   2910	manufacture_request->function = 1;
   2911	manufacture_request->reserved = 0;
   2912	manufacture_request->request_length = 0;
   2913
   2914	smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
   2915	smpreq->PhysicalPort = 0xFF;
   2916	*((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
   2917	smpreq->RequestDataLength = sizeof(struct rep_manu_request);
   2918
   2919	psge = (char *)
   2920		(((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
   2921
   2922	flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
   2923		MPI_SGE_FLAGS_SYSTEM_ADDRESS |
   2924		MPI_SGE_FLAGS_HOST_TO_IOC |
   2925		MPI_SGE_FLAGS_END_OF_BUFFER;
   2926	flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
   2927	flagsLength |= sizeof(struct rep_manu_request);
   2928
   2929	ioc->add_sge(psge, flagsLength, data_out_dma);
   2930	psge += ioc->SGE_size;
   2931
   2932	flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
   2933		MPI_SGE_FLAGS_SYSTEM_ADDRESS |
   2934		MPI_SGE_FLAGS_IOC_TO_HOST |
   2935		MPI_SGE_FLAGS_END_OF_BUFFER;
   2936	flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
   2937	flagsLength |= sizeof(struct rep_manu_reply);
   2938	ioc->add_sge(psge, flagsLength, data_out_dma +
   2939	sizeof(struct rep_manu_request));
   2940
   2941	INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
   2942	mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
   2943
   2944	timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
   2945	if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
   2946		ret = -ETIME;
   2947		mpt_free_msg_frame(ioc, mf);
   2948		mf = NULL;
   2949		if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
   2950			goto out_free;
   2951		if (!timeleft)
   2952			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
   2953		goto out_free;
   2954	}
   2955
   2956	mf = NULL;
   2957
   2958	if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
   2959		u8 *tmp;
   2960
   2961		smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
   2962		if (le16_to_cpu(smprep->ResponseDataLength) !=
   2963		    sizeof(struct rep_manu_reply))
   2964			goto out_free;
   2965
   2966		manufacture_reply = data_out + sizeof(struct rep_manu_request);
   2967		strncpy(edev->vendor_id, manufacture_reply->vendor_id,
   2968			SAS_EXPANDER_VENDOR_ID_LEN);
   2969		strncpy(edev->product_id, manufacture_reply->product_id,
   2970			SAS_EXPANDER_PRODUCT_ID_LEN);
   2971		strncpy(edev->product_rev, manufacture_reply->product_rev,
   2972			SAS_EXPANDER_PRODUCT_REV_LEN);
   2973		edev->level = manufacture_reply->sas_format;
   2974		if (manufacture_reply->sas_format) {
   2975			strncpy(edev->component_vendor_id,
   2976				manufacture_reply->component_vendor_id,
   2977				SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
   2978			tmp = (u8 *)&manufacture_reply->component_id;
   2979			edev->component_id = tmp[0] << 8 | tmp[1];
   2980			edev->component_revision_id =
   2981				manufacture_reply->component_revision_id;
   2982		}
   2983	} else {
   2984		printk(MYIOC_s_ERR_FMT
   2985			"%s: smp passthru reply failed to be returned\n",
   2986			ioc->name, __func__);
   2987		ret = -ENXIO;
   2988	}
   2989out_free:
   2990	if (data_out_dma)
   2991		dma_free_coherent(&ioc->pcidev->dev, sz, data_out,
   2992				  data_out_dma);
   2993put_mf:
   2994	if (mf)
   2995		mpt_free_msg_frame(ioc, mf);
   2996out_unlock:
   2997	CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
   2998	mutex_unlock(&ioc->sas_mgmt.mutex);
   2999out:
   3000	return ret;
   3001}
   3002
   3003static void
   3004mptsas_parse_device_info(struct sas_identify *identify,
   3005		struct mptsas_devinfo *device_info)
   3006{
   3007	u16 protocols;
   3008
   3009	identify->sas_address = device_info->sas_address;
   3010	identify->phy_identifier = device_info->phy_id;
   3011
   3012	/*
   3013	 * Fill in Phy Initiator Port Protocol.
   3014	 * Bits 6:3, more than one bit can be set, fall through cases.
   3015	 */
   3016	protocols = device_info->device_info & 0x78;
   3017	identify->initiator_port_protocols = 0;
   3018	if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
   3019		identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
   3020	if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
   3021		identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
   3022	if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
   3023		identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
   3024	if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
   3025		identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
   3026
   3027	/*
   3028	 * Fill in Phy Target Port Protocol.
   3029	 * Bits 10:7, more than one bit can be set, fall through cases.
   3030	 */
   3031	protocols = device_info->device_info & 0x780;
   3032	identify->target_port_protocols = 0;
   3033	if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
   3034		identify->target_port_protocols |= SAS_PROTOCOL_SSP;
   3035	if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
   3036		identify->target_port_protocols |= SAS_PROTOCOL_STP;
   3037	if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
   3038		identify->target_port_protocols |= SAS_PROTOCOL_SMP;
   3039	if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
   3040		identify->target_port_protocols |= SAS_PROTOCOL_SATA;
   3041
   3042	/*
   3043	 * Fill in Attached device type.
   3044	 */
   3045	switch (device_info->device_info &
   3046			MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
   3047	case MPI_SAS_DEVICE_INFO_NO_DEVICE:
   3048		identify->device_type = SAS_PHY_UNUSED;
   3049		break;
   3050	case MPI_SAS_DEVICE_INFO_END_DEVICE:
   3051		identify->device_type = SAS_END_DEVICE;
   3052		break;
   3053	case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
   3054		identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
   3055		break;
   3056	case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
   3057		identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
   3058		break;
   3059	}
   3060}
   3061
   3062static int mptsas_probe_one_phy(struct device *dev,
   3063		struct mptsas_phyinfo *phy_info, int index, int local)
   3064{
   3065	MPT_ADAPTER *ioc;
   3066	struct sas_phy *phy;
   3067	struct sas_port *port;
   3068	int error = 0;
   3069	VirtTarget *vtarget;
   3070
   3071	if (!dev) {
   3072		error = -ENODEV;
   3073		goto out;
   3074	}
   3075
   3076	if (!phy_info->phy) {
   3077		phy = sas_phy_alloc(dev, index);
   3078		if (!phy) {
   3079			error = -ENOMEM;
   3080			goto out;
   3081		}
   3082	} else
   3083		phy = phy_info->phy;
   3084
   3085	mptsas_parse_device_info(&phy->identify, &phy_info->identify);
   3086
   3087	/*
   3088	 * Set Negotiated link rate.
   3089	 */
   3090	switch (phy_info->negotiated_link_rate) {
   3091	case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
   3092		phy->negotiated_linkrate = SAS_PHY_DISABLED;
   3093		break;
   3094	case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
   3095		phy->negotiated_linkrate = SAS_LINK_RATE_FAILED;
   3096		break;
   3097	case MPI_SAS_IOUNIT0_RATE_1_5:
   3098		phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
   3099		break;
   3100	case MPI_SAS_IOUNIT0_RATE_3_0:
   3101		phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
   3102		break;
   3103	case MPI_SAS_IOUNIT0_RATE_6_0:
   3104		phy->negotiated_linkrate = SAS_LINK_RATE_6_0_GBPS;
   3105		break;
   3106	case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
   3107	case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
   3108	default:
   3109		phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
   3110		break;
   3111	}
   3112
   3113	/*
   3114	 * Set Max hardware link rate.
   3115	 */
   3116	switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
   3117	case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
   3118		phy->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
   3119		break;
   3120	case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
   3121		phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
   3122		break;
   3123	default:
   3124		break;
   3125	}
   3126
   3127	/*
   3128	 * Set Max programmed link rate.
   3129	 */
   3130	switch (phy_info->programmed_link_rate &
   3131			MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
   3132	case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
   3133		phy->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
   3134		break;
   3135	case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
   3136		phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
   3137		break;
   3138	default:
   3139		break;
   3140	}
   3141
   3142	/*
   3143	 * Set Min hardware link rate.
   3144	 */
   3145	switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
   3146	case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
   3147		phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
   3148		break;
   3149	case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
   3150		phy->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
   3151		break;
   3152	default:
   3153		break;
   3154	}
   3155
   3156	/*
   3157	 * Set Min programmed link rate.
   3158	 */
   3159	switch (phy_info->programmed_link_rate &
   3160			MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
   3161	case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
   3162		phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
   3163		break;
   3164	case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
   3165		phy->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
   3166		break;
   3167	default:
   3168		break;
   3169	}
   3170
   3171	if (!phy_info->phy) {
   3172
   3173		error = sas_phy_add(phy);
   3174		if (error) {
   3175			sas_phy_free(phy);
   3176			goto out;
   3177		}
   3178		phy_info->phy = phy;
   3179	}
   3180
   3181	if (!phy_info->attached.handle ||
   3182			!phy_info->port_details)
   3183		goto out;
   3184
   3185	port = mptsas_get_port(phy_info);
   3186	ioc = phy_to_ioc(phy_info->phy);
   3187
   3188	if (phy_info->sas_port_add_phy) {
   3189
   3190		if (!port) {
   3191			port = sas_port_alloc_num(dev);
   3192			if (!port) {
   3193				error = -ENOMEM;
   3194				goto out;
   3195			}
   3196			error = sas_port_add(port);
   3197			if (error) {
   3198				dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   3199					"%s: exit at line=%d\n", ioc->name,
   3200					__func__, __LINE__));
   3201				goto out;
   3202			}
   3203			mptsas_set_port(ioc, phy_info, port);
   3204			devtprintk(ioc, dev_printk(KERN_DEBUG, &port->dev,
   3205			    MYIOC_s_FMT "add port %d, sas_addr (0x%llx)\n",
   3206			    ioc->name, port->port_identifier,
   3207			    (unsigned long long)phy_info->
   3208			    attached.sas_address));
   3209		}
   3210		dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   3211			"sas_port_add_phy: phy_id=%d\n",
   3212			ioc->name, phy_info->phy_id));
   3213		sas_port_add_phy(port, phy_info->phy);
   3214		phy_info->sas_port_add_phy = 0;
   3215		devtprintk(ioc, dev_printk(KERN_DEBUG, &phy_info->phy->dev,
   3216		    MYIOC_s_FMT "add phy %d, phy-obj (0x%p)\n", ioc->name,
   3217		     phy_info->phy_id, phy_info->phy));
   3218	}
   3219	if (!mptsas_get_rphy(phy_info) && port && !port->rphy) {
   3220
   3221		struct sas_rphy *rphy;
   3222		struct device *parent;
   3223		struct sas_identify identify;
   3224
   3225		parent = dev->parent->parent;
   3226		/*
   3227		 * Let the hotplug_work thread handle processing
   3228		 * the adding/removing of devices that occur
   3229		 * after start of day.
   3230		 */
   3231		if (mptsas_is_end_device(&phy_info->attached) &&
   3232		    phy_info->attached.handle_parent) {
   3233			goto out;
   3234		}
   3235
   3236		mptsas_parse_device_info(&identify, &phy_info->attached);
   3237		if (scsi_is_host_device(parent)) {
   3238			struct mptsas_portinfo *port_info;
   3239			int i;
   3240
   3241			port_info = ioc->hba_port_info;
   3242
   3243			for (i = 0; i < port_info->num_phys; i++)
   3244				if (port_info->phy_info[i].identify.sas_address ==
   3245				    identify.sas_address) {
   3246					sas_port_mark_backlink(port);
   3247					goto out;
   3248				}
   3249
   3250		} else if (scsi_is_sas_rphy(parent)) {
   3251			struct sas_rphy *parent_rphy = dev_to_rphy(parent);
   3252			if (identify.sas_address ==
   3253			    parent_rphy->identify.sas_address) {
   3254				sas_port_mark_backlink(port);
   3255				goto out;
   3256			}
   3257		}
   3258
   3259		switch (identify.device_type) {
   3260		case SAS_END_DEVICE:
   3261			rphy = sas_end_device_alloc(port);
   3262			break;
   3263		case SAS_EDGE_EXPANDER_DEVICE:
   3264		case SAS_FANOUT_EXPANDER_DEVICE:
   3265			rphy = sas_expander_alloc(port, identify.device_type);
   3266			break;
   3267		default:
   3268			rphy = NULL;
   3269			break;
   3270		}
   3271		if (!rphy) {
   3272			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   3273				"%s: exit at line=%d\n", ioc->name,
   3274				__func__, __LINE__));
   3275			goto out;
   3276		}
   3277
   3278		rphy->identify = identify;
   3279		error = sas_rphy_add(rphy);
   3280		if (error) {
   3281			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   3282				"%s: exit at line=%d\n", ioc->name,
   3283				__func__, __LINE__));
   3284			sas_rphy_free(rphy);
   3285			goto out;
   3286		}
   3287		mptsas_set_rphy(ioc, phy_info, rphy);
   3288		if (identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
   3289			identify.device_type == SAS_FANOUT_EXPANDER_DEVICE)
   3290				mptsas_exp_repmanufacture_info(ioc,
   3291					identify.sas_address,
   3292					rphy_to_expander_device(rphy));
   3293	}
   3294
   3295	/* If the device exists, verify it wasn't previously flagged
   3296	as a missing device.  If so, clear it */
   3297	vtarget = mptsas_find_vtarget(ioc,
   3298	    phy_info->attached.channel,
   3299	    phy_info->attached.id);
   3300	if (vtarget && vtarget->inDMD) {
   3301		printk(KERN_INFO "Device returned, unsetting inDMD\n");
   3302		vtarget->inDMD = 0;
   3303	}
   3304
   3305 out:
   3306	return error;
   3307}
   3308
   3309static int
   3310mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
   3311{
   3312	struct mptsas_portinfo *port_info, *hba;
   3313	int error = -ENOMEM, i;
   3314
   3315	hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
   3316	if (! hba)
   3317		goto out;
   3318
   3319	error = mptsas_sas_io_unit_pg0(ioc, hba);
   3320	if (error)
   3321		goto out_free_port_info;
   3322
   3323	mptsas_sas_io_unit_pg1(ioc);
   3324	mutex_lock(&ioc->sas_topology_mutex);
   3325	port_info = ioc->hba_port_info;
   3326	if (!port_info) {
   3327		ioc->hba_port_info = port_info = hba;
   3328		ioc->hba_port_num_phy = port_info->num_phys;
   3329		list_add_tail(&port_info->list, &ioc->sas_topology);
   3330	} else {
   3331		for (i = 0; i < hba->num_phys; i++) {
   3332			port_info->phy_info[i].negotiated_link_rate =
   3333				hba->phy_info[i].negotiated_link_rate;
   3334			port_info->phy_info[i].handle =
   3335				hba->phy_info[i].handle;
   3336			port_info->phy_info[i].port_id =
   3337				hba->phy_info[i].port_id;
   3338		}
   3339		kfree(hba->phy_info);
   3340		kfree(hba);
   3341		hba = NULL;
   3342	}
   3343	mutex_unlock(&ioc->sas_topology_mutex);
   3344#if defined(CPQ_CIM)
   3345	ioc->num_ports = port_info->num_phys;
   3346#endif
   3347	for (i = 0; i < port_info->num_phys; i++) {
   3348		mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
   3349			(MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
   3350			 MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
   3351		port_info->phy_info[i].identify.handle =
   3352		    port_info->phy_info[i].handle;
   3353		mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
   3354			(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
   3355			 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
   3356			 port_info->phy_info[i].identify.handle);
   3357		if (!ioc->hba_port_sas_addr)
   3358			ioc->hba_port_sas_addr =
   3359			    port_info->phy_info[i].identify.sas_address;
   3360		port_info->phy_info[i].identify.phy_id =
   3361		    port_info->phy_info[i].phy_id = i;
   3362		if (port_info->phy_info[i].attached.handle)
   3363			mptsas_sas_device_pg0(ioc,
   3364				&port_info->phy_info[i].attached,
   3365				(MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
   3366				 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
   3367				port_info->phy_info[i].attached.handle);
   3368	}
   3369
   3370	mptsas_setup_wide_ports(ioc, port_info);
   3371
   3372	for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
   3373		mptsas_probe_one_phy(&ioc->sh->shost_gendev,
   3374		    &port_info->phy_info[i], ioc->sas_index, 1);
   3375
   3376	return 0;
   3377
   3378 out_free_port_info:
   3379	kfree(hba);
   3380 out:
   3381	return error;
   3382}
   3383
   3384static void
   3385mptsas_expander_refresh(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
   3386{
   3387	struct mptsas_portinfo *parent;
   3388	struct device *parent_dev;
   3389	struct sas_rphy	*rphy;
   3390	int		i;
   3391	u64		sas_address; /* expander sas address */
   3392	u32		handle;
   3393
   3394	handle = port_info->phy_info[0].handle;
   3395	sas_address = port_info->phy_info[0].identify.sas_address;
   3396	for (i = 0; i < port_info->num_phys; i++) {
   3397		mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
   3398		    (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
   3399		    MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + handle);
   3400
   3401		mptsas_sas_device_pg0(ioc,
   3402		    &port_info->phy_info[i].identify,
   3403		    (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
   3404		    MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
   3405		    port_info->phy_info[i].identify.handle);
   3406		port_info->phy_info[i].identify.phy_id =
   3407		    port_info->phy_info[i].phy_id;
   3408
   3409		if (port_info->phy_info[i].attached.handle) {
   3410			mptsas_sas_device_pg0(ioc,
   3411			    &port_info->phy_info[i].attached,
   3412			    (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
   3413			     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
   3414			    port_info->phy_info[i].attached.handle);
   3415			port_info->phy_info[i].attached.phy_id =
   3416			    port_info->phy_info[i].phy_id;
   3417		}
   3418	}
   3419
   3420	mutex_lock(&ioc->sas_topology_mutex);
   3421	parent = mptsas_find_portinfo_by_handle(ioc,
   3422	    port_info->phy_info[0].identify.handle_parent);
   3423	if (!parent) {
   3424		mutex_unlock(&ioc->sas_topology_mutex);
   3425		return;
   3426	}
   3427	for (i = 0, parent_dev = NULL; i < parent->num_phys && !parent_dev;
   3428	    i++) {
   3429		if (parent->phy_info[i].attached.sas_address == sas_address) {
   3430			rphy = mptsas_get_rphy(&parent->phy_info[i]);
   3431			parent_dev = &rphy->dev;
   3432		}
   3433	}
   3434	mutex_unlock(&ioc->sas_topology_mutex);
   3435
   3436	mptsas_setup_wide_ports(ioc, port_info);
   3437	for (i = 0; i < port_info->num_phys; i++, ioc->sas_index++)
   3438		mptsas_probe_one_phy(parent_dev, &port_info->phy_info[i],
   3439		    ioc->sas_index, 0);
   3440}
   3441
   3442static void
   3443mptsas_expander_event_add(MPT_ADAPTER *ioc,
   3444    MpiEventDataSasExpanderStatusChange_t *expander_data)
   3445{
   3446	struct mptsas_portinfo *port_info;
   3447	int i;
   3448	__le64 sas_address;
   3449
   3450	port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
   3451	BUG_ON(!port_info);
   3452	port_info->num_phys = (expander_data->NumPhys) ?
   3453	    expander_data->NumPhys : 1;
   3454	port_info->phy_info = kcalloc(port_info->num_phys,
   3455	    sizeof(struct mptsas_phyinfo), GFP_KERNEL);
   3456	BUG_ON(!port_info->phy_info);
   3457	memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
   3458	for (i = 0; i < port_info->num_phys; i++) {
   3459		port_info->phy_info[i].portinfo = port_info;
   3460		port_info->phy_info[i].handle =
   3461		    le16_to_cpu(expander_data->DevHandle);
   3462		port_info->phy_info[i].identify.sas_address =
   3463		    le64_to_cpu(sas_address);
   3464		port_info->phy_info[i].identify.handle_parent =
   3465		    le16_to_cpu(expander_data->ParentDevHandle);
   3466	}
   3467
   3468	mutex_lock(&ioc->sas_topology_mutex);
   3469	list_add_tail(&port_info->list, &ioc->sas_topology);
   3470	mutex_unlock(&ioc->sas_topology_mutex);
   3471
   3472	printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
   3473	    "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
   3474	    (unsigned long long)sas_address);
   3475
   3476	mptsas_expander_refresh(ioc, port_info);
   3477}
   3478
   3479/**
   3480 * mptsas_delete_expander_siblings - remove siblings attached to expander
   3481 * @ioc: Pointer to MPT_ADAPTER structure
   3482 * @parent: the parent port_info object
   3483 * @expander: the expander port_info object
   3484 **/
   3485static void
   3486mptsas_delete_expander_siblings(MPT_ADAPTER *ioc, struct mptsas_portinfo
   3487    *parent, struct mptsas_portinfo *expander)
   3488{
   3489	struct mptsas_phyinfo *phy_info;
   3490	struct mptsas_portinfo *port_info;
   3491	struct sas_rphy *rphy;
   3492	int i;
   3493
   3494	phy_info = expander->phy_info;
   3495	for (i = 0; i < expander->num_phys; i++, phy_info++) {
   3496		rphy = mptsas_get_rphy(phy_info);
   3497		if (!rphy)
   3498			continue;
   3499		if (rphy->identify.device_type == SAS_END_DEVICE)
   3500			mptsas_del_end_device(ioc, phy_info);
   3501	}
   3502
   3503	phy_info = expander->phy_info;
   3504	for (i = 0; i < expander->num_phys; i++, phy_info++) {
   3505		rphy = mptsas_get_rphy(phy_info);
   3506		if (!rphy)
   3507			continue;
   3508		if (rphy->identify.device_type ==
   3509		    MPI_SAS_DEVICE_INFO_EDGE_EXPANDER ||
   3510		    rphy->identify.device_type ==
   3511		    MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER) {
   3512			port_info = mptsas_find_portinfo_by_sas_address(ioc,
   3513			    rphy->identify.sas_address);
   3514			if (!port_info)
   3515				continue;
   3516			if (port_info == parent) /* backlink rphy */
   3517				continue;
   3518			/*
   3519			Delete this expander even if the expdevpage is exists
   3520			because the parent expander is already deleted
   3521			*/
   3522			mptsas_expander_delete(ioc, port_info, 1);
   3523		}
   3524	}
   3525}
   3526
   3527
   3528/**
   3529 *	mptsas_expander_delete - remove this expander
   3530 *	@ioc: Pointer to MPT_ADAPTER structure
   3531 *	@port_info: expander port_info struct
   3532 *	@force: Flag to forcefully delete the expander
   3533 *
   3534 **/
   3535
   3536static void mptsas_expander_delete(MPT_ADAPTER *ioc,
   3537		struct mptsas_portinfo *port_info, u8 force)
   3538{
   3539
   3540	struct mptsas_portinfo *parent;
   3541	int		i;
   3542	u64		expander_sas_address;
   3543	struct mptsas_phyinfo *phy_info;
   3544	struct mptsas_portinfo buffer;
   3545	struct mptsas_portinfo_details *port_details;
   3546	struct sas_port *port;
   3547
   3548	if (!port_info)
   3549		return;
   3550
   3551	/* see if expander is still there before deleting */
   3552	mptsas_sas_expander_pg0(ioc, &buffer,
   3553	    (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
   3554	    MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
   3555	    port_info->phy_info[0].identify.handle);
   3556
   3557	if (buffer.num_phys) {
   3558		kfree(buffer.phy_info);
   3559		if (!force)
   3560			return;
   3561	}
   3562
   3563
   3564	/*
   3565	 * Obtain the port_info instance to the parent port
   3566	 */
   3567	port_details = NULL;
   3568	expander_sas_address =
   3569	    port_info->phy_info[0].identify.sas_address;
   3570	parent = mptsas_find_portinfo_by_handle(ioc,
   3571	    port_info->phy_info[0].identify.handle_parent);
   3572	mptsas_delete_expander_siblings(ioc, parent, port_info);
   3573	if (!parent)
   3574		goto out;
   3575
   3576	/*
   3577	 * Delete rphys in the parent that point
   3578	 * to this expander.
   3579	 */
   3580	phy_info = parent->phy_info;
   3581	port = NULL;
   3582	for (i = 0; i < parent->num_phys; i++, phy_info++) {
   3583		if (!phy_info->phy)
   3584			continue;
   3585		if (phy_info->attached.sas_address !=
   3586		    expander_sas_address)
   3587			continue;
   3588		if (!port) {
   3589			port = mptsas_get_port(phy_info);
   3590			port_details = phy_info->port_details;
   3591		}
   3592		dev_printk(KERN_DEBUG, &phy_info->phy->dev,
   3593		    MYIOC_s_FMT "delete phy %d, phy-obj (0x%p)\n", ioc->name,
   3594		    phy_info->phy_id, phy_info->phy);
   3595		sas_port_delete_phy(port, phy_info->phy);
   3596	}
   3597	if (port) {
   3598		dev_printk(KERN_DEBUG, &port->dev,
   3599		    MYIOC_s_FMT "delete port %d, sas_addr (0x%llx)\n",
   3600		    ioc->name, port->port_identifier,
   3601		    (unsigned long long)expander_sas_address);
   3602		sas_port_delete(port);
   3603		mptsas_port_delete(ioc, port_details);
   3604	}
   3605 out:
   3606
   3607	printk(MYIOC_s_INFO_FMT "delete expander: num_phys %d, "
   3608	    "sas_addr (0x%llx)\n",  ioc->name, port_info->num_phys,
   3609	    (unsigned long long)expander_sas_address);
   3610
   3611	/*
   3612	 * free link
   3613	 */
   3614	list_del(&port_info->list);
   3615	kfree(port_info->phy_info);
   3616	kfree(port_info);
   3617}
   3618
   3619
   3620/**
   3621 * mptsas_send_expander_event - expanders events
   3622 * @fw_event: event data
   3623 *
   3624 *
   3625 * This function handles adding, removing, and refreshing
   3626 * device handles within the expander objects.
   3627 */
   3628static void
   3629mptsas_send_expander_event(struct fw_event_work *fw_event)
   3630{
   3631	MPT_ADAPTER *ioc;
   3632	MpiEventDataSasExpanderStatusChange_t *expander_data;
   3633	struct mptsas_portinfo *port_info;
   3634	__le64 sas_address;
   3635	int i;
   3636
   3637	ioc = fw_event->ioc;
   3638	expander_data = (MpiEventDataSasExpanderStatusChange_t *)
   3639	    fw_event->event_data;
   3640	memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
   3641	sas_address = le64_to_cpu(sas_address);
   3642	port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
   3643
   3644	if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
   3645		if (port_info) {
   3646			for (i = 0; i < port_info->num_phys; i++) {
   3647				port_info->phy_info[i].portinfo = port_info;
   3648				port_info->phy_info[i].handle =
   3649				    le16_to_cpu(expander_data->DevHandle);
   3650				port_info->phy_info[i].identify.sas_address =
   3651				    le64_to_cpu(sas_address);
   3652				port_info->phy_info[i].identify.handle_parent =
   3653				    le16_to_cpu(expander_data->ParentDevHandle);
   3654			}
   3655			mptsas_expander_refresh(ioc, port_info);
   3656		} else if (!port_info && expander_data->NumPhys)
   3657			mptsas_expander_event_add(ioc, expander_data);
   3658	} else if (expander_data->ReasonCode ==
   3659	    MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING)
   3660		mptsas_expander_delete(ioc, port_info, 0);
   3661
   3662	mptsas_free_fw_event(ioc, fw_event);
   3663}
   3664
   3665
   3666/**
   3667 * mptsas_expander_add - adds a newly discovered expander
   3668 * @ioc: Pointer to MPT_ADAPTER structure
   3669 * @handle: device handle
   3670 *
   3671 */
   3672static struct mptsas_portinfo *
   3673mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
   3674{
   3675	struct mptsas_portinfo buffer, *port_info;
   3676	int i;
   3677
   3678	if ((mptsas_sas_expander_pg0(ioc, &buffer,
   3679	    (MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
   3680	    MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
   3681		return NULL;
   3682
   3683	port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
   3684	if (!port_info) {
   3685		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   3686		"%s: exit at line=%d\n", ioc->name,
   3687		__func__, __LINE__));
   3688		return NULL;
   3689	}
   3690	port_info->num_phys = buffer.num_phys;
   3691	port_info->phy_info = buffer.phy_info;
   3692	for (i = 0; i < port_info->num_phys; i++)
   3693		port_info->phy_info[i].portinfo = port_info;
   3694	mutex_lock(&ioc->sas_topology_mutex);
   3695	list_add_tail(&port_info->list, &ioc->sas_topology);
   3696	mutex_unlock(&ioc->sas_topology_mutex);
   3697	printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
   3698	    "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
   3699	    (unsigned long long)buffer.phy_info[0].identify.sas_address);
   3700	mptsas_expander_refresh(ioc, port_info);
   3701	return port_info;
   3702}
   3703
   3704static void
   3705mptsas_send_link_status_event(struct fw_event_work *fw_event)
   3706{
   3707	MPT_ADAPTER *ioc;
   3708	MpiEventDataSasPhyLinkStatus_t *link_data;
   3709	struct mptsas_portinfo *port_info;
   3710	struct mptsas_phyinfo *phy_info = NULL;
   3711	__le64 sas_address;
   3712	u8 phy_num;
   3713	u8 link_rate;
   3714
   3715	ioc = fw_event->ioc;
   3716	link_data = (MpiEventDataSasPhyLinkStatus_t *)fw_event->event_data;
   3717
   3718	memcpy(&sas_address, &link_data->SASAddress, sizeof(__le64));
   3719	sas_address = le64_to_cpu(sas_address);
   3720	link_rate = link_data->LinkRates >> 4;
   3721	phy_num = link_data->PhyNum;
   3722
   3723	port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
   3724	if (port_info) {
   3725		phy_info = &port_info->phy_info[phy_num];
   3726		if (phy_info)
   3727			phy_info->negotiated_link_rate = link_rate;
   3728	}
   3729
   3730	if (link_rate == MPI_SAS_IOUNIT0_RATE_1_5 ||
   3731	    link_rate == MPI_SAS_IOUNIT0_RATE_3_0 ||
   3732	    link_rate == MPI_SAS_IOUNIT0_RATE_6_0) {
   3733
   3734		if (!port_info) {
   3735			if (ioc->old_sas_discovery_protocal) {
   3736				port_info = mptsas_expander_add(ioc,
   3737					le16_to_cpu(link_data->DevHandle));
   3738				if (port_info)
   3739					goto out;
   3740			}
   3741			goto out;
   3742		}
   3743
   3744		if (port_info == ioc->hba_port_info)
   3745			mptsas_probe_hba_phys(ioc);
   3746		else
   3747			mptsas_expander_refresh(ioc, port_info);
   3748	} else if (phy_info && phy_info->phy) {
   3749		if (link_rate ==  MPI_SAS_IOUNIT0_RATE_PHY_DISABLED)
   3750			phy_info->phy->negotiated_linkrate =
   3751			    SAS_PHY_DISABLED;
   3752		else if (link_rate ==
   3753		    MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION)
   3754			phy_info->phy->negotiated_linkrate =
   3755			    SAS_LINK_RATE_FAILED;
   3756		else {
   3757			phy_info->phy->negotiated_linkrate =
   3758			    SAS_LINK_RATE_UNKNOWN;
   3759			if (ioc->device_missing_delay &&
   3760			    mptsas_is_end_device(&phy_info->attached)) {
   3761				struct scsi_device		*sdev;
   3762				VirtDevice			*vdevice;
   3763				u8	channel, id;
   3764				id = phy_info->attached.id;
   3765				channel = phy_info->attached.channel;
   3766				devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   3767				"Link down for fw_id %d:fw_channel %d\n",
   3768				    ioc->name, phy_info->attached.id,
   3769				    phy_info->attached.channel));
   3770
   3771				shost_for_each_device(sdev, ioc->sh) {
   3772					vdevice = sdev->hostdata;
   3773					if ((vdevice == NULL) ||
   3774						(vdevice->vtarget == NULL))
   3775						continue;
   3776					if ((vdevice->vtarget->tflags &
   3777					    MPT_TARGET_FLAGS_RAID_COMPONENT ||
   3778					    vdevice->vtarget->raidVolume))
   3779						continue;
   3780					if (vdevice->vtarget->id == id &&
   3781						vdevice->vtarget->channel ==
   3782						channel)
   3783						devtprintk(ioc,
   3784						printk(MYIOC_s_DEBUG_FMT
   3785						"SDEV OUTSTANDING CMDS"
   3786						"%d\n", ioc->name,
   3787						scsi_device_busy(sdev)));
   3788				}
   3789
   3790			}
   3791		}
   3792	}
   3793 out:
   3794	mptsas_free_fw_event(ioc, fw_event);
   3795}
   3796
   3797static void
   3798mptsas_not_responding_devices(MPT_ADAPTER *ioc)
   3799{
   3800	struct mptsas_portinfo buffer, *port_info;
   3801	struct mptsas_device_info	*sas_info;
   3802	struct mptsas_devinfo sas_device;
   3803	u32	handle;
   3804	VirtTarget *vtarget = NULL;
   3805	struct mptsas_phyinfo *phy_info;
   3806	u8 found_expander;
   3807	int retval, retry_count;
   3808	unsigned long flags;
   3809
   3810	mpt_findImVolumes(ioc);
   3811
   3812	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
   3813	if (ioc->ioc_reset_in_progress) {
   3814		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   3815		   "%s: exiting due to a parallel reset \n", ioc->name,
   3816		    __func__));
   3817		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
   3818		return;
   3819	}
   3820	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
   3821
   3822	/* devices, logical volumes */
   3823	mutex_lock(&ioc->sas_device_info_mutex);
   3824 redo_device_scan:
   3825	list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) {
   3826		if (sas_info->is_cached)
   3827			continue;
   3828		if (!sas_info->is_logical_volume) {
   3829			sas_device.handle = 0;
   3830			retry_count = 0;
   3831retry_page:
   3832			retval = mptsas_sas_device_pg0(ioc, &sas_device,
   3833				(MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID
   3834				<< MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
   3835				(sas_info->fw.channel << 8) +
   3836				sas_info->fw.id);
   3837
   3838			if (sas_device.handle)
   3839				continue;
   3840			if (retval == -EBUSY) {
   3841				spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
   3842				if (ioc->ioc_reset_in_progress) {
   3843					dfailprintk(ioc,
   3844					printk(MYIOC_s_DEBUG_FMT
   3845					"%s: exiting due to reset\n",
   3846					ioc->name, __func__));
   3847					spin_unlock_irqrestore
   3848					(&ioc->taskmgmt_lock, flags);
   3849					mutex_unlock(&ioc->
   3850					sas_device_info_mutex);
   3851					return;
   3852				}
   3853				spin_unlock_irqrestore(&ioc->taskmgmt_lock,
   3854				flags);
   3855			}
   3856
   3857			if (retval && (retval != -ENODEV)) {
   3858				if (retry_count < 10) {
   3859					retry_count++;
   3860					goto retry_page;
   3861				} else {
   3862					devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   3863					"%s: Config page retry exceeded retry "
   3864					"count deleting device 0x%llx\n",
   3865					ioc->name, __func__,
   3866					sas_info->sas_address));
   3867				}
   3868			}
   3869
   3870			/* delete device */
   3871			vtarget = mptsas_find_vtarget(ioc,
   3872				sas_info->fw.channel, sas_info->fw.id);
   3873
   3874			if (vtarget)
   3875				vtarget->deleted = 1;
   3876
   3877			phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
   3878					sas_info->sas_address);
   3879
   3880			mptsas_del_end_device(ioc, phy_info);
   3881			goto redo_device_scan;
   3882		} else
   3883			mptsas_volume_delete(ioc, sas_info->fw.id);
   3884	}
   3885	mutex_unlock(&ioc->sas_device_info_mutex);
   3886
   3887	/* expanders */
   3888	mutex_lock(&ioc->sas_topology_mutex);
   3889 redo_expander_scan:
   3890	list_for_each_entry(port_info, &ioc->sas_topology, list) {
   3891
   3892		if (!(port_info->phy_info[0].identify.device_info &
   3893		    MPI_SAS_DEVICE_INFO_SMP_TARGET))
   3894			continue;
   3895		found_expander = 0;
   3896		handle = 0xFFFF;
   3897		while (!mptsas_sas_expander_pg0(ioc, &buffer,
   3898		    (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
   3899		     MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle) &&
   3900		    !found_expander) {
   3901
   3902			handle = buffer.phy_info[0].handle;
   3903			if (buffer.phy_info[0].identify.sas_address ==
   3904			    port_info->phy_info[0].identify.sas_address) {
   3905				found_expander = 1;
   3906			}
   3907			kfree(buffer.phy_info);
   3908		}
   3909
   3910		if (!found_expander) {
   3911			mptsas_expander_delete(ioc, port_info, 0);
   3912			goto redo_expander_scan;
   3913		}
   3914	}
   3915	mutex_unlock(&ioc->sas_topology_mutex);
   3916}
   3917
   3918/**
   3919 *	mptsas_probe_expanders - adding expanders
   3920 *	@ioc: Pointer to MPT_ADAPTER structure
   3921 *
   3922 **/
   3923static void
   3924mptsas_probe_expanders(MPT_ADAPTER *ioc)
   3925{
   3926	struct mptsas_portinfo buffer, *port_info;
   3927	u32 			handle;
   3928	int i;
   3929
   3930	handle = 0xFFFF;
   3931	while (!mptsas_sas_expander_pg0(ioc, &buffer,
   3932	    (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
   3933	     MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)) {
   3934
   3935		handle = buffer.phy_info[0].handle;
   3936		port_info = mptsas_find_portinfo_by_sas_address(ioc,
   3937		    buffer.phy_info[0].identify.sas_address);
   3938
   3939		if (port_info) {
   3940			/* refreshing handles */
   3941			for (i = 0; i < buffer.num_phys; i++) {
   3942				port_info->phy_info[i].handle = handle;
   3943				port_info->phy_info[i].identify.handle_parent =
   3944				    buffer.phy_info[0].identify.handle_parent;
   3945			}
   3946			mptsas_expander_refresh(ioc, port_info);
   3947			kfree(buffer.phy_info);
   3948			continue;
   3949		}
   3950
   3951		port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
   3952		if (!port_info) {
   3953			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   3954			"%s: exit at line=%d\n", ioc->name,
   3955			__func__, __LINE__));
   3956			return;
   3957		}
   3958		port_info->num_phys = buffer.num_phys;
   3959		port_info->phy_info = buffer.phy_info;
   3960		for (i = 0; i < port_info->num_phys; i++)
   3961			port_info->phy_info[i].portinfo = port_info;
   3962		mutex_lock(&ioc->sas_topology_mutex);
   3963		list_add_tail(&port_info->list, &ioc->sas_topology);
   3964		mutex_unlock(&ioc->sas_topology_mutex);
   3965		printk(MYIOC_s_INFO_FMT "add expander: num_phys %d, "
   3966		    "sas_addr (0x%llx)\n", ioc->name, port_info->num_phys,
   3967	    (unsigned long long)buffer.phy_info[0].identify.sas_address);
   3968		mptsas_expander_refresh(ioc, port_info);
   3969	}
   3970}
   3971
   3972static void
   3973mptsas_probe_devices(MPT_ADAPTER *ioc)
   3974{
   3975	u16 handle;
   3976	struct mptsas_devinfo sas_device;
   3977	struct mptsas_phyinfo *phy_info;
   3978
   3979	handle = 0xFFFF;
   3980	while (!(mptsas_sas_device_pg0(ioc, &sas_device,
   3981	    MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
   3982
   3983		handle = sas_device.handle;
   3984
   3985		if ((sas_device.device_info &
   3986		     (MPI_SAS_DEVICE_INFO_SSP_TARGET |
   3987		      MPI_SAS_DEVICE_INFO_STP_TARGET |
   3988		      MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0)
   3989			continue;
   3990
   3991		/* If there is no FW B_T mapping for this device then continue
   3992		 * */
   3993		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
   3994			|| !(sas_device.flags &
   3995			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
   3996			continue;
   3997
   3998		phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
   3999		if (!phy_info)
   4000			continue;
   4001
   4002		if (mptsas_get_rphy(phy_info))
   4003			continue;
   4004
   4005		mptsas_add_end_device(ioc, phy_info);
   4006	}
   4007}
   4008
   4009/**
   4010 *	mptsas_scan_sas_topology - scans new SAS topology
   4011 *	  (part of probe or rescan)
   4012 *	@ioc: Pointer to MPT_ADAPTER structure
   4013 *
   4014 **/
   4015static void
   4016mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
   4017{
   4018	struct scsi_device *sdev;
   4019	int i;
   4020
   4021	mptsas_probe_hba_phys(ioc);
   4022	mptsas_probe_expanders(ioc);
   4023	mptsas_probe_devices(ioc);
   4024
   4025	/*
   4026	  Reporting RAID volumes.
   4027	*/
   4028	if (!ioc->ir_firmware || !ioc->raid_data.pIocPg2 ||
   4029	    !ioc->raid_data.pIocPg2->NumActiveVolumes)
   4030		return;
   4031	for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
   4032		sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
   4033		    ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
   4034		if (sdev) {
   4035			scsi_device_put(sdev);
   4036			continue;
   4037		}
   4038		printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
   4039		    "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
   4040		    ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID);
   4041		scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
   4042		    ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
   4043	}
   4044}
   4045
   4046
   4047static void
   4048mptsas_handle_queue_full_event(struct fw_event_work *fw_event)
   4049{
   4050	MPT_ADAPTER *ioc;
   4051	EventDataQueueFull_t *qfull_data;
   4052	struct mptsas_device_info *sas_info;
   4053	struct scsi_device	*sdev;
   4054	int depth;
   4055	int id = -1;
   4056	int channel = -1;
   4057	int fw_id, fw_channel;
   4058	u16 current_depth;
   4059
   4060
   4061	ioc = fw_event->ioc;
   4062	qfull_data = (EventDataQueueFull_t *)fw_event->event_data;
   4063	fw_id = qfull_data->TargetID;
   4064	fw_channel = qfull_data->Bus;
   4065	current_depth = le16_to_cpu(qfull_data->CurrentDepth);
   4066
   4067	/* if hidden raid component, look for the volume id */
   4068	mutex_lock(&ioc->sas_device_info_mutex);
   4069	if (mptscsih_is_phys_disk(ioc, fw_channel, fw_id)) {
   4070		list_for_each_entry(sas_info, &ioc->sas_device_info_list,
   4071		    list) {
   4072			if (sas_info->is_cached ||
   4073			    sas_info->is_logical_volume)
   4074				continue;
   4075			if (sas_info->is_hidden_raid_component &&
   4076			    (sas_info->fw.channel == fw_channel &&
   4077			    sas_info->fw.id == fw_id)) {
   4078				id = sas_info->volume_id;
   4079				channel = MPTSAS_RAID_CHANNEL;
   4080				goto out;
   4081			}
   4082		}
   4083	} else {
   4084		list_for_each_entry(sas_info, &ioc->sas_device_info_list,
   4085		    list) {
   4086			if (sas_info->is_cached ||
   4087			    sas_info->is_hidden_raid_component ||
   4088			    sas_info->is_logical_volume)
   4089				continue;
   4090			if (sas_info->fw.channel == fw_channel &&
   4091			    sas_info->fw.id == fw_id) {
   4092				id = sas_info->os.id;
   4093				channel = sas_info->os.channel;
   4094				goto out;
   4095			}
   4096		}
   4097
   4098	}
   4099
   4100 out:
   4101	mutex_unlock(&ioc->sas_device_info_mutex);
   4102
   4103	if (id != -1) {
   4104		shost_for_each_device(sdev, ioc->sh) {
   4105			if (sdev->id == id && sdev->channel == channel) {
   4106				if (current_depth > sdev->queue_depth) {
   4107					sdev_printk(KERN_INFO, sdev,
   4108					    "strange observation, the queue "
   4109					    "depth is (%d) meanwhile fw queue "
   4110					    "depth (%d)\n", sdev->queue_depth,
   4111					    current_depth);
   4112					continue;
   4113				}
   4114				depth = scsi_track_queue_full(sdev,
   4115					sdev->queue_depth - 1);
   4116				if (depth > 0)
   4117					sdev_printk(KERN_INFO, sdev,
   4118					"Queue depth reduced to (%d)\n",
   4119					   depth);
   4120				else if (depth < 0)
   4121					sdev_printk(KERN_INFO, sdev,
   4122					"Tagged Command Queueing is being "
   4123					"disabled\n");
   4124				else if (depth == 0)
   4125					sdev_printk(KERN_DEBUG, sdev,
   4126					"Queue depth not changed yet\n");
   4127			}
   4128		}
   4129	}
   4130
   4131	mptsas_free_fw_event(ioc, fw_event);
   4132}
   4133
   4134
   4135static struct mptsas_phyinfo *
   4136mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
   4137{
   4138	struct mptsas_portinfo *port_info;
   4139	struct mptsas_phyinfo *phy_info = NULL;
   4140	int i;
   4141
   4142	mutex_lock(&ioc->sas_topology_mutex);
   4143	list_for_each_entry(port_info, &ioc->sas_topology, list) {
   4144		for (i = 0; i < port_info->num_phys; i++) {
   4145			if (!mptsas_is_end_device(
   4146				&port_info->phy_info[i].attached))
   4147				continue;
   4148			if (port_info->phy_info[i].attached.sas_address
   4149			    != sas_address)
   4150				continue;
   4151			phy_info = &port_info->phy_info[i];
   4152			break;
   4153		}
   4154	}
   4155	mutex_unlock(&ioc->sas_topology_mutex);
   4156	return phy_info;
   4157}
   4158
   4159/**
   4160 *	mptsas_find_phyinfo_by_phys_disk_num - find phyinfo for the
   4161 *	  specified @phys_disk_num
   4162 *	@ioc: Pointer to MPT_ADAPTER structure
   4163 *	@phys_disk_num: (hot plug) physical disk number (for RAID support)
   4164 *	@channel: channel number
   4165 *	@id: Logical Target ID
   4166 *
   4167 **/
   4168static struct mptsas_phyinfo *
   4169mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
   4170	u8 channel, u8 id)
   4171{
   4172	struct mptsas_phyinfo *phy_info = NULL;
   4173	struct mptsas_portinfo *port_info;
   4174	RaidPhysDiskPage1_t *phys_disk = NULL;
   4175	int num_paths;
   4176	u64 sas_address = 0;
   4177	int i;
   4178
   4179	phy_info = NULL;
   4180	if (!ioc->raid_data.pIocPg3)
   4181		return NULL;
   4182	/* dual port support */
   4183	num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num);
   4184	if (!num_paths)
   4185		goto out;
   4186	phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
   4187	   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
   4188	if (!phys_disk)
   4189		goto out;
   4190	mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk);
   4191	for (i = 0; i < num_paths; i++) {
   4192		if ((phys_disk->Path[i].Flags & 1) != 0)
   4193			/* entry no longer valid */
   4194			continue;
   4195		if ((id == phys_disk->Path[i].PhysDiskID) &&
   4196		    (channel == phys_disk->Path[i].PhysDiskBus)) {
   4197			memcpy(&sas_address, &phys_disk->Path[i].WWID,
   4198				sizeof(u64));
   4199			phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
   4200					sas_address);
   4201			goto out;
   4202		}
   4203	}
   4204
   4205 out:
   4206	kfree(phys_disk);
   4207	if (phy_info)
   4208		return phy_info;
   4209
   4210	/*
   4211	 * Extra code to handle RAID0 case, where the sas_address is not updated
   4212	 * in phys_disk_page_1 when hotswapped
   4213	 */
   4214	mutex_lock(&ioc->sas_topology_mutex);
   4215	list_for_each_entry(port_info, &ioc->sas_topology, list) {
   4216		for (i = 0; i < port_info->num_phys && !phy_info; i++) {
   4217			if (!mptsas_is_end_device(
   4218				&port_info->phy_info[i].attached))
   4219				continue;
   4220			if (port_info->phy_info[i].attached.phys_disk_num == ~0)
   4221				continue;
   4222			if ((port_info->phy_info[i].attached.phys_disk_num ==
   4223			    phys_disk_num) &&
   4224			    (port_info->phy_info[i].attached.id == id) &&
   4225			    (port_info->phy_info[i].attached.channel ==
   4226			     channel))
   4227				phy_info = &port_info->phy_info[i];
   4228		}
   4229	}
   4230	mutex_unlock(&ioc->sas_topology_mutex);
   4231	return phy_info;
   4232}
   4233
   4234static void
   4235mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
   4236{
   4237	int rc;
   4238
   4239	sdev->no_uld_attach = data ? 1 : 0;
   4240	rc = scsi_device_reprobe(sdev);
   4241}
   4242
   4243static void
   4244mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
   4245{
   4246	starget_for_each_device(starget, uld_attach ? (void *)1 : NULL,
   4247			mptsas_reprobe_lun);
   4248}
   4249
   4250static void
   4251mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
   4252{
   4253	CONFIGPARMS			cfg;
   4254	ConfigPageHeader_t		hdr;
   4255	dma_addr_t			dma_handle;
   4256	pRaidVolumePage0_t		buffer = NULL;
   4257	RaidPhysDiskPage0_t 		phys_disk;
   4258	int				i;
   4259	struct mptsas_phyinfo	*phy_info;
   4260	struct mptsas_devinfo		sas_device;
   4261
   4262	memset(&cfg, 0 , sizeof(CONFIGPARMS));
   4263	memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
   4264	hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
   4265	cfg.pageAddr = (channel << 8) + id;
   4266	cfg.cfghdr.hdr = &hdr;
   4267	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
   4268	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
   4269
   4270	if (mpt_config(ioc, &cfg) != 0)
   4271		goto out;
   4272
   4273	if (!hdr.PageLength)
   4274		goto out;
   4275
   4276	buffer = dma_alloc_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
   4277				    &dma_handle, GFP_KERNEL);
   4278
   4279	if (!buffer)
   4280		goto out;
   4281
   4282	cfg.physAddr = dma_handle;
   4283	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
   4284
   4285	if (mpt_config(ioc, &cfg) != 0)
   4286		goto out;
   4287
   4288	if (!(buffer->VolumeStatus.Flags &
   4289	    MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
   4290		goto out;
   4291
   4292	if (!buffer->NumPhysDisks)
   4293		goto out;
   4294
   4295	for (i = 0; i < buffer->NumPhysDisks; i++) {
   4296
   4297		if (mpt_raid_phys_disk_pg0(ioc,
   4298		    buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
   4299			continue;
   4300
   4301		if (mptsas_sas_device_pg0(ioc, &sas_device,
   4302		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
   4303		     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
   4304			(phys_disk.PhysDiskBus << 8) +
   4305			phys_disk.PhysDiskID))
   4306			continue;
   4307
   4308		/* If there is no FW B_T mapping for this device then continue
   4309		 * */
   4310		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
   4311			|| !(sas_device.flags &
   4312			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
   4313			continue;
   4314
   4315
   4316		phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
   4317		    sas_device.sas_address);
   4318		mptsas_add_end_device(ioc, phy_info);
   4319	}
   4320
   4321 out:
   4322	if (buffer)
   4323		dma_free_coherent(&ioc->pcidev->dev, hdr.PageLength * 4,
   4324				  buffer, dma_handle);
   4325}
   4326/*
   4327 * Work queue thread to handle SAS hotplug events
   4328 */
   4329static void
   4330mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event,
   4331    struct mptsas_hotplug_event *hot_plug_info)
   4332{
   4333	struct mptsas_phyinfo *phy_info;
   4334	struct scsi_target * starget;
   4335	struct mptsas_devinfo sas_device;
   4336	VirtTarget *vtarget;
   4337	int i;
   4338	struct mptsas_portinfo *port_info;
   4339
   4340	switch (hot_plug_info->event_type) {
   4341
   4342	case MPTSAS_ADD_PHYSDISK:
   4343
   4344		if (!ioc->raid_data.pIocPg2)
   4345			break;
   4346
   4347		for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
   4348			if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID ==
   4349			    hot_plug_info->id) {
   4350				printk(MYIOC_s_WARN_FMT "firmware bug: unable "
   4351				    "to add hidden disk - target_id matches "
   4352				    "volume_id\n", ioc->name);
   4353				mptsas_free_fw_event(ioc, fw_event);
   4354				return;
   4355			}
   4356		}
   4357		mpt_findImVolumes(ioc);
   4358		fallthrough;
   4359
   4360	case MPTSAS_ADD_DEVICE:
   4361		memset(&sas_device, 0, sizeof(struct mptsas_devinfo));
   4362		mptsas_sas_device_pg0(ioc, &sas_device,
   4363		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
   4364		    MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
   4365		    (hot_plug_info->channel << 8) +
   4366		    hot_plug_info->id);
   4367
   4368		/* If there is no FW B_T mapping for this device then break
   4369		 * */
   4370		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
   4371			|| !(sas_device.flags &
   4372			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
   4373			break;
   4374
   4375		if (!sas_device.handle)
   4376			return;
   4377
   4378		phy_info = mptsas_refreshing_device_handles(ioc, &sas_device);
   4379		/* Device hot plug */
   4380		if (!phy_info) {
   4381			devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   4382				"%s %d HOT PLUG: "
   4383				"parent handle of device %x\n", ioc->name,
   4384				__func__, __LINE__, sas_device.handle_parent));
   4385			port_info = mptsas_find_portinfo_by_handle(ioc,
   4386				sas_device.handle_parent);
   4387
   4388			if (port_info == ioc->hba_port_info)
   4389				mptsas_probe_hba_phys(ioc);
   4390			else if (port_info)
   4391				mptsas_expander_refresh(ioc, port_info);
   4392			else {
   4393				dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   4394					"%s %d port info is NULL\n",
   4395					ioc->name, __func__, __LINE__));
   4396				break;
   4397			}
   4398			phy_info = mptsas_refreshing_device_handles
   4399				(ioc, &sas_device);
   4400		}
   4401
   4402		if (!phy_info) {
   4403			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   4404				"%s %d phy info is NULL\n",
   4405				ioc->name, __func__, __LINE__));
   4406			break;
   4407		}
   4408
   4409		if (mptsas_get_rphy(phy_info))
   4410			break;
   4411
   4412		mptsas_add_end_device(ioc, phy_info);
   4413		break;
   4414
   4415	case MPTSAS_DEL_DEVICE:
   4416		phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
   4417		    hot_plug_info->sas_address);
   4418		mptsas_del_end_device(ioc, phy_info);
   4419		break;
   4420
   4421	case MPTSAS_DEL_PHYSDISK:
   4422
   4423		mpt_findImVolumes(ioc);
   4424
   4425		phy_info = mptsas_find_phyinfo_by_phys_disk_num(
   4426				ioc, hot_plug_info->phys_disk_num,
   4427				hot_plug_info->channel,
   4428				hot_plug_info->id);
   4429		mptsas_del_end_device(ioc, phy_info);
   4430		break;
   4431
   4432	case MPTSAS_ADD_PHYSDISK_REPROBE:
   4433
   4434		if (mptsas_sas_device_pg0(ioc, &sas_device,
   4435		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
   4436		     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
   4437		    (hot_plug_info->channel << 8) + hot_plug_info->id)) {
   4438			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   4439			"%s: fw_id=%d exit at line=%d\n", ioc->name,
   4440				 __func__, hot_plug_info->id, __LINE__));
   4441			break;
   4442		}
   4443
   4444		/* If there is no FW B_T mapping for this device then break
   4445		 * */
   4446		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
   4447			|| !(sas_device.flags &
   4448			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
   4449			break;
   4450
   4451		phy_info = mptsas_find_phyinfo_by_sas_address(
   4452		    ioc, sas_device.sas_address);
   4453
   4454		if (!phy_info) {
   4455			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   4456				"%s: fw_id=%d exit at line=%d\n", ioc->name,
   4457				 __func__, hot_plug_info->id, __LINE__));
   4458			break;
   4459		}
   4460
   4461		starget = mptsas_get_starget(phy_info);
   4462		if (!starget) {
   4463			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   4464				"%s: fw_id=%d exit at line=%d\n", ioc->name,
   4465				 __func__, hot_plug_info->id, __LINE__));
   4466			break;
   4467		}
   4468
   4469		vtarget = starget->hostdata;
   4470		if (!vtarget) {
   4471			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   4472				"%s: fw_id=%d exit at line=%d\n", ioc->name,
   4473				 __func__, hot_plug_info->id, __LINE__));
   4474			break;
   4475		}
   4476
   4477		mpt_findImVolumes(ioc);
   4478
   4479		starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Hidding: "
   4480		    "fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
   4481		    ioc->name, hot_plug_info->channel, hot_plug_info->id,
   4482		    hot_plug_info->phys_disk_num, (unsigned long long)
   4483		    sas_device.sas_address);
   4484
   4485		vtarget->id = hot_plug_info->phys_disk_num;
   4486		vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
   4487		phy_info->attached.phys_disk_num = hot_plug_info->phys_disk_num;
   4488		mptsas_reprobe_target(starget, 1);
   4489		break;
   4490
   4491	case MPTSAS_DEL_PHYSDISK_REPROBE:
   4492
   4493		if (mptsas_sas_device_pg0(ioc, &sas_device,
   4494		    (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
   4495		     MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
   4496			(hot_plug_info->channel << 8) + hot_plug_info->id)) {
   4497				dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   4498				    "%s: fw_id=%d exit at line=%d\n",
   4499				    ioc->name, __func__,
   4500				    hot_plug_info->id, __LINE__));
   4501			break;
   4502		}
   4503
   4504		/* If there is no FW B_T mapping for this device then break
   4505		 * */
   4506		if (!(sas_device.flags & MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)
   4507			|| !(sas_device.flags &
   4508			MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED))
   4509			break;
   4510
   4511		phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
   4512				sas_device.sas_address);
   4513		if (!phy_info) {
   4514			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   4515			    "%s: fw_id=%d exit at line=%d\n", ioc->name,
   4516			 __func__, hot_plug_info->id, __LINE__));
   4517			break;
   4518		}
   4519
   4520		starget = mptsas_get_starget(phy_info);
   4521		if (!starget) {
   4522			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   4523			    "%s: fw_id=%d exit at line=%d\n", ioc->name,
   4524			 __func__, hot_plug_info->id, __LINE__));
   4525			break;
   4526		}
   4527
   4528		vtarget = starget->hostdata;
   4529		if (!vtarget) {
   4530			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   4531			    "%s: fw_id=%d exit at line=%d\n", ioc->name,
   4532			 __func__, hot_plug_info->id, __LINE__));
   4533			break;
   4534		}
   4535
   4536		if (!(vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)) {
   4537			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
   4538			    "%s: fw_id=%d exit at line=%d\n", ioc->name,
   4539			 __func__, hot_plug_info->id, __LINE__));
   4540			break;
   4541		}
   4542
   4543		mpt_findImVolumes(ioc);
   4544
   4545		starget_printk(KERN_INFO, starget, MYIOC_s_FMT "RAID Exposing:"
   4546		    " fw_channel=%d, fw_id=%d, physdsk %d, sas_addr 0x%llx\n",
   4547		    ioc->name, hot_plug_info->channel, hot_plug_info->id,
   4548		    hot_plug_info->phys_disk_num, (unsigned long long)
   4549		    sas_device.sas_address);
   4550
   4551		vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
   4552		vtarget->id = hot_plug_info->id;
   4553		phy_info->attached.phys_disk_num = ~0;
   4554		mptsas_reprobe_target(starget, 0);
   4555		mptsas_add_device_component_by_fw(ioc,
   4556		    hot_plug_info->channel, hot_plug_info->id);
   4557		break;
   4558
   4559	case MPTSAS_ADD_RAID:
   4560
   4561		mpt_findImVolumes(ioc);
   4562		printk(MYIOC_s_INFO_FMT "attaching raid volume, channel %d, "
   4563		    "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
   4564		    hot_plug_info->id);
   4565		scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
   4566		    hot_plug_info->id, 0);
   4567		break;
   4568
   4569	case MPTSAS_DEL_RAID:
   4570
   4571		mpt_findImVolumes(ioc);
   4572		printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
   4573		    "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL,
   4574		    hot_plug_info->id);
   4575		scsi_remove_device(hot_plug_info->sdev);
   4576		scsi_device_put(hot_plug_info->sdev);
   4577		break;
   4578
   4579	case MPTSAS_ADD_INACTIVE_VOLUME:
   4580
   4581		mpt_findImVolumes(ioc);
   4582		mptsas_adding_inactive_raid_components(ioc,
   4583		    hot_plug_info->channel, hot_plug_info->id);
   4584		break;
   4585
   4586	default:
   4587		break;
   4588	}
   4589
   4590	mptsas_free_fw_event(ioc, fw_event);
   4591}
   4592
   4593static void
   4594mptsas_send_sas_event(struct fw_event_work *fw_event)
   4595{
   4596	MPT_ADAPTER *ioc;
   4597	struct mptsas_hotplug_event hot_plug_info;
   4598	EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
   4599	u32 device_info;
   4600	u64 sas_address;
   4601
   4602	ioc = fw_event->ioc;
   4603	sas_event_data = (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
   4604	    fw_event->event_data;
   4605	device_info = le32_to_cpu(sas_event_data->DeviceInfo);
   4606
   4607	if ((device_info &
   4608		(MPI_SAS_DEVICE_INFO_SSP_TARGET |
   4609		MPI_SAS_DEVICE_INFO_STP_TARGET |
   4610		MPI_SAS_DEVICE_INFO_SATA_DEVICE)) == 0) {
   4611		mptsas_free_fw_event(ioc, fw_event);
   4612		return;
   4613	}
   4614
   4615	if (sas_event_data->ReasonCode ==
   4616		MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED) {
   4617		mptbase_sas_persist_operation(ioc,
   4618		MPI_SAS_OP_CLEAR_NOT_PRESENT);
   4619		mptsas_free_fw_event(ioc, fw_event);
   4620		return;
   4621	}
   4622
   4623	switch (sas_event_data->ReasonCode) {
   4624	case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
   4625	case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
   4626		memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
   4627		hot_plug_info.handle = le16_to_cpu(sas_event_data->DevHandle);
   4628		hot_plug_info.channel = sas_event_data->Bus;
   4629		hot_plug_info.id = sas_event_data->TargetID;
   4630		hot_plug_info.phy_id = sas_event_data->PhyNum;
   4631		memcpy(&sas_address, &sas_event_data->SASAddress,
   4632		    sizeof(u64));
   4633		hot_plug_info.sas_address = le64_to_cpu(sas_address);
   4634		hot_plug_info.device_info = device_info;
   4635		if (sas_event_data->ReasonCode &
   4636		    MPI_EVENT_SAS_DEV_STAT_RC_ADDED)
   4637			hot_plug_info.event_type = MPTSAS_ADD_DEVICE;
   4638		else
   4639			hot_plug_info.event_type = MPTSAS_DEL_DEVICE;
   4640		mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
   4641		break;
   4642
   4643	case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
   4644		mptbase_sas_persist_operation(ioc,
   4645		    MPI_SAS_OP_CLEAR_NOT_PRESENT);
   4646		mptsas_free_fw_event(ioc, fw_event);
   4647		break;
   4648
   4649	case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
   4650	/* TODO */
   4651	case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
   4652	/* TODO */
   4653	default:
   4654		mptsas_free_fw_event(ioc, fw_event);
   4655		break;
   4656	}
   4657}
   4658
   4659static void
   4660mptsas_send_raid_event(struct fw_event_work *fw_event)
   4661{
   4662	MPT_ADAPTER *ioc;
   4663	EVENT_DATA_RAID *raid_event_data;
   4664	struct mptsas_hotplug_event hot_plug_info;
   4665	int status;
   4666	int state;
   4667	struct scsi_device *sdev = NULL;
   4668	VirtDevice *vdevice = NULL;
   4669	RaidPhysDiskPage0_t phys_disk;
   4670
   4671	ioc = fw_event->ioc;
   4672	raid_event_data = (EVENT_DATA_RAID *)fw_event->event_data;
   4673	status = le32_to_cpu(raid_event_data->SettingsStatus);
   4674	state = (status >> 8) & 0xff;
   4675
   4676	memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
   4677	hot_plug_info.id = raid_event_data->VolumeID;
   4678	hot_plug_info.channel = raid_event_data->VolumeBus;
   4679	hot_plug_info.phys_disk_num = raid_event_data->PhysDiskNum;
   4680
   4681	if (raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_DELETED ||
   4682	    raid_event_data->ReasonCode == MPI_EVENT_RAID_RC_VOLUME_CREATED ||
   4683	    raid_event_data->ReasonCode ==
   4684	    MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED) {
   4685		sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
   4686		    hot_plug_info.id, 0);
   4687		hot_plug_info.sdev = sdev;
   4688		if (sdev)
   4689			vdevice = sdev->hostdata;
   4690	}
   4691
   4692	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
   4693	    "ReasonCode=%02x\n", ioc->name, __func__,
   4694	    raid_event_data->ReasonCode));
   4695
   4696	switch (raid_event_data->ReasonCode) {
   4697	case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
   4698		hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK_REPROBE;
   4699		break;
   4700	case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
   4701		hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK_REPROBE;
   4702		break;
   4703	case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
   4704		switch (state) {
   4705		case MPI_PD_STATE_ONLINE:
   4706		case MPI_PD_STATE_NOT_COMPATIBLE:
   4707			mpt_raid_phys_disk_pg0(ioc,
   4708			    raid_event_data->PhysDiskNum, &phys_disk);
   4709			hot_plug_info.id = phys_disk.PhysDiskID;
   4710			hot_plug_info.channel = phys_disk.PhysDiskBus;
   4711			hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
   4712			break;
   4713		case MPI_PD_STATE_FAILED:
   4714		case MPI_PD_STATE_MISSING:
   4715		case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
   4716		case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
   4717		case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
   4718			hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
   4719			break;
   4720		default:
   4721			break;
   4722		}
   4723		break;
   4724	case MPI_EVENT_RAID_RC_VOLUME_DELETED:
   4725		if (!sdev)
   4726			break;
   4727		vdevice->vtarget->deleted = 1; /* block IO */
   4728		hot_plug_info.event_type = MPTSAS_DEL_RAID;
   4729		break;
   4730	case MPI_EVENT_RAID_RC_VOLUME_CREATED:
   4731		if (sdev) {
   4732			scsi_device_put(sdev);
   4733			break;
   4734		}
   4735		hot_plug_info.event_type = MPTSAS_ADD_RAID;
   4736		break;
   4737	case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
   4738		if (!(status & MPI_RAIDVOL0_STATUS_FLAG_ENABLED)) {
   4739			if (!sdev)
   4740				break;
   4741			vdevice->vtarget->deleted = 1; /* block IO */
   4742			hot_plug_info.event_type = MPTSAS_DEL_RAID;
   4743			break;
   4744		}
   4745		switch (state) {
   4746		case MPI_RAIDVOL0_STATUS_STATE_FAILED:
   4747		case MPI_RAIDVOL0_STATUS_STATE_MISSING:
   4748			if (!sdev)
   4749				break;
   4750			vdevice->vtarget->deleted = 1; /* block IO */
   4751			hot_plug_info.event_type = MPTSAS_DEL_RAID;
   4752			break;
   4753		case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
   4754		case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
   4755			if (sdev) {
   4756				scsi_device_put(sdev);
   4757				break;
   4758			}
   4759			hot_plug_info.event_type = MPTSAS_ADD_RAID;
   4760			break;
   4761		default:
   4762			break;
   4763		}
   4764		break;
   4765	default:
   4766		break;
   4767	}
   4768
   4769	if (hot_plug_info.event_type != MPTSAS_IGNORE_EVENT)
   4770		mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
   4771	else
   4772		mptsas_free_fw_event(ioc, fw_event);
   4773}
   4774
   4775/**
   4776 *	mptsas_issue_tm - send mptsas internal tm request
   4777 *	@ioc: Pointer to MPT_ADAPTER structure
   4778 *	@type: Task Management type
   4779 *	@channel: channel number for task management
   4780 *	@id: Logical Target ID for reset (if appropriate)
   4781 *	@lun: Logical unit for reset (if appropriate)
   4782 *	@task_context: Context for the task to be aborted
   4783 *	@timeout: timeout for task management control
   4784 *	@issue_reset: set to 1 on return if reset is needed, else 0
   4785 *
   4786 *	Return: 0 on success or -1 on failure.
   4787 *
   4788 */
   4789static int
   4790mptsas_issue_tm(MPT_ADAPTER *ioc, u8 type, u8 channel, u8 id, u64 lun,
   4791	int task_context, ulong timeout, u8 *issue_reset)
   4792{
   4793	MPT_FRAME_HDR	*mf;
   4794	SCSITaskMgmt_t	*pScsiTm;
   4795	int		 retval;
   4796	unsigned long	 timeleft;
   4797
   4798	*issue_reset = 0;
   4799	mf = mpt_get_msg_frame(mptsasDeviceResetCtx, ioc);
   4800	if (mf == NULL) {
   4801		retval = -1; /* return failure */
   4802		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "TaskMgmt request: no "
   4803		    "msg frames!!\n", ioc->name));
   4804		goto out;
   4805	}
   4806
   4807	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request: mr = %p, "
   4808	    "task_type = 0x%02X,\n\t timeout = %ld, fw_channel = %d, "
   4809	    "fw_id = %d, lun = %lld,\n\t task_context = 0x%x\n", ioc->name, mf,
   4810	     type, timeout, channel, id, (unsigned long long)lun,
   4811	     task_context));
   4812
   4813	pScsiTm = (SCSITaskMgmt_t *) mf;
   4814	memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
   4815	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
   4816	pScsiTm->TaskType = type;
   4817	pScsiTm->MsgFlags = 0;
   4818	pScsiTm->TargetID = id;
   4819	pScsiTm->Bus = channel;
   4820	pScsiTm->ChainOffset = 0;
   4821	pScsiTm->Reserved = 0;
   4822	pScsiTm->Reserved1 = 0;
   4823	pScsiTm->TaskMsgContext = task_context;
   4824	int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
   4825
   4826	INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
   4827	CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
   4828	retval = 0;
   4829	mpt_put_msg_frame_hi_pri(mptsasDeviceResetCtx, ioc, mf);
   4830
   4831	/* Now wait for the command to complete */
   4832	timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
   4833	    timeout*HZ);
   4834	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
   4835		retval = -1; /* return failure */
   4836		dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
   4837		    "TaskMgmt request: TIMED OUT!(mr=%p)\n", ioc->name, mf));
   4838		mpt_free_msg_frame(ioc, mf);
   4839		if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
   4840			goto out;
   4841		*issue_reset = 1;
   4842		goto out;
   4843	}
   4844
   4845	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
   4846		retval = -1; /* return failure */
   4847		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   4848		    "TaskMgmt request: failed with no reply\n", ioc->name));
   4849		goto out;
   4850	}
   4851
   4852 out:
   4853	CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
   4854	return retval;
   4855}
   4856
   4857/**
   4858 *	mptsas_broadcast_primitive_work - Handle broadcast primitives
   4859 *	@fw_event: work queue payload containing info describing the event
   4860 *
   4861 *	This will be handled in workqueue context.
   4862 */
   4863static void
   4864mptsas_broadcast_primitive_work(struct fw_event_work *fw_event)
   4865{
   4866	MPT_ADAPTER *ioc = fw_event->ioc;
   4867	MPT_FRAME_HDR	*mf;
   4868	VirtDevice	*vdevice;
   4869	int			ii;
   4870	struct scsi_cmnd	*sc;
   4871	SCSITaskMgmtReply_t	*pScsiTmReply;
   4872	u8			issue_reset;
   4873	int			task_context;
   4874	u8			channel, id;
   4875	int			 lun;
   4876	u32			 termination_count;
   4877	u32			 query_count;
   4878
   4879	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   4880	    "%s - enter\n", ioc->name, __func__));
   4881
   4882	mutex_lock(&ioc->taskmgmt_cmds.mutex);
   4883	if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
   4884		mutex_unlock(&ioc->taskmgmt_cmds.mutex);
   4885		mptsas_requeue_fw_event(ioc, fw_event, 1000);
   4886		return;
   4887	}
   4888
   4889	issue_reset = 0;
   4890	termination_count = 0;
   4891	query_count = 0;
   4892	mpt_findImVolumes(ioc);
   4893	pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
   4894
   4895	for (ii = 0; ii < ioc->req_depth; ii++) {
   4896		if (ioc->fw_events_off)
   4897			goto out;
   4898		sc = mptscsih_get_scsi_lookup(ioc, ii);
   4899		if (!sc)
   4900			continue;
   4901		mf = MPT_INDEX_2_MFPTR(ioc, ii);
   4902		if (!mf)
   4903			continue;
   4904		task_context = mf->u.frame.hwhdr.msgctxu.MsgContext;
   4905		vdevice = sc->device->hostdata;
   4906		if (!vdevice || !vdevice->vtarget)
   4907			continue;
   4908		if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
   4909			continue; /* skip hidden raid components */
   4910		if (vdevice->vtarget->raidVolume)
   4911			continue; /* skip hidden raid components */
   4912		channel = vdevice->vtarget->channel;
   4913		id = vdevice->vtarget->id;
   4914		lun = vdevice->lun;
   4915		if (mptsas_issue_tm(ioc, MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK,
   4916		    channel, id, (u64)lun, task_context, 30, &issue_reset))
   4917			goto out;
   4918		query_count++;
   4919		termination_count +=
   4920		    le32_to_cpu(pScsiTmReply->TerminationCount);
   4921		if ((pScsiTmReply->IOCStatus == MPI_IOCSTATUS_SUCCESS) &&
   4922		    (pScsiTmReply->ResponseCode ==
   4923		    MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED ||
   4924		    pScsiTmReply->ResponseCode ==
   4925		    MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC))
   4926			continue;
   4927		if (mptsas_issue_tm(ioc,
   4928		    MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET,
   4929		    channel, id, (u64)lun, 0, 30, &issue_reset))
   4930			goto out;
   4931		termination_count +=
   4932		    le32_to_cpu(pScsiTmReply->TerminationCount);
   4933	}
   4934
   4935 out:
   4936	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   4937	    "%s - exit, query_count = %d termination_count = %d\n",
   4938	    ioc->name, __func__, query_count, termination_count));
   4939
   4940	ioc->broadcast_aen_busy = 0;
   4941	mpt_clear_taskmgmt_in_progress_flag(ioc);
   4942	mutex_unlock(&ioc->taskmgmt_cmds.mutex);
   4943
   4944	if (issue_reset) {
   4945		printk(MYIOC_s_WARN_FMT
   4946		       "Issuing Reset from %s!! doorbell=0x%08x\n",
   4947		       ioc->name, __func__, mpt_GetIocState(ioc, 0));
   4948		mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
   4949	}
   4950	mptsas_free_fw_event(ioc, fw_event);
   4951}
   4952
   4953/*
   4954 * mptsas_send_ir2_event - handle exposing hidden disk when
   4955 * an inactive raid volume is added
   4956 *
   4957 * @ioc: Pointer to MPT_ADAPTER structure
   4958 * @ir2_data
   4959 *
   4960 */
   4961static void
   4962mptsas_send_ir2_event(struct fw_event_work *fw_event)
   4963{
   4964	MPT_ADAPTER	*ioc;
   4965	struct mptsas_hotplug_event hot_plug_info;
   4966	MPI_EVENT_DATA_IR2	*ir2_data;
   4967	u8 reasonCode;
   4968	RaidPhysDiskPage0_t phys_disk;
   4969
   4970	ioc = fw_event->ioc;
   4971	ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data;
   4972	reasonCode = ir2_data->ReasonCode;
   4973
   4974	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Entering %s: "
   4975	    "ReasonCode=%02x\n", ioc->name, __func__, reasonCode));
   4976
   4977	memset(&hot_plug_info, 0, sizeof(struct mptsas_hotplug_event));
   4978	hot_plug_info.id = ir2_data->TargetID;
   4979	hot_plug_info.channel = ir2_data->Bus;
   4980	switch (reasonCode) {
   4981	case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
   4982		hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME;
   4983		break;
   4984	case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
   4985		hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
   4986		hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK;
   4987		break;
   4988	case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
   4989		hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum;
   4990		mpt_raid_phys_disk_pg0(ioc,
   4991		    ir2_data->PhysDiskNum, &phys_disk);
   4992		hot_plug_info.id = phys_disk.PhysDiskID;
   4993		hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK;
   4994		break;
   4995	default:
   4996		mptsas_free_fw_event(ioc, fw_event);
   4997		return;
   4998	}
   4999	mptsas_hotplug_work(ioc, fw_event, &hot_plug_info);
   5000}
   5001
   5002static int
   5003mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
   5004{
   5005	u32 event = le32_to_cpu(reply->Event);
   5006	int event_data_sz;
   5007	struct fw_event_work *fw_event;
   5008	unsigned long delay;
   5009
   5010	if (ioc->bus_type != SAS)
   5011		return 0;
   5012
   5013	/* events turned off due to host reset or driver unloading */
   5014	if (ioc->fw_events_off)
   5015		return 0;
   5016
   5017	delay = msecs_to_jiffies(1);
   5018	switch (event) {
   5019	case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
   5020	{
   5021		EVENT_DATA_SAS_BROADCAST_PRIMITIVE *broadcast_event_data =
   5022		    (EVENT_DATA_SAS_BROADCAST_PRIMITIVE *)reply->Data;
   5023		if (broadcast_event_data->Primitive !=
   5024		    MPI_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
   5025			return 0;
   5026		if (ioc->broadcast_aen_busy)
   5027			return 0;
   5028		ioc->broadcast_aen_busy = 1;
   5029		break;
   5030	}
   5031	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
   5032	{
   5033		EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data =
   5034		    (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data;
   5035		u16	ioc_stat;
   5036		ioc_stat = le16_to_cpu(reply->IOCStatus);
   5037
   5038		if (sas_event_data->ReasonCode ==
   5039		    MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING) {
   5040			mptsas_target_reset_queue(ioc, sas_event_data);
   5041			return 0;
   5042		}
   5043		if (sas_event_data->ReasonCode ==
   5044			MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET &&
   5045			ioc->device_missing_delay &&
   5046			(ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)) {
   5047			VirtTarget *vtarget = NULL;
   5048			u8		id, channel;
   5049
   5050			id = sas_event_data->TargetID;
   5051			channel = sas_event_data->Bus;
   5052
   5053			vtarget = mptsas_find_vtarget(ioc, channel, id);
   5054			if (vtarget) {
   5055				devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   5056				    "LogInfo (0x%x) available for "
   5057				   "INTERNAL_DEVICE_RESET"
   5058				   "fw_id %d fw_channel %d\n", ioc->name,
   5059				   le32_to_cpu(reply->IOCLogInfo),
   5060				   id, channel));
   5061				if (vtarget->raidVolume) {
   5062					devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   5063					"Skipping Raid Volume for inDMD\n",
   5064					ioc->name));
   5065				} else {
   5066					devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   5067					"Setting device flag inDMD\n",
   5068					ioc->name));
   5069					vtarget->inDMD = 1;
   5070				}
   5071
   5072			}
   5073
   5074		}
   5075
   5076		break;
   5077	}
   5078	case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
   5079	{
   5080		MpiEventDataSasExpanderStatusChange_t *expander_data =
   5081		    (MpiEventDataSasExpanderStatusChange_t *)reply->Data;
   5082
   5083		if (ioc->old_sas_discovery_protocal)
   5084			return 0;
   5085
   5086		if (expander_data->ReasonCode ==
   5087		    MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING &&
   5088		    ioc->device_missing_delay)
   5089			delay = HZ * ioc->device_missing_delay;
   5090		break;
   5091	}
   5092	case MPI_EVENT_SAS_DISCOVERY:
   5093	{
   5094		u32 discovery_status;
   5095		EventDataSasDiscovery_t *discovery_data =
   5096		    (EventDataSasDiscovery_t *)reply->Data;
   5097
   5098		discovery_status = le32_to_cpu(discovery_data->DiscoveryStatus);
   5099		ioc->sas_discovery_quiesce_io = discovery_status ? 1 : 0;
   5100		if (ioc->old_sas_discovery_protocal && !discovery_status)
   5101			mptsas_queue_rescan(ioc);
   5102		return 0;
   5103	}
   5104	case MPI_EVENT_INTEGRATED_RAID:
   5105	case MPI_EVENT_PERSISTENT_TABLE_FULL:
   5106	case MPI_EVENT_IR2:
   5107	case MPI_EVENT_SAS_PHY_LINK_STATUS:
   5108	case MPI_EVENT_QUEUE_FULL:
   5109		break;
   5110	default:
   5111		return 0;
   5112	}
   5113
   5114	event_data_sz = ((reply->MsgLength * 4) -
   5115	    offsetof(EventNotificationReply_t, Data));
   5116	fw_event = kzalloc(sizeof(*fw_event) + event_data_sz, GFP_ATOMIC);
   5117	if (!fw_event) {
   5118		printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name,
   5119		 __func__, __LINE__);
   5120		return 0;
   5121	}
   5122	memcpy(fw_event->event_data, reply->Data, event_data_sz);
   5123	fw_event->event = event;
   5124	fw_event->ioc = ioc;
   5125	mptsas_add_fw_event(ioc, fw_event, delay);
   5126	return 0;
   5127}
   5128
   5129/* Delete a volume when no longer listed in ioc pg2
   5130 */
   5131static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id)
   5132{
   5133	struct scsi_device *sdev;
   5134	int i;
   5135
   5136	sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0);
   5137	if (!sdev)
   5138		return;
   5139	if (!ioc->raid_data.pIocPg2)
   5140		goto out;
   5141	if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
   5142		goto out;
   5143	for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
   5144		if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id)
   5145			goto release_sdev;
   5146 out:
   5147	printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, "
   5148	    "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id);
   5149	scsi_remove_device(sdev);
   5150 release_sdev:
   5151	scsi_device_put(sdev);
   5152}
   5153
   5154static int
   5155mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
   5156{
   5157	struct Scsi_Host	*sh;
   5158	MPT_SCSI_HOST		*hd;
   5159	MPT_ADAPTER 		*ioc;
   5160	unsigned long		 flags;
   5161	int			 ii;
   5162	int			 numSGE = 0;
   5163	int			 scale;
   5164	int			 ioc_cap;
   5165	int			error=0;
   5166	int			r;
   5167
   5168	r = mpt_attach(pdev,id);
   5169	if (r)
   5170		return r;
   5171
   5172	ioc = pci_get_drvdata(pdev);
   5173	mptsas_fw_event_off(ioc);
   5174	ioc->DoneCtx = mptsasDoneCtx;
   5175	ioc->TaskCtx = mptsasTaskCtx;
   5176	ioc->InternalCtx = mptsasInternalCtx;
   5177	ioc->schedule_target_reset = &mptsas_schedule_target_reset;
   5178	ioc->schedule_dead_ioc_flush_running_cmds =
   5179				&mptscsih_flush_running_cmds;
   5180	/*  Added sanity check on readiness of the MPT adapter.
   5181	 */
   5182	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
   5183		printk(MYIOC_s_WARN_FMT
   5184		  "Skipping because it's not operational!\n",
   5185		  ioc->name);
   5186		error = -ENODEV;
   5187		goto out_mptsas_probe;
   5188	}
   5189
   5190	if (!ioc->active) {
   5191		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
   5192		  ioc->name);
   5193		error = -ENODEV;
   5194		goto out_mptsas_probe;
   5195	}
   5196
   5197	/*  Sanity check - ensure at least 1 port is INITIATOR capable
   5198	 */
   5199	ioc_cap = 0;
   5200	for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
   5201		if (ioc->pfacts[ii].ProtocolFlags &
   5202				MPI_PORTFACTS_PROTOCOL_INITIATOR)
   5203			ioc_cap++;
   5204	}
   5205
   5206	if (!ioc_cap) {
   5207		printk(MYIOC_s_WARN_FMT
   5208			"Skipping ioc=%p because SCSI Initiator mode "
   5209			"is NOT enabled!\n", ioc->name, ioc);
   5210		return 0;
   5211	}
   5212
   5213	sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
   5214	if (!sh) {
   5215		printk(MYIOC_s_WARN_FMT
   5216			"Unable to register controller with SCSI subsystem\n",
   5217			ioc->name);
   5218		error = -1;
   5219		goto out_mptsas_probe;
   5220        }
   5221
   5222	spin_lock_irqsave(&ioc->FreeQlock, flags);
   5223
   5224	/* Attach the SCSI Host to the IOC structure
   5225	 */
   5226	ioc->sh = sh;
   5227
   5228	sh->io_port = 0;
   5229	sh->n_io_port = 0;
   5230	sh->irq = 0;
   5231
   5232	/* set 16 byte cdb's */
   5233	sh->max_cmd_len = 16;
   5234	sh->can_queue = min_t(int, ioc->req_depth - 10, sh->can_queue);
   5235	sh->max_id = -1;
   5236	sh->max_lun = max_lun;
   5237	sh->transportt = mptsas_transport_template;
   5238
   5239	/* Required entry.
   5240	 */
   5241	sh->unique_id = ioc->id;
   5242
   5243	INIT_LIST_HEAD(&ioc->sas_topology);
   5244	mutex_init(&ioc->sas_topology_mutex);
   5245	mutex_init(&ioc->sas_discovery_mutex);
   5246	mutex_init(&ioc->sas_mgmt.mutex);
   5247	init_completion(&ioc->sas_mgmt.done);
   5248
   5249	/* Verify that we won't exceed the maximum
   5250	 * number of chain buffers
   5251	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
   5252	 * For 32bit SGE's:
   5253	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
   5254	 *               + (req_sz - 64)/sizeof(SGE)
   5255	 * A slightly different algorithm is required for
   5256	 * 64bit SGEs.
   5257	 */
   5258	scale = ioc->req_sz/ioc->SGE_size;
   5259	if (ioc->sg_addr_size == sizeof(u64)) {
   5260		numSGE = (scale - 1) *
   5261		  (ioc->facts.MaxChainDepth-1) + scale +
   5262		  (ioc->req_sz - 60) / ioc->SGE_size;
   5263	} else {
   5264		numSGE = 1 + (scale - 1) *
   5265		  (ioc->facts.MaxChainDepth-1) + scale +
   5266		  (ioc->req_sz - 64) / ioc->SGE_size;
   5267	}
   5268
   5269	if (numSGE < sh->sg_tablesize) {
   5270		/* Reset this value */
   5271		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   5272		  "Resetting sg_tablesize to %d from %d\n",
   5273		  ioc->name, numSGE, sh->sg_tablesize));
   5274		sh->sg_tablesize = numSGE;
   5275	}
   5276
   5277	if (mpt_loadtime_max_sectors) {
   5278		if (mpt_loadtime_max_sectors < 64 ||
   5279			mpt_loadtime_max_sectors > 8192) {
   5280			printk(MYIOC_s_INFO_FMT "Invalid value passed for"
   5281				"mpt_loadtime_max_sectors %d."
   5282				"Range from 64 to 8192\n", ioc->name,
   5283				mpt_loadtime_max_sectors);
   5284		}
   5285		mpt_loadtime_max_sectors &=  0xFFFFFFFE;
   5286		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   5287			"Resetting max sector to %d from %d\n",
   5288		  ioc->name, mpt_loadtime_max_sectors, sh->max_sectors));
   5289		sh->max_sectors = mpt_loadtime_max_sectors;
   5290	}
   5291
   5292	hd = shost_priv(sh);
   5293	hd->ioc = ioc;
   5294
   5295	/* SCSI needs scsi_cmnd lookup table!
   5296	 * (with size equal to req_depth*PtrSz!)
   5297	 */
   5298	ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
   5299	if (!ioc->ScsiLookup) {
   5300		error = -ENOMEM;
   5301		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
   5302		goto out_mptsas_probe;
   5303	}
   5304	spin_lock_init(&ioc->scsi_lookup_lock);
   5305
   5306	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
   5307		 ioc->name, ioc->ScsiLookup));
   5308
   5309	ioc->sas_data.ptClear = mpt_pt_clear;
   5310
   5311	hd->last_queue_full = 0;
   5312	INIT_LIST_HEAD(&hd->target_reset_list);
   5313	INIT_LIST_HEAD(&ioc->sas_device_info_list);
   5314	mutex_init(&ioc->sas_device_info_mutex);
   5315
   5316	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
   5317
   5318	if (ioc->sas_data.ptClear==1) {
   5319		mptbase_sas_persist_operation(
   5320		    ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
   5321	}
   5322
   5323	error = scsi_add_host(sh, &ioc->pcidev->dev);
   5324	if (error) {
   5325		dprintk(ioc, printk(MYIOC_s_ERR_FMT
   5326		  "scsi_add_host failed\n", ioc->name));
   5327		goto out_mptsas_probe;
   5328	}
   5329
   5330	/* older firmware doesn't support expander events */
   5331	if ((ioc->facts.HeaderVersion >> 8) < 0xE)
   5332		ioc->old_sas_discovery_protocal = 1;
   5333	mptsas_scan_sas_topology(ioc);
   5334	mptsas_fw_event_on(ioc);
   5335	return 0;
   5336
   5337 out_mptsas_probe:
   5338
   5339	mptscsih_remove(pdev);
   5340	return error;
   5341}
   5342
   5343static void
   5344mptsas_shutdown(struct pci_dev *pdev)
   5345{
   5346	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
   5347
   5348	mptsas_fw_event_off(ioc);
   5349	mptsas_cleanup_fw_event_q(ioc);
   5350}
   5351
   5352static void mptsas_remove(struct pci_dev *pdev)
   5353{
   5354	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
   5355	struct mptsas_portinfo *p, *n;
   5356	int i;
   5357
   5358	if (!ioc->sh) {
   5359		printk(MYIOC_s_INFO_FMT "IOC is in Target mode\n", ioc->name);
   5360		mpt_detach(pdev);
   5361		return;
   5362	}
   5363
   5364	mptsas_shutdown(pdev);
   5365
   5366	mptsas_del_device_components(ioc);
   5367
   5368	ioc->sas_discovery_ignore_events = 1;
   5369	sas_remove_host(ioc->sh);
   5370
   5371	mutex_lock(&ioc->sas_topology_mutex);
   5372	list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
   5373		list_del(&p->list);
   5374		for (i = 0 ; i < p->num_phys ; i++)
   5375			mptsas_port_delete(ioc, p->phy_info[i].port_details);
   5376
   5377		kfree(p->phy_info);
   5378		kfree(p);
   5379	}
   5380	mutex_unlock(&ioc->sas_topology_mutex);
   5381	ioc->hba_port_info = NULL;
   5382	mptscsih_remove(pdev);
   5383}
   5384
   5385static struct pci_device_id mptsas_pci_table[] = {
   5386	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064,
   5387		PCI_ANY_ID, PCI_ANY_ID },
   5388	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068,
   5389		PCI_ANY_ID, PCI_ANY_ID },
   5390	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1064E,
   5391		PCI_ANY_ID, PCI_ANY_ID },
   5392	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068E,
   5393		PCI_ANY_ID, PCI_ANY_ID },
   5394	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1078,
   5395		PCI_ANY_ID, PCI_ANY_ID },
   5396	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_SAS1068_820XELP,
   5397		PCI_ANY_ID, PCI_ANY_ID },
   5398	{0}	/* Terminating entry */
   5399};
   5400MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
   5401
   5402
   5403static struct pci_driver mptsas_driver = {
   5404	.name		= "mptsas",
   5405	.id_table	= mptsas_pci_table,
   5406	.probe		= mptsas_probe,
   5407	.remove		= mptsas_remove,
   5408	.shutdown	= mptsas_shutdown,
   5409#ifdef CONFIG_PM
   5410	.suspend	= mptscsih_suspend,
   5411	.resume		= mptscsih_resume,
   5412#endif
   5413};
   5414
   5415static int __init
   5416mptsas_init(void)
   5417{
   5418	int error;
   5419
   5420	show_mptmod_ver(my_NAME, my_VERSION);
   5421
   5422	mptsas_transport_template =
   5423	    sas_attach_transport(&mptsas_transport_functions);
   5424	if (!mptsas_transport_template)
   5425		return -ENODEV;
   5426
   5427	mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER,
   5428	    "mptscsih_io_done");
   5429	mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER,
   5430	    "mptscsih_taskmgmt_complete");
   5431	mptsasInternalCtx =
   5432		mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER,
   5433		    "mptscsih_scandv_complete");
   5434	mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER,
   5435	    "mptsas_mgmt_done");
   5436	mptsasDeviceResetCtx =
   5437		mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER,
   5438		    "mptsas_taskmgmt_complete");
   5439
   5440	mpt_event_register(mptsasDoneCtx, mptsas_event_process);
   5441	mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset);
   5442
   5443	error = pci_register_driver(&mptsas_driver);
   5444	if (error)
   5445		sas_release_transport(mptsas_transport_template);
   5446
   5447	return error;
   5448}
   5449
   5450static void __exit
   5451mptsas_exit(void)
   5452{
   5453	pci_unregister_driver(&mptsas_driver);
   5454	sas_release_transport(mptsas_transport_template);
   5455
   5456	mpt_reset_deregister(mptsasDoneCtx);
   5457	mpt_event_deregister(mptsasDoneCtx);
   5458
   5459	mpt_deregister(mptsasMgmtCtx);
   5460	mpt_deregister(mptsasInternalCtx);
   5461	mpt_deregister(mptsasTaskCtx);
   5462	mpt_deregister(mptsasDoneCtx);
   5463	mpt_deregister(mptsasDeviceResetCtx);
   5464}
   5465
   5466module_init(mptsas_init);
   5467module_exit(mptsas_exit);