Linux Audio

Check our new training course

Real-Time Linux with PREEMPT_RT training

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