Linux Audio

Check our new training course

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