Linux Audio

Check our new training course

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