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

mptfc.c (42615B)


      1/*
      2 *  linux/drivers/message/fusion/mptfc.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/*
     12    This program is free software; you can redistribute it and/or modify
     13    it under the terms of the GNU General Public License as published by
     14    the Free Software Foundation; version 2 of the License.
     15
     16    This program is distributed in the hope that it will be useful,
     17    but WITHOUT ANY WARRANTY; without even the implied warranty of
     18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19    GNU General Public License for more details.
     20
     21    NO WARRANTY
     22    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
     23    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
     24    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
     25    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
     26    solely responsible for determining the appropriateness of using and
     27    distributing the Program and assumes all risks associated with its
     28    exercise of rights under this Agreement, including but not limited to
     29    the risks and costs of program errors, damage to or loss of data,
     30    programs or equipment, and unavailability or interruption of operations.
     31
     32    DISCLAIMER OF LIABILITY
     33    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
     34    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     35    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
     36    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
     37    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
     38    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
     39    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
     40
     41    You should have received a copy of the GNU General Public License
     42    along with this program; if not, write to the Free Software
     43    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     44*/
     45/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
     46#include <linux/module.h>
     47#include <linux/kernel.h>
     48#include <linux/init.h>
     49#include <linux/errno.h>
     50#include <linux/kdev_t.h>
     51#include <linux/blkdev.h>
     52#include <linux/delay.h>	/* for mdelay */
     53#include <linux/interrupt.h>
     54#include <linux/reboot.h>	/* notifier code */
     55#include <linux/workqueue.h>
     56#include <linux/sort.h>
     57#include <linux/slab.h>
     58
     59#include <scsi/scsi.h>
     60#include <scsi/scsi_cmnd.h>
     61#include <scsi/scsi_device.h>
     62#include <scsi/scsi_host.h>
     63#include <scsi/scsi_tcq.h>
     64#include <scsi/scsi_transport_fc.h>
     65
     66#include "mptbase.h"
     67#include "mptscsih.h"
     68
     69/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
     70#define my_NAME		"Fusion MPT FC Host driver"
     71#define my_VERSION	MPT_LINUX_VERSION_COMMON
     72#define MYNAM		"mptfc"
     73
     74MODULE_AUTHOR(MODULEAUTHOR);
     75MODULE_DESCRIPTION(my_NAME);
     76MODULE_LICENSE("GPL");
     77MODULE_VERSION(my_VERSION);
     78
     79/* Command line args */
     80#define MPTFC_DEV_LOSS_TMO (60)
     81static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;	/* reasonable default */
     82module_param(mptfc_dev_loss_tmo, int, 0);
     83MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "
     84    				     " transport to wait for an rport to "
     85				     " return following a device loss event."
     86				     "  Default=60.");
     87
     88/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
     89#define MPTFC_MAX_LUN (16895)
     90static int max_lun = MPTFC_MAX_LUN;
     91module_param(max_lun, int, 0);
     92MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
     93
     94static u8	mptfcDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
     95static u8	mptfcTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
     96static u8	mptfcInternalCtx = MPT_MAX_PROTOCOL_DRIVERS;
     97
     98static int mptfc_target_alloc(struct scsi_target *starget);
     99static int mptfc_slave_alloc(struct scsi_device *sdev);
    100static int mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt);
    101static void mptfc_target_destroy(struct scsi_target *starget);
    102static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
    103static void mptfc_remove(struct pci_dev *pdev);
    104static int mptfc_abort(struct scsi_cmnd *SCpnt);
    105static int mptfc_dev_reset(struct scsi_cmnd *SCpnt);
    106static int mptfc_bus_reset(struct scsi_cmnd *SCpnt);
    107
    108static struct scsi_host_template mptfc_driver_template = {
    109	.module				= THIS_MODULE,
    110	.proc_name			= "mptfc",
    111	.show_info			= mptscsih_show_info,
    112	.name				= "MPT FC Host",
    113	.info				= mptscsih_info,
    114	.queuecommand			= mptfc_qcmd,
    115	.target_alloc			= mptfc_target_alloc,
    116	.slave_alloc			= mptfc_slave_alloc,
    117	.slave_configure		= mptscsih_slave_configure,
    118	.target_destroy			= mptfc_target_destroy,
    119	.slave_destroy			= mptscsih_slave_destroy,
    120	.change_queue_depth 		= mptscsih_change_queue_depth,
    121	.eh_timed_out			= fc_eh_timed_out,
    122	.eh_abort_handler		= mptfc_abort,
    123	.eh_device_reset_handler	= mptfc_dev_reset,
    124	.eh_bus_reset_handler		= mptfc_bus_reset,
    125	.eh_host_reset_handler		= mptscsih_host_reset,
    126	.bios_param			= mptscsih_bios_param,
    127	.can_queue			= MPT_FC_CAN_QUEUE,
    128	.this_id			= -1,
    129	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
    130	.max_sectors			= 8192,
    131	.cmd_per_lun			= 7,
    132	.shost_groups			= mptscsih_host_attr_groups,
    133};
    134
    135/****************************************************************************
    136 * Supported hardware
    137 */
    138
    139static struct pci_device_id mptfc_pci_table[] = {
    140	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC909,
    141		PCI_ANY_ID, PCI_ANY_ID },
    142	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919,
    143		PCI_ANY_ID, PCI_ANY_ID },
    144	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929,
    145		PCI_ANY_ID, PCI_ANY_ID },
    146	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919X,
    147		PCI_ANY_ID, PCI_ANY_ID },
    148	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929X,
    149		PCI_ANY_ID, PCI_ANY_ID },
    150	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC939X,
    151		PCI_ANY_ID, PCI_ANY_ID },
    152	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949X,
    153		PCI_ANY_ID, PCI_ANY_ID },
    154	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E,
    155		PCI_ANY_ID, PCI_ANY_ID },
    156	{ PCI_VENDOR_ID_BROCADE, MPI_MANUFACTPAGE_DEVICEID_FC949E,
    157		PCI_ANY_ID, PCI_ANY_ID },
    158	{0}	/* Terminating entry */
    159};
    160MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
    161
    162static struct scsi_transport_template *mptfc_transport_template = NULL;
    163
    164static struct fc_function_template mptfc_transport_functions = {
    165	.dd_fcrport_size = 8,
    166	.show_host_node_name = 1,
    167	.show_host_port_name = 1,
    168	.show_host_supported_classes = 1,
    169	.show_host_port_id = 1,
    170	.show_rport_supported_classes = 1,
    171	.show_starget_node_name = 1,
    172	.show_starget_port_name = 1,
    173	.show_starget_port_id = 1,
    174	.set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
    175	.show_rport_dev_loss_tmo = 1,
    176	.show_host_supported_speeds = 1,
    177	.show_host_maxframe_size = 1,
    178	.show_host_speed = 1,
    179	.show_host_fabric_name = 1,
    180	.show_host_port_type = 1,
    181	.show_host_port_state = 1,
    182	.show_host_symbolic_name = 1,
    183};
    184
    185static int
    186mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
    187			  int (*func)(struct scsi_cmnd *SCpnt),
    188			  const char *caller)
    189{
    190	MPT_SCSI_HOST		*hd;
    191	struct scsi_device	*sdev = SCpnt->device;
    192	struct Scsi_Host	*shost = sdev->host;
    193	struct fc_rport		*rport = starget_to_rport(scsi_target(sdev));
    194	unsigned long		flags;
    195	int			ready;
    196	MPT_ADAPTER 		*ioc;
    197	int			loops = 40;	/* seconds */
    198
    199	hd = shost_priv(SCpnt->device->host);
    200	ioc = hd->ioc;
    201	spin_lock_irqsave(shost->host_lock, flags);
    202	while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY
    203	 || (loops > 0 && ioc->active == 0)) {
    204		spin_unlock_irqrestore(shost->host_lock, flags);
    205		dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
    206			"mptfc_block_error_handler.%d: %d:%llu, port status is "
    207			"%x, active flag %d, deferring %s recovery.\n",
    208			ioc->name, ioc->sh->host_no,
    209			SCpnt->device->id, SCpnt->device->lun,
    210			ready, ioc->active, caller));
    211		msleep(1000);
    212		spin_lock_irqsave(shost->host_lock, flags);
    213		loops --;
    214	}
    215	spin_unlock_irqrestore(shost->host_lock, flags);
    216
    217	if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata
    218	 || ioc->active == 0) {
    219		dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
    220			"%s.%d: %d:%llu, failing recovery, "
    221			"port state %x, active %d, vdevice %p.\n", caller,
    222			ioc->name, ioc->sh->host_no,
    223			SCpnt->device->id, SCpnt->device->lun, ready,
    224			ioc->active, SCpnt->device->hostdata));
    225		return FAILED;
    226	}
    227	dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
    228		"%s.%d: %d:%llu, executing recovery.\n", caller,
    229		ioc->name, ioc->sh->host_no,
    230		SCpnt->device->id, SCpnt->device->lun));
    231	return (*func)(SCpnt);
    232}
    233
    234static int
    235mptfc_abort(struct scsi_cmnd *SCpnt)
    236{
    237	return
    238	    mptfc_block_error_handler(SCpnt, mptscsih_abort, __func__);
    239}
    240
    241static int
    242mptfc_dev_reset(struct scsi_cmnd *SCpnt)
    243{
    244	return
    245	    mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __func__);
    246}
    247
    248static int
    249mptfc_bus_reset(struct scsi_cmnd *SCpnt)
    250{
    251	return
    252	    mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __func__);
    253}
    254
    255static void
    256mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
    257{
    258	if (timeout > 0)
    259		rport->dev_loss_tmo = timeout;
    260	else
    261		rport->dev_loss_tmo = mptfc_dev_loss_tmo;
    262}
    263
    264static int
    265mptfc_FcDevPage0_cmp_func(const void *a, const void *b)
    266{
    267	FCDevicePage0_t **aa = (FCDevicePage0_t **)a;
    268	FCDevicePage0_t **bb = (FCDevicePage0_t **)b;
    269
    270	if ((*aa)->CurrentBus == (*bb)->CurrentBus) {
    271		if ((*aa)->CurrentTargetID == (*bb)->CurrentTargetID)
    272			return 0;
    273		if ((*aa)->CurrentTargetID < (*bb)->CurrentTargetID)
    274			return -1;
    275		return 1;
    276	}
    277	if ((*aa)->CurrentBus < (*bb)->CurrentBus)
    278		return -1;
    279	return 1;
    280}
    281
    282static int
    283mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
    284	void(*func)(MPT_ADAPTER *ioc,int channel, FCDevicePage0_t *arg))
    285{
    286	ConfigPageHeader_t	 hdr;
    287	CONFIGPARMS		 cfg;
    288	FCDevicePage0_t		*ppage0_alloc, *fc;
    289	dma_addr_t		 page0_dma;
    290	int			 data_sz;
    291	int			 ii;
    292
    293	FCDevicePage0_t		*p0_array=NULL, *p_p0;
    294	FCDevicePage0_t		**pp0_array=NULL, **p_pp0;
    295
    296	int			 rc = -ENOMEM;
    297	U32			 port_id = 0xffffff;
    298	int			 num_targ = 0;
    299	int			 max_bus = ioc->facts.MaxBuses;
    300	int			 max_targ;
    301
    302	max_targ = (ioc->facts.MaxDevices == 0) ? 256 : ioc->facts.MaxDevices;
    303
    304	data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
    305	p_p0 = p0_array =  kzalloc(data_sz, GFP_KERNEL);
    306	if (!p0_array)
    307		goto out;
    308
    309	data_sz = sizeof(FCDevicePage0_t *) * max_bus * max_targ;
    310	p_pp0 = pp0_array = kzalloc(data_sz, GFP_KERNEL);
    311	if (!pp0_array)
    312		goto out;
    313
    314	do {
    315		/* Get FC Device Page 0 header */
    316		hdr.PageVersion = 0;
    317		hdr.PageLength = 0;
    318		hdr.PageNumber = 0;
    319		hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;
    320		cfg.cfghdr.hdr = &hdr;
    321		cfg.physAddr = -1;
    322		cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
    323		cfg.dir = 0;
    324		cfg.pageAddr = port_id;
    325		cfg.timeout = 0;
    326
    327		if ((rc = mpt_config(ioc, &cfg)) != 0)
    328			break;
    329
    330		if (hdr.PageLength <= 0)
    331			break;
    332
    333		data_sz = hdr.PageLength * 4;
    334		ppage0_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
    335						  &page0_dma, GFP_KERNEL);
    336		rc = -ENOMEM;
    337		if (!ppage0_alloc)
    338			break;
    339
    340		cfg.physAddr = page0_dma;
    341		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
    342
    343		if ((rc = mpt_config(ioc, &cfg)) == 0) {
    344			ppage0_alloc->PortIdentifier =
    345				le32_to_cpu(ppage0_alloc->PortIdentifier);
    346
    347			ppage0_alloc->WWNN.Low =
    348				le32_to_cpu(ppage0_alloc->WWNN.Low);
    349
    350			ppage0_alloc->WWNN.High =
    351				le32_to_cpu(ppage0_alloc->WWNN.High);
    352
    353			ppage0_alloc->WWPN.Low =
    354				le32_to_cpu(ppage0_alloc->WWPN.Low);
    355
    356			ppage0_alloc->WWPN.High =
    357				le32_to_cpu(ppage0_alloc->WWPN.High);
    358
    359			ppage0_alloc->BBCredit =
    360				le16_to_cpu(ppage0_alloc->BBCredit);
    361
    362			ppage0_alloc->MaxRxFrameSize =
    363				le16_to_cpu(ppage0_alloc->MaxRxFrameSize);
    364
    365			port_id = ppage0_alloc->PortIdentifier;
    366			num_targ++;
    367			*p_p0 = *ppage0_alloc;	/* save data */
    368			*p_pp0++ = p_p0++;	/* save addr */
    369		}
    370		dma_free_coherent(&ioc->pcidev->dev, data_sz,
    371				  ppage0_alloc, page0_dma);
    372		if (rc != 0)
    373			break;
    374
    375	} while (port_id <= 0xff0000);
    376
    377	if (num_targ) {
    378		/* sort array */
    379		if (num_targ > 1)
    380			sort (pp0_array, num_targ, sizeof(FCDevicePage0_t *),
    381				mptfc_FcDevPage0_cmp_func, NULL);
    382		/* call caller's func for each targ */
    383		for (ii = 0; ii < num_targ;  ii++) {
    384			fc = *(pp0_array+ii);
    385			func(ioc, ioc_port, fc);
    386		}
    387	}
    388
    389 out:
    390	kfree(pp0_array);
    391	kfree(p0_array);
    392	return rc;
    393}
    394
    395static int
    396mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
    397{
    398	/* not currently usable */
    399	if (pg0->Flags & (MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID |
    400			  MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID))
    401		return -1;
    402
    403	if (!(pg0->Flags & MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID))
    404		return -1;
    405
    406	if (!(pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET))
    407		return -1;
    408
    409	/*
    410	 * board data structure already normalized to platform endianness
    411	 * shifted to avoid unaligned access on 64 bit architecture
    412	 */
    413	rid->node_name = ((u64)pg0->WWNN.High) << 32 | (u64)pg0->WWNN.Low;
    414	rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
    415	rid->port_id =   pg0->PortIdentifier;
    416	rid->roles = FC_RPORT_ROLE_UNKNOWN;
    417
    418	return 0;
    419}
    420
    421static void
    422mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
    423{
    424	struct fc_rport_identifiers rport_ids;
    425	struct fc_rport		*rport;
    426	struct mptfc_rport_info	*ri;
    427	int			new_ri = 1;
    428	u64			pn, nn;
    429	VirtTarget		*vtarget;
    430	u32			roles = FC_RPORT_ROLE_UNKNOWN;
    431
    432	if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
    433		return;
    434
    435	roles |= FC_RPORT_ROLE_FCP_TARGET;
    436	if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
    437		roles |= FC_RPORT_ROLE_FCP_INITIATOR;
    438
    439	/* scan list looking for a match */
    440	list_for_each_entry(ri, &ioc->fc_rports, list) {
    441		pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
    442		if (pn == rport_ids.port_name) {	/* match */
    443			list_move_tail(&ri->list, &ioc->fc_rports);
    444			new_ri = 0;
    445			break;
    446		}
    447	}
    448	if (new_ri) {	/* allocate one */
    449		ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
    450		if (!ri)
    451			return;
    452		list_add_tail(&ri->list, &ioc->fc_rports);
    453	}
    454
    455	ri->pg0 = *pg0;	/* add/update pg0 data */
    456	ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
    457
    458	/* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
    459	if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
    460		ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
    461		rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
    462		if (rport) {
    463			ri->rport = rport;
    464			if (new_ri) /* may have been reset by user */
    465				rport->dev_loss_tmo = mptfc_dev_loss_tmo;
    466			/*
    467			 * if already mapped, remap here.  If not mapped,
    468			 * target_alloc will allocate vtarget and map,
    469			 * slave_alloc will fill in vdevice from vtarget.
    470			 */
    471			if (ri->starget) {
    472				vtarget = ri->starget->hostdata;
    473				if (vtarget) {
    474					vtarget->id = pg0->CurrentTargetID;
    475					vtarget->channel = pg0->CurrentBus;
    476					vtarget->deleted = 0;
    477				}
    478			}
    479			*((struct mptfc_rport_info **)rport->dd_data) = ri;
    480			/* scan will be scheduled once rport becomes a target */
    481			fc_remote_port_rolechg(rport,roles);
    482
    483			pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
    484			nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
    485			dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
    486				"mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
    487				"rport tid %d, tmo %d\n",
    488					ioc->name,
    489					ioc->sh->host_no,
    490					pg0->PortIdentifier,
    491					(unsigned long long)nn,
    492					(unsigned long long)pn,
    493					pg0->CurrentTargetID,
    494					ri->rport->scsi_target_id,
    495					ri->rport->dev_loss_tmo));
    496		} else {
    497			list_del(&ri->list);
    498			kfree(ri);
    499			ri = NULL;
    500		}
    501	}
    502}
    503
    504/*
    505 *	OS entry point to allow for host driver to free allocated memory
    506 *	Called if no device present or device being unloaded
    507 */
    508static void
    509mptfc_target_destroy(struct scsi_target *starget)
    510{
    511	struct fc_rport		*rport;
    512	struct mptfc_rport_info *ri;
    513
    514	rport = starget_to_rport(starget);
    515	if (rport) {
    516		ri = *((struct mptfc_rport_info **)rport->dd_data);
    517		if (ri)	/* better be! */
    518			ri->starget = NULL;
    519	}
    520	kfree(starget->hostdata);
    521	starget->hostdata = NULL;
    522}
    523
    524/*
    525 *	OS entry point to allow host driver to alloc memory
    526 *	for each scsi target. Called once per device the bus scan.
    527 *	Return non-zero if allocation fails.
    528 */
    529static int
    530mptfc_target_alloc(struct scsi_target *starget)
    531{
    532	VirtTarget		*vtarget;
    533	struct fc_rport		*rport;
    534	struct mptfc_rport_info *ri;
    535	int			rc;
    536
    537	vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
    538	if (!vtarget)
    539		return -ENOMEM;
    540	starget->hostdata = vtarget;
    541
    542	rc = -ENODEV;
    543	rport = starget_to_rport(starget);
    544	if (rport) {
    545		ri = *((struct mptfc_rport_info **)rport->dd_data);
    546		if (ri) {	/* better be! */
    547			vtarget->id = ri->pg0.CurrentTargetID;
    548			vtarget->channel = ri->pg0.CurrentBus;
    549			ri->starget = starget;
    550			rc = 0;
    551		}
    552	}
    553	if (rc != 0) {
    554		kfree(vtarget);
    555		starget->hostdata = NULL;
    556	}
    557
    558	return rc;
    559}
    560/*
    561 *	mptfc_dump_lun_info
    562 *	@ioc
    563 *	@rport
    564 *	@sdev
    565 *
    566 */
    567static void
    568mptfc_dump_lun_info(MPT_ADAPTER *ioc, struct fc_rport *rport, struct scsi_device *sdev,
    569		VirtTarget *vtarget)
    570{
    571	u64 nn, pn;
    572	struct mptfc_rport_info *ri;
    573
    574	ri = *((struct mptfc_rport_info **)rport->dd_data);
    575	pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
    576	nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
    577	dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
    578		"mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
    579		"CurrentTargetID %d, %x %llx %llx\n",
    580		ioc->name,
    581		sdev->host->host_no,
    582		vtarget->num_luns,
    583		sdev->id, ri->pg0.CurrentTargetID,
    584		ri->pg0.PortIdentifier,
    585		(unsigned long long)pn,
    586		(unsigned long long)nn));
    587}
    588
    589
    590/*
    591 *	OS entry point to allow host driver to alloc memory
    592 *	for each scsi device. Called once per device the bus scan.
    593 *	Return non-zero if allocation fails.
    594 *	Init memory once per LUN.
    595 */
    596static int
    597mptfc_slave_alloc(struct scsi_device *sdev)
    598{
    599	MPT_SCSI_HOST		*hd;
    600	VirtTarget		*vtarget;
    601	VirtDevice		*vdevice;
    602	struct scsi_target	*starget;
    603	struct fc_rport		*rport;
    604	MPT_ADAPTER 		*ioc;
    605
    606	starget = scsi_target(sdev);
    607	rport = starget_to_rport(starget);
    608
    609	if (!rport || fc_remote_port_chkready(rport))
    610		return -ENXIO;
    611
    612	hd = shost_priv(sdev->host);
    613	ioc = hd->ioc;
    614
    615	vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
    616	if (!vdevice) {
    617		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
    618				ioc->name, sizeof(VirtDevice));
    619		return -ENOMEM;
    620	}
    621
    622
    623	sdev->hostdata = vdevice;
    624	vtarget = starget->hostdata;
    625
    626	if (vtarget->num_luns == 0) {
    627		vtarget->ioc_id = ioc->id;
    628		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
    629	}
    630
    631	vdevice->vtarget = vtarget;
    632	vdevice->lun = sdev->lun;
    633
    634	vtarget->num_luns++;
    635
    636
    637	mptfc_dump_lun_info(ioc, rport, sdev, vtarget);
    638
    639	return 0;
    640}
    641
    642static int
    643mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
    644{
    645	struct mptfc_rport_info	*ri;
    646	struct fc_rport	*rport = starget_to_rport(scsi_target(SCpnt->device));
    647	int		err;
    648	VirtDevice	*vdevice = SCpnt->device->hostdata;
    649
    650	if (!vdevice || !vdevice->vtarget) {
    651		SCpnt->result = DID_NO_CONNECT << 16;
    652		scsi_done(SCpnt);
    653		return 0;
    654	}
    655
    656	err = fc_remote_port_chkready(rport);
    657	if (unlikely(err)) {
    658		SCpnt->result = err;
    659		scsi_done(SCpnt);
    660		return 0;
    661	}
    662
    663	/* dd_data is null until finished adding target */
    664	ri = *((struct mptfc_rport_info **)rport->dd_data);
    665	if (unlikely(!ri)) {
    666		SCpnt->result = DID_IMM_RETRY << 16;
    667		scsi_done(SCpnt);
    668		return 0;
    669	}
    670
    671	return mptscsih_qcmd(SCpnt);
    672}
    673
    674/*
    675 *	mptfc_display_port_link_speed - displaying link speed
    676 *	@ioc: Pointer to MPT_ADAPTER structure
    677 *	@portnum: IOC Port number
    678 *	@pp0dest: port page0 data payload
    679 *
    680 */
    681static void
    682mptfc_display_port_link_speed(MPT_ADAPTER *ioc, int portnum, FCPortPage0_t *pp0dest)
    683{
    684	u8	old_speed, new_speed, state;
    685	char	*old, *new;
    686
    687	if (portnum >= 2)
    688		return;
    689
    690	old_speed = ioc->fc_link_speed[portnum];
    691	new_speed = pp0dest->CurrentSpeed;
    692	state = pp0dest->PortState;
    693
    694	if (state != MPI_FCPORTPAGE0_PORTSTATE_OFFLINE &&
    695	    new_speed != MPI_FCPORTPAGE0_CURRENT_SPEED_UNKNOWN) {
    696
    697		old = old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
    698		       old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
    699			old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
    700			 "Unknown";
    701		new = new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
    702		       new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
    703			new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
    704			 "Unknown";
    705		if (old_speed == 0)
    706			printk(MYIOC_s_NOTE_FMT
    707				"FC Link Established, Speed = %s\n",
    708				ioc->name, new);
    709		else if (old_speed != new_speed)
    710			printk(MYIOC_s_WARN_FMT
    711				"FC Link Speed Change, Old Speed = %s, New Speed = %s\n",
    712				ioc->name, old, new);
    713
    714		ioc->fc_link_speed[portnum] = new_speed;
    715	}
    716}
    717
    718/*
    719 *	mptfc_GetFcPortPage0 - Fetch FCPort config Page0.
    720 *	@ioc: Pointer to MPT_ADAPTER structure
    721 *	@portnum: IOC Port number
    722 *
    723 *	Return: 0 for success
    724 *	-ENOMEM if no memory available
    725 *		-EPERM if not allowed due to ISR context
    726 *		-EAGAIN if no msg frames currently available
    727 *		-EFAULT for non-successful reply or no reply (timeout)
    728 *		-EINVAL portnum arg out of range (hardwired to two elements)
    729 */
    730static int
    731mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
    732{
    733	ConfigPageHeader_t	 hdr;
    734	CONFIGPARMS		 cfg;
    735	FCPortPage0_t		*ppage0_alloc;
    736	FCPortPage0_t		*pp0dest;
    737	dma_addr_t		 page0_dma;
    738	int			 data_sz;
    739	int			 copy_sz;
    740	int			 rc;
    741	int			 count = 400;
    742
    743	if (portnum > 1)
    744		return -EINVAL;
    745
    746	/* Get FCPort Page 0 header */
    747	hdr.PageVersion = 0;
    748	hdr.PageLength = 0;
    749	hdr.PageNumber = 0;
    750	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
    751	cfg.cfghdr.hdr = &hdr;
    752	cfg.physAddr = -1;
    753	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
    754	cfg.dir = 0;
    755	cfg.pageAddr = portnum;
    756	cfg.timeout = 0;
    757
    758	if ((rc = mpt_config(ioc, &cfg)) != 0)
    759		return rc;
    760
    761	if (hdr.PageLength == 0)
    762		return 0;
    763
    764	data_sz = hdr.PageLength * 4;
    765	rc = -ENOMEM;
    766	ppage0_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
    767					  &page0_dma, GFP_KERNEL);
    768	if (ppage0_alloc) {
    769
    770 try_again:
    771		memset((u8 *)ppage0_alloc, 0, data_sz);
    772		cfg.physAddr = page0_dma;
    773		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
    774
    775		if ((rc = mpt_config(ioc, &cfg)) == 0) {
    776			/* save the data */
    777			pp0dest = &ioc->fc_port_page0[portnum];
    778			copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
    779			memcpy(pp0dest, ppage0_alloc, copy_sz);
    780
    781			/*
    782			 *	Normalize endianness of structure data,
    783			 *	by byte-swapping all > 1 byte fields!
    784			 */
    785			pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
    786			pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
    787			pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
    788			pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
    789			pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
    790			pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
    791			pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
    792			pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
    793			pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
    794			pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
    795			pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
    796			pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
    797			pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
    798			pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
    799			pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
    800			pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
    801
    802			/*
    803			 * if still doing discovery,
    804			 * hang loose a while until finished
    805			 */
    806			if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) ||
    807			    (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE &&
    808			     (pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK)
    809			      == MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) {
    810				if (count-- > 0) {
    811					msleep(100);
    812					goto try_again;
    813				}
    814				printk(MYIOC_s_INFO_FMT "Firmware discovery not"
    815							" complete.\n",
    816						ioc->name);
    817			}
    818			mptfc_display_port_link_speed(ioc, portnum, pp0dest);
    819		}
    820
    821		dma_free_coherent(&ioc->pcidev->dev, data_sz, ppage0_alloc,
    822				  page0_dma);
    823	}
    824
    825	return rc;
    826}
    827
    828static int
    829mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum)
    830{
    831	ConfigPageHeader_t	 hdr;
    832	CONFIGPARMS		 cfg;
    833	int			 rc;
    834
    835	if (portnum > 1)
    836		return -EINVAL;
    837
    838	if (!(ioc->fc_data.fc_port_page1[portnum].data))
    839		return -EINVAL;
    840
    841	/* get fcport page 1 header */
    842	hdr.PageVersion = 0;
    843	hdr.PageLength = 0;
    844	hdr.PageNumber = 1;
    845	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
    846	cfg.cfghdr.hdr = &hdr;
    847	cfg.physAddr = -1;
    848	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
    849	cfg.dir = 0;
    850	cfg.pageAddr = portnum;
    851	cfg.timeout = 0;
    852
    853	if ((rc = mpt_config(ioc, &cfg)) != 0)
    854		return rc;
    855
    856	if (hdr.PageLength == 0)
    857		return -ENODEV;
    858
    859	if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz)
    860		return -EINVAL;
    861
    862	cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma;
    863	cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
    864	cfg.dir = 1;
    865
    866	rc = mpt_config(ioc, &cfg);
    867
    868	return rc;
    869}
    870
    871static int
    872mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum)
    873{
    874	ConfigPageHeader_t	 hdr;
    875	CONFIGPARMS		 cfg;
    876	FCPortPage1_t		*page1_alloc;
    877	dma_addr_t		 page1_dma;
    878	int			 data_sz;
    879	int			 rc;
    880
    881	if (portnum > 1)
    882		return -EINVAL;
    883
    884	/* get fcport page 1 header */
    885	hdr.PageVersion = 0;
    886	hdr.PageLength = 0;
    887	hdr.PageNumber = 1;
    888	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
    889	cfg.cfghdr.hdr = &hdr;
    890	cfg.physAddr = -1;
    891	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
    892	cfg.dir = 0;
    893	cfg.pageAddr = portnum;
    894	cfg.timeout = 0;
    895
    896	if ((rc = mpt_config(ioc, &cfg)) != 0)
    897		return rc;
    898
    899	if (hdr.PageLength == 0)
    900		return -ENODEV;
    901
    902start_over:
    903
    904	if (ioc->fc_data.fc_port_page1[portnum].data == NULL) {
    905		data_sz = hdr.PageLength * 4;
    906		if (data_sz < sizeof(FCPortPage1_t))
    907			data_sz = sizeof(FCPortPage1_t);
    908
    909		page1_alloc = dma_alloc_coherent(&ioc->pcidev->dev, data_sz,
    910						 &page1_dma, GFP_KERNEL);
    911		if (!page1_alloc)
    912			return -ENOMEM;
    913	}
    914	else {
    915		page1_alloc = ioc->fc_data.fc_port_page1[portnum].data;
    916		page1_dma = ioc->fc_data.fc_port_page1[portnum].dma;
    917		data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz;
    918		if (hdr.PageLength * 4 > data_sz) {
    919			ioc->fc_data.fc_port_page1[portnum].data = NULL;
    920			dma_free_coherent(&ioc->pcidev->dev, data_sz,
    921					  page1_alloc, page1_dma);
    922			goto start_over;
    923		}
    924	}
    925
    926	cfg.physAddr = page1_dma;
    927	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
    928
    929	if ((rc = mpt_config(ioc, &cfg)) == 0) {
    930		ioc->fc_data.fc_port_page1[portnum].data = page1_alloc;
    931		ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz;
    932		ioc->fc_data.fc_port_page1[portnum].dma = page1_dma;
    933	}
    934	else {
    935		ioc->fc_data.fc_port_page1[portnum].data = NULL;
    936		dma_free_coherent(&ioc->pcidev->dev, data_sz, page1_alloc,
    937				  page1_dma);
    938	}
    939
    940	return rc;
    941}
    942
    943static void
    944mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
    945{
    946	int		ii;
    947	FCPortPage1_t	*pp1;
    948
    949	#define MPTFC_FW_DEVICE_TIMEOUT	(1)
    950	#define MPTFC_FW_IO_PEND_TIMEOUT (1)
    951	#define ON_FLAGS  (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY)
    952	#define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS)
    953
    954	for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
    955		if (mptfc_GetFcPortPage1(ioc, ii) != 0)
    956			continue;
    957		pp1 = ioc->fc_data.fc_port_page1[ii].data;
    958		if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT)
    959		 && (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT)
    960		 && ((pp1->Flags & ON_FLAGS) == ON_FLAGS)
    961		 && ((pp1->Flags & OFF_FLAGS) == 0))
    962			continue;
    963		pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT;
    964		pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT;
    965		pp1->Flags &= ~OFF_FLAGS;
    966		pp1->Flags |= ON_FLAGS;
    967		mptfc_WriteFcPortPage1(ioc, ii);
    968	}
    969}
    970
    971
    972static void
    973mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
    974{
    975	unsigned	class = 0;
    976	unsigned	cos = 0;
    977	unsigned	speed;
    978	unsigned	port_type;
    979	unsigned	port_state;
    980	FCPortPage0_t	*pp0;
    981	struct Scsi_Host *sh;
    982	char		*sn;
    983
    984	/* don't know what to do as only one scsi (fc) host was allocated */
    985	if (portnum != 0)
    986		return;
    987
    988	pp0 = &ioc->fc_port_page0[portnum];
    989	sh = ioc->sh;
    990
    991	sn = fc_host_symbolic_name(sh);
    992	snprintf(sn, FC_SYMBOLIC_NAME_SIZE, "%s %s%08xh",
    993	    ioc->prod_name,
    994	    MPT_FW_REV_MAGIC_ID_STRING,
    995	    ioc->facts.FWVersion.Word);
    996
    997	fc_host_tgtid_bind_type(sh) = FC_TGTID_BIND_BY_WWPN;
    998
    999	fc_host_maxframe_size(sh) = pp0->MaxFrameSize;
   1000
   1001	fc_host_node_name(sh) =
   1002	    	(u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
   1003
   1004	fc_host_port_name(sh) =
   1005	    	(u64)pp0->WWPN.High << 32 | (u64)pp0->WWPN.Low;
   1006
   1007	fc_host_port_id(sh) = pp0->PortIdentifier;
   1008
   1009	class = pp0->SupportedServiceClass;
   1010	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
   1011		cos |= FC_COS_CLASS1;
   1012	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
   1013		cos |= FC_COS_CLASS2;
   1014	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
   1015		cos |= FC_COS_CLASS3;
   1016	fc_host_supported_classes(sh) = cos;
   1017
   1018	if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT)
   1019		speed = FC_PORTSPEED_1GBIT;
   1020	else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT)
   1021		speed = FC_PORTSPEED_2GBIT;
   1022	else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT)
   1023		speed = FC_PORTSPEED_4GBIT;
   1024	else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT)
   1025		speed = FC_PORTSPEED_10GBIT;
   1026	else
   1027		speed = FC_PORTSPEED_UNKNOWN;
   1028	fc_host_speed(sh) = speed;
   1029
   1030	speed = 0;
   1031	if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED)
   1032		speed |= FC_PORTSPEED_1GBIT;
   1033	if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED)
   1034		speed |= FC_PORTSPEED_2GBIT;
   1035	if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED)
   1036		speed |= FC_PORTSPEED_4GBIT;
   1037	if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED)
   1038		speed |= FC_PORTSPEED_10GBIT;
   1039	fc_host_supported_speeds(sh) = speed;
   1040
   1041	port_state = FC_PORTSTATE_UNKNOWN;
   1042	if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE)
   1043		port_state = FC_PORTSTATE_ONLINE;
   1044	else if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_OFFLINE)
   1045		port_state = FC_PORTSTATE_LINKDOWN;
   1046	fc_host_port_state(sh) = port_state;
   1047
   1048	port_type = FC_PORTTYPE_UNKNOWN;
   1049	if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT)
   1050		port_type = FC_PORTTYPE_PTP;
   1051	else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP)
   1052		port_type = FC_PORTTYPE_LPORT;
   1053	else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP)
   1054		port_type = FC_PORTTYPE_NLPORT;
   1055	else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT)
   1056		port_type = FC_PORTTYPE_NPORT;
   1057	fc_host_port_type(sh) = port_type;
   1058
   1059	fc_host_fabric_name(sh) =
   1060	    (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID) ?
   1061		(u64) pp0->FabricWWNN.High << 32 | (u64) pp0->FabricWWPN.Low :
   1062		(u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
   1063
   1064}
   1065
   1066static void
   1067mptfc_link_status_change(struct work_struct *work)
   1068{
   1069	MPT_ADAPTER             *ioc =
   1070		container_of(work, MPT_ADAPTER, fc_rescan_work);
   1071	int ii;
   1072
   1073	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++)
   1074		(void) mptfc_GetFcPortPage0(ioc, ii);
   1075
   1076}
   1077
   1078static void
   1079mptfc_setup_reset(struct work_struct *work)
   1080{
   1081	MPT_ADAPTER		*ioc =
   1082		container_of(work, MPT_ADAPTER, fc_setup_reset_work);
   1083	u64			pn;
   1084	struct mptfc_rport_info *ri;
   1085	struct scsi_target      *starget;
   1086	VirtTarget              *vtarget;
   1087
   1088	/* reset about to happen, delete (block) all rports */
   1089	list_for_each_entry(ri, &ioc->fc_rports, list) {
   1090		if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
   1091			ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
   1092			fc_remote_port_delete(ri->rport);	/* won't sleep */
   1093			ri->rport = NULL;
   1094			starget = ri->starget;
   1095			if (starget) {
   1096				vtarget = starget->hostdata;
   1097				if (vtarget)
   1098					vtarget->deleted = 1;
   1099			}
   1100
   1101			pn = (u64)ri->pg0.WWPN.High << 32 |
   1102			     (u64)ri->pg0.WWPN.Low;
   1103			dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
   1104				"mptfc_setup_reset.%d: %llx deleted\n",
   1105				ioc->name,
   1106				ioc->sh->host_no,
   1107				(unsigned long long)pn));
   1108		}
   1109	}
   1110}
   1111
   1112static void
   1113mptfc_rescan_devices(struct work_struct *work)
   1114{
   1115	MPT_ADAPTER		*ioc =
   1116		container_of(work, MPT_ADAPTER, fc_rescan_work);
   1117	int			ii;
   1118	u64			pn;
   1119	struct mptfc_rport_info *ri;
   1120	struct scsi_target      *starget;
   1121	VirtTarget              *vtarget;
   1122
   1123	/* start by tagging all ports as missing */
   1124	list_for_each_entry(ri, &ioc->fc_rports, list) {
   1125		if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
   1126			ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
   1127		}
   1128	}
   1129
   1130	/*
   1131	 * now rescan devices known to adapter,
   1132	 * will reregister existing rports
   1133	 */
   1134	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
   1135		(void) mptfc_GetFcPortPage0(ioc, ii);
   1136		mptfc_init_host_attr(ioc, ii);	/* refresh */
   1137		mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
   1138	}
   1139
   1140	/* delete devices still missing */
   1141	list_for_each_entry(ri, &ioc->fc_rports, list) {
   1142		/* if newly missing, delete it */
   1143		if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
   1144
   1145			ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
   1146				       MPT_RPORT_INFO_FLAGS_MISSING);
   1147			fc_remote_port_delete(ri->rport);	/* won't sleep */
   1148			ri->rport = NULL;
   1149			starget = ri->starget;
   1150			if (starget) {
   1151				vtarget = starget->hostdata;
   1152				if (vtarget)
   1153					vtarget->deleted = 1;
   1154			}
   1155
   1156			pn = (u64)ri->pg0.WWPN.High << 32 |
   1157			     (u64)ri->pg0.WWPN.Low;
   1158			dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
   1159				"mptfc_rescan.%d: %llx deleted\n",
   1160				ioc->name,
   1161				ioc->sh->host_no,
   1162				(unsigned long long)pn));
   1163		}
   1164	}
   1165}
   1166
   1167static int
   1168mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
   1169{
   1170	struct Scsi_Host	*sh;
   1171	MPT_SCSI_HOST		*hd;
   1172	MPT_ADAPTER 		*ioc;
   1173	unsigned long		 flags;
   1174	int			 ii;
   1175	int			 numSGE = 0;
   1176	int			 scale;
   1177	int			 ioc_cap;
   1178	int			error=0;
   1179	int			r;
   1180
   1181	if ((r = mpt_attach(pdev,id)) != 0)
   1182		return r;
   1183
   1184	ioc = pci_get_drvdata(pdev);
   1185	ioc->DoneCtx = mptfcDoneCtx;
   1186	ioc->TaskCtx = mptfcTaskCtx;
   1187	ioc->InternalCtx = mptfcInternalCtx;
   1188
   1189	/*  Added sanity check on readiness of the MPT adapter.
   1190	 */
   1191	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
   1192		printk(MYIOC_s_WARN_FMT
   1193		  "Skipping because it's not operational!\n",
   1194		  ioc->name);
   1195		error = -ENODEV;
   1196		goto out_mptfc_probe;
   1197	}
   1198
   1199	if (!ioc->active) {
   1200		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
   1201		  ioc->name);
   1202		error = -ENODEV;
   1203		goto out_mptfc_probe;
   1204	}
   1205
   1206	/*  Sanity check - ensure at least 1 port is INITIATOR capable
   1207	 */
   1208	ioc_cap = 0;
   1209	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
   1210		if (ioc->pfacts[ii].ProtocolFlags &
   1211		    MPI_PORTFACTS_PROTOCOL_INITIATOR)
   1212			ioc_cap ++;
   1213	}
   1214
   1215	if (!ioc_cap) {
   1216		printk(MYIOC_s_WARN_FMT
   1217			"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
   1218			ioc->name, ioc);
   1219		return 0;
   1220	}
   1221
   1222	sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
   1223
   1224	if (!sh) {
   1225		printk(MYIOC_s_WARN_FMT
   1226			"Unable to register controller with SCSI subsystem\n",
   1227			ioc->name);
   1228		error = -1;
   1229		goto out_mptfc_probe;
   1230        }
   1231
   1232	spin_lock_init(&ioc->fc_rescan_work_lock);
   1233	INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices);
   1234	INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset);
   1235	INIT_WORK(&ioc->fc_lsc_work, mptfc_link_status_change);
   1236
   1237	spin_lock_irqsave(&ioc->FreeQlock, flags);
   1238
   1239	/* Attach the SCSI Host to the IOC structure
   1240	 */
   1241	ioc->sh = sh;
   1242
   1243	sh->io_port = 0;
   1244	sh->n_io_port = 0;
   1245	sh->irq = 0;
   1246
   1247	/* set 16 byte cdb's */
   1248	sh->max_cmd_len = 16;
   1249
   1250	sh->max_id = ioc->pfacts->MaxDevices;
   1251	sh->max_lun = max_lun;
   1252
   1253	/* Required entry.
   1254	 */
   1255	sh->unique_id = ioc->id;
   1256
   1257	/* Verify that we won't exceed the maximum
   1258	 * number of chain buffers
   1259	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
   1260	 * For 32bit SGE's:
   1261	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
   1262	 *               + (req_sz - 64)/sizeof(SGE)
   1263	 * A slightly different algorithm is required for
   1264	 * 64bit SGEs.
   1265	 */
   1266	scale = ioc->req_sz/ioc->SGE_size;
   1267	if (ioc->sg_addr_size == sizeof(u64)) {
   1268		numSGE = (scale - 1) *
   1269		  (ioc->facts.MaxChainDepth-1) + scale +
   1270		  (ioc->req_sz - 60) / ioc->SGE_size;
   1271	} else {
   1272		numSGE = 1 + (scale - 1) *
   1273		  (ioc->facts.MaxChainDepth-1) + scale +
   1274		  (ioc->req_sz - 64) / ioc->SGE_size;
   1275	}
   1276
   1277	if (numSGE < sh->sg_tablesize) {
   1278		/* Reset this value */
   1279		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   1280		  "Resetting sg_tablesize to %d from %d\n",
   1281		  ioc->name, numSGE, sh->sg_tablesize));
   1282		sh->sg_tablesize = numSGE;
   1283	}
   1284
   1285	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
   1286
   1287	hd = shost_priv(sh);
   1288	hd->ioc = ioc;
   1289
   1290	/* SCSI needs scsi_cmnd lookup table!
   1291	 * (with size equal to req_depth*PtrSz!)
   1292	 */
   1293	ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_KERNEL);
   1294	if (!ioc->ScsiLookup) {
   1295		error = -ENOMEM;
   1296		goto out_mptfc_probe;
   1297	}
   1298	spin_lock_init(&ioc->scsi_lookup_lock);
   1299
   1300	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
   1301		 ioc->name, ioc->ScsiLookup));
   1302
   1303	hd->last_queue_full = 0;
   1304
   1305	sh->transportt = mptfc_transport_template;
   1306	error = scsi_add_host (sh, &ioc->pcidev->dev);
   1307	if(error) {
   1308		dprintk(ioc, printk(MYIOC_s_ERR_FMT
   1309		  "scsi_add_host failed\n", ioc->name));
   1310		goto out_mptfc_probe;
   1311	}
   1312
   1313	/* initialize workqueue */
   1314
   1315	snprintf(ioc->fc_rescan_work_q_name, sizeof(ioc->fc_rescan_work_q_name),
   1316		 "mptfc_wq_%d", sh->host_no);
   1317	ioc->fc_rescan_work_q =
   1318		alloc_ordered_workqueue(ioc->fc_rescan_work_q_name,
   1319					WQ_MEM_RECLAIM);
   1320	if (!ioc->fc_rescan_work_q) {
   1321		error = -ENOMEM;
   1322		goto out_mptfc_host;
   1323	}
   1324
   1325	/*
   1326	 *  Pre-fetch FC port WWN and stuff...
   1327	 *  (FCPortPage0_t stuff)
   1328	 */
   1329	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
   1330		(void) mptfc_GetFcPortPage0(ioc, ii);
   1331	}
   1332	mptfc_SetFcPortPage1_defaults(ioc);
   1333
   1334	/*
   1335	 * scan for rports -
   1336	 *	by doing it via the workqueue, some locking is eliminated
   1337	 */
   1338
   1339	queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
   1340	flush_workqueue(ioc->fc_rescan_work_q);
   1341
   1342	return 0;
   1343
   1344out_mptfc_host:
   1345	scsi_remove_host(sh);
   1346
   1347out_mptfc_probe:
   1348
   1349	mptscsih_remove(pdev);
   1350	return error;
   1351}
   1352
   1353static struct pci_driver mptfc_driver = {
   1354	.name		= "mptfc",
   1355	.id_table	= mptfc_pci_table,
   1356	.probe		= mptfc_probe,
   1357	.remove		= mptfc_remove,
   1358	.shutdown	= mptscsih_shutdown,
   1359#ifdef CONFIG_PM
   1360	.suspend	= mptscsih_suspend,
   1361	.resume		= mptscsih_resume,
   1362#endif
   1363};
   1364
   1365static int
   1366mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
   1367{
   1368	MPT_SCSI_HOST *hd;
   1369	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
   1370	unsigned long flags;
   1371	int rc=1;
   1372
   1373	if (ioc->bus_type != FC)
   1374		return 0;
   1375
   1376	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
   1377			ioc->name, event));
   1378
   1379	if (ioc->sh == NULL ||
   1380		((hd = shost_priv(ioc->sh)) == NULL))
   1381		return 1;
   1382
   1383	switch (event) {
   1384	case MPI_EVENT_RESCAN:
   1385		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
   1386		if (ioc->fc_rescan_work_q) {
   1387			queue_work(ioc->fc_rescan_work_q,
   1388				   &ioc->fc_rescan_work);
   1389		}
   1390		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
   1391		break;
   1392	case MPI_EVENT_LINK_STATUS_CHANGE:
   1393		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
   1394		if (ioc->fc_rescan_work_q) {
   1395			queue_work(ioc->fc_rescan_work_q,
   1396				   &ioc->fc_lsc_work);
   1397		}
   1398		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
   1399		break;
   1400	default:
   1401		rc = mptscsih_event_process(ioc,pEvReply);
   1402		break;
   1403	}
   1404	return rc;
   1405}
   1406
   1407static int
   1408mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
   1409{
   1410	int		rc;
   1411	unsigned long	flags;
   1412
   1413	rc = mptscsih_ioc_reset(ioc,reset_phase);
   1414	if ((ioc->bus_type != FC) || (!rc))
   1415		return rc;
   1416
   1417
   1418	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
   1419		": IOC %s_reset routed to FC host driver!\n",ioc->name,
   1420		reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
   1421		reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
   1422
   1423	if (reset_phase == MPT_IOC_SETUP_RESET) {
   1424		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
   1425		if (ioc->fc_rescan_work_q) {
   1426			queue_work(ioc->fc_rescan_work_q,
   1427				   &ioc->fc_setup_reset_work);
   1428		}
   1429		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
   1430	}
   1431
   1432	else if (reset_phase == MPT_IOC_PRE_RESET) {
   1433	}
   1434
   1435	else {	/* MPT_IOC_POST_RESET */
   1436		mptfc_SetFcPortPage1_defaults(ioc);
   1437		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
   1438		if (ioc->fc_rescan_work_q) {
   1439			queue_work(ioc->fc_rescan_work_q,
   1440				   &ioc->fc_rescan_work);
   1441		}
   1442		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
   1443	}
   1444	return 1;
   1445}
   1446
   1447/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
   1448/**
   1449 *	mptfc_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer.
   1450 *
   1451 *	Returns 0 for success, non-zero for failure.
   1452 */
   1453static int __init
   1454mptfc_init(void)
   1455{
   1456	int error;
   1457
   1458	show_mptmod_ver(my_NAME, my_VERSION);
   1459
   1460	/* sanity check module parameters */
   1461	if (mptfc_dev_loss_tmo <= 0)
   1462		mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
   1463
   1464	mptfc_transport_template =
   1465		fc_attach_transport(&mptfc_transport_functions);
   1466
   1467	if (!mptfc_transport_template)
   1468		return -ENODEV;
   1469
   1470	mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER,
   1471	    "mptscsih_scandv_complete");
   1472	mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER,
   1473	    "mptscsih_scandv_complete");
   1474	mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER,
   1475	    "mptscsih_scandv_complete");
   1476
   1477	mpt_event_register(mptfcDoneCtx, mptfc_event_process);
   1478	mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset);
   1479
   1480	error = pci_register_driver(&mptfc_driver);
   1481	if (error)
   1482		fc_release_transport(mptfc_transport_template);
   1483
   1484	return error;
   1485}
   1486
   1487/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
   1488/**
   1489 *	mptfc_remove - Remove fc infrastructure for devices
   1490 *	@pdev: Pointer to pci_dev structure
   1491 *
   1492 */
   1493static void mptfc_remove(struct pci_dev *pdev)
   1494{
   1495	MPT_ADAPTER		*ioc = pci_get_drvdata(pdev);
   1496	struct mptfc_rport_info	*p, *n;
   1497	struct workqueue_struct *work_q;
   1498	unsigned long		flags;
   1499	int			ii;
   1500
   1501	/* destroy workqueue */
   1502	if ((work_q=ioc->fc_rescan_work_q)) {
   1503		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
   1504		ioc->fc_rescan_work_q = NULL;
   1505		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
   1506		destroy_workqueue(work_q);
   1507	}
   1508
   1509	fc_remove_host(ioc->sh);
   1510
   1511	list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
   1512		list_del(&p->list);
   1513		kfree(p);
   1514	}
   1515
   1516	for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
   1517		if (ioc->fc_data.fc_port_page1[ii].data) {
   1518			dma_free_coherent(&ioc->pcidev->dev,
   1519					  ioc->fc_data.fc_port_page1[ii].pg_sz,
   1520					  ioc->fc_data.fc_port_page1[ii].data,
   1521					  ioc->fc_data.fc_port_page1[ii].dma);
   1522			ioc->fc_data.fc_port_page1[ii].data = NULL;
   1523		}
   1524	}
   1525
   1526	scsi_remove_host(ioc->sh);
   1527
   1528	mptscsih_remove(pdev);
   1529}
   1530
   1531/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
   1532/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
   1533/**
   1534 *	mptfc_exit - Unregisters MPT adapter(s)
   1535 *
   1536 */
   1537static void __exit
   1538mptfc_exit(void)
   1539{
   1540	pci_unregister_driver(&mptfc_driver);
   1541	fc_release_transport(mptfc_transport_template);
   1542
   1543	mpt_reset_deregister(mptfcDoneCtx);
   1544	mpt_event_deregister(mptfcDoneCtx);
   1545
   1546	mpt_deregister(mptfcInternalCtx);
   1547	mpt_deregister(mptfcTaskCtx);
   1548	mpt_deregister(mptfcDoneCtx);
   1549}
   1550
   1551module_init(mptfc_init);
   1552module_exit(mptfc_exit);